Kubernetes 部署常见应用

k8s 安装:https://www.cnblogs.com/jhxxb/p/14321352.html

yaml 文件说明:https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/kubernetes-objects

命名空间:https://kubernetes.io/zh/docs/tasks/administer-cluster/namespaces

创建命令:https://kubernetes.io/zh/docs/tasks/manage-kubernetes-objects/declarative-config/#how-to-create-objects

 

一、使用任意端口暴露

sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml

# 在 - --service-cluster-ip-range=10.96.0.0/16 下添加
- --service-node-port-range=1-65535

# 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
  • targetPort:容器的端口(最根本的入口),与制作容器时暴露的端口一致(DockerFile中EXPOSE),也是 pod 的端口
  • port:kubernetes 中服务之间访问的端口,service 的端口
  • nodePort:外部可访问的端口。容器所在宿主机的端口(实质上也是通过 service 暴露给了宿主机,而 port 却没有)
  • hostPort:通过宿主机的 IP:Port 来访问 Pod,和 nodePort 类似

nodePort 是集群外流量访问集群内服务的端口类型。Port 是集群内的 pod 互相通信用的端口类型。targetPort 是最终端口

 

二、常见应用

MySQL

随机端口,指定端口需要配置 nodePort,或者部署后是用 kubectl edit svc mysql-service 修改

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-mysql
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.74.2.71
    path: "/nfs/mysql"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-mysql
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 5Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
spec:
  selector:
    matchLabels:
      app: mysql-label
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql-label
    spec:
      containers:
        - name: mysql
          image: mysql:latest
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: root
            - name: MYSQL_ROOT_HOST
              value: '%'
            - name: TZ
              value: Asia/Shanghai
          ports:
            - containerPort: 3306
          volumeMounts:
            - name: mysql-data
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-data
          persistentVolumeClaim:
            claimName: nfs-mysql
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql-label
  type: NodePort
  ports:
    - port: 3306
      targetPort: 3306
View Code

sudo mkdir /nfs/mysql

kubectl apply -f mysql.yaml

kubectl delete -f mysql.yaml

 

Oracle

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-oracle
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.74.2.71
    path: "/nfs/oracle"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-oracle
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: oracle-deployment
spec:
  selector:
    matchLabels:
      app: oracle-label
  replicas: 1
  template:
    metadata:
      labels:
        app: oracle-label
    spec:
      containers:
        - name: oracle-11g
          image: loliconneko/oracle-ee-11g:latest
          env:
            - name: WEB_CONSOLE
              value: 'false'
            - name: DBCA_TOTAL_MEMORY
              value: '4096'
          ports:
            - containerPort: 1521
          volumeMounts:
            - name: oracle-data
              mountPath: /u01/app/oracle
      volumes:
        - name: oracle-data
          persistentVolumeClaim:
            claimName: nfs-oracle
---
apiVersion: v1
kind: Service
metadata:
  name: oracle-service
spec:
  selector:
    app: oracle-label
  type: NodePort
  ports:
    - port: 1521
      targetPort: 1521
      nodePort: 1521
View Code

sudo mkdir /nfs/oracle

kubectl apply -f oracle.yaml

 

Redis

注意这里 resources 项限制了 CPU 和 Memory 资源

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
spec:
  selector:
    matchLabels:
      app: redis-label
  replicas: 1
  template:
    metadata:
      labels:
        app: redis-label
    spec:
      containers:
        - name: redis
          image: redis:alpine
          resources:
            limits:
              cpu: 1
              memory: 512Mi
            requests:
              cpu: 0.5
              memory: 128Mi
          ports:
            - containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  name: redis-service
spec:
  selector:
    app: redis-label
  type: NodePort
  ports:
    - port: 6379
      targetPort: 6379
      nodePort: 6379
View Code

kubectl apply -f redis.yaml

 

Zentao(禅道)

https://hub.docker.com/r/easysoft/zentao

https://www.zentao.net/book/zentaopmshelp/40.html

apiVersion: v1
kind: PersistentVolume
metadata:
  name: zentao-data
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.74.2.71
    path: "/nfs/zentao"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: zentao-data
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: zentao-mysql-data
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.74.2.71
    path: "/nfs/zentao-mysql"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: zentao-mysql-data
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: zentao-deployment
spec:
  selector:
    matchLabels:
      app: zentao-label
  replicas: 1
  template:
    metadata:
      labels:
        app: zentao-label
    spec:
      containers:
        - name: zentao
          image: easysoft/zentao:15.7
          resources:
            requests:
              cpu: 2000m
              memory: 2Gi
            limits:
              cpu: 2000m
              memory: 2Gi
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: root
          ports:
            - name: zentao
              containerPort: 80
            - name: mysql
              containerPort: 3306
          volumeMounts:
            - name: zentao-data
              mountPath: /www/zentaopms
            - name: zentao-mysql-data
              mountPath: /var/lib/mysql
      volumes:
        - name: zentao-data
          persistentVolumeClaim:
            claimName: zentao-data
        - name: zentao-mysql-data
          persistentVolumeClaim:
            claimName: zentao-mysql-data
---
apiVersion: v1
kind: Service
metadata:
  name: zentao-service
spec:
  selector:
    app: zentao-label
  type: NodePort
  ports:
    - name: mysql
      port: 3306
      targetPort: 3306
      nodePort: 9595
    - name: zentao
      port: 80
      targetPort: 80
      nodePort: 9696
View Code

部署并修改远程连接可以数据库

sudo mkdir /nfs/zentao
sudo mkdir /nfs/zentao-mysql
sudo chown zhangsan:zhangsan -R /nfs/zentao/
sudo chown zhangsan:zhangsan -R /nfs/zentao-mysql/
kubectl apply -f zentao.yaml

# 进入容器,修改配置
# https://mariadb.com/kb/en/configuring-mariadb-for-remote-client-access/
vim /etc/mysql/mariadb.conf.d/50-server.cnf
#bind-address=127.0.0.1
skip-networking=0
skip-bind-address
# 重启 mariadb 服务
cat /var/run/mysqld/mysqld.pid
kill xxx
service mysql restart
# 查看监听地址
ss -an
View Code

 

Docker 镜像仓库

https://github.com/Joxit/docker-registry-ui/tree/main/examples/kubernetes

先创建 https 证书和密码文件:https://www.cnblogs.com/jhxxb/p/13647369.html

然后将文件创建成 ConfigMap:https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-pod-configmap

kubectl create namespace devops
kubectl -n devops create configmap registry-config-auth --from-file=/opt/registry/auth
kubectl -n devops create configmap registry-config-certs --from-file=/opt/registry/certs

仓库使用 registry,UI 使用 joxit/docker-registry-ui,若出现 Access-Control-Allow-Origin 问题,看看配置:NGINX_PROXY_PASS_URL 为代理,REGISTRY_URL 为直接访问,二选一。若存储为本机可以将 nfs 改为 hostPath

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-docker-registry
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Delete # https://kubernetes.io/zh/docs/tasks/administer-cluster/change-pv-reclaim-policy/
  nfs:
    server: 10.74.2.71
    path: /nfs/docker-registry # sudo chmod -R 0777 /nfs/docker-registry
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-docker-registry
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: docker-registry-deployment
spec:
  selector:
    matchLabels:
      app: docker-registry-label
  replicas: 1
  template:
    metadata:
      labels:
        app: docker-registry-label
    spec:
      containers:
        - name: docker-registry
          image: registry # 镜像版本
          env:
            - name: REGISTRY_STORAGE_DELETE_ENABLED
              value: "true"
            - name: REGISTRY_AUTH
              value: htpasswd 
            - name: REGISTRY_AUTH_HTPASSWD_REALM
              value: basic-realm
            - name: REGISTRY_AUTH_HTPASSWD_PATH
              value: /auth/htpasswd
            - name: REGISTRY_HTTP_TLS_CERTIFICATE
              value: /certs/domain.crt
            - name: REGISTRY_HTTP_TLS_KEY
              value: /certs/domain.key
          ports:
            - containerPort: 5000
              protocol: TCP
          volumeMounts:
            - name: docker-registry-data
              mountPath: /var/lib/registry
            - name: docker-registry-auth
              mountPath: /auth
            - name: docker-registry-certs
              mountPath: /certs
      volumes:
        - name: docker-registry-data
          persistentVolumeClaim:
            claimName: nfs-docker-registry # 将上面创建的 pv 关联到 pvc 上
        - name: docker-registry-auth
          configMap:
            name: registry-config-auth # 关联到 configMap 上
        - name: docker-registry-certs
          configMap:
            name: registry-config-certs
---
apiVersion: v1
kind: Service
metadata:
  name: docker-registry-service
spec:
  selector:
    app: docker-registry-label
  ports:
    - targetPort: 5000
      port: 5000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: docker-registry-ui-deployment
spec:
  selector:
    matchLabels:
      app: docker-registry-ui-label
  replicas: 1
  template:
    metadata:
      labels:
        app: docker-registry-ui-label
    spec:
      containers:
        - name: docker-registry-ui
          image: joxit/docker-registry-ui
          env:
            - name: DELETE_IMAGES
              value: "true"
            - name: SINGLE_REGISTRY
              value: "true"
            - name: PULL_URL
              value: 10.74.2.71:5000
            - name: NGINX_PROXY_PASS_URL # https://github.com/Joxit/docker-registry-ui/tree/main/examples
              value: https://docker-registry-service:5000 # 若配置了 ca,这里为 https
          ports:
            - containerPort: 80
              protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: docker-registry-ui-service
spec:
  selector:
    app: docker-registry-ui-label
  ports:
    - targetPort: 80
      port: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: docker-registry-ui-ingress
spec:
  ingressClassName: nginx
  rules:
    - http:
        paths:
          - path: /
            backend:
              service:
                name: docker-registry-ui-service
                port:
                  number: 80
            pathType: Prefix
      host: registry.example.com
View Code

创建

sudo mkdir /nfs/docker-registry
kubectl apply -f registry.yaml
# 查看
kubectl get deployment -n docker-registry -o wide
kubectl get pods -n docker-registry
kubectl get svc -n docker-registry -o wide
kubectl get ing -n docker-registry
kubectl describe ingress docker-registry-ui-ingress -n docker-registry
# 查看 ingress 对外端口
kubectl get svc -n ingress-nginx

访问 UI 要配置 Hosts 文件,端口为 ingress 的 80 对外端口

 

Jenkins

https://github.com/jenkinsci/kubernetes-plugin/blob/master/README_zh.md#在-kubernetes-中运行

PV 配置,VolumeClaimTemplates 匹配不上 PV 时会出现 StatefulSet 挂载不到 PV 的问题

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-home
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    server: 10.74.2.71
    path: /nfs/jenkins

若删除了 PVC,想让 PV 可以被重新绑定:https://stackoverflow.com/questions/58168408/kubernetes-pv-refuses-to-bind-after-delete-re-create

# 要再次让 PV Available,需删除 uid
kubectl patch pv jenkins-home --type json -p '[{"op": "remove", "path": "/spec/claimRef/uid"}]'
# 或删除整个 claimRef 部分
kubectl patch pv jenkins-home --type json -p '[{"op": "remove", "path": "/spec/claimRef"}]'

创建

# 创建 PV
sudo mkdir /nfs/jenkins & sudo chmod -R 0777 /nfs/jenkins
kubectl apply -f jenkins-pv.yaml
# 创建名称空间
kubectl create namespace devops
# 设置当前配置默认名称空间
kubectl config set-context $(kubectl config current-context) --namespace=devops
# 创建 jenkins
kubectl create -f http://raw.githubusercontent.com/jenkinsci/kubernetes-plugin/master/src/main/kubernetes/service-account.yml
kubectl create -f http://raw.githubusercontent.com/jenkinsci/kubernetes-plugin/master/src/main/kubernetes/jenkins.yml
# 查看网络,访问需要配置 hosts 文件:jenkins.example.com,使用 https 访问
kubectl describe services/jenkins
# 设置当前配置默认名称空间
kubectl config set-context $(kubectl config current-context) --namespace=default

安装 Kubernetes 插件:https://plugins.jenkins.io/kubernetes

https://kubernetes.default.svc.cluster.local
http://jenkins.devops.svc.cluster.local:80

关于地址命名,与 DNS 有关:https://kubernetes.io/zh/docs/concepts/services-networking/dns-pod-service

安装 Pipeline 插件,测试 Pipeline script,注意改 NFS 地址

def label = "mypod-${UUID.randomUUID().toString()}"
podTemplate(label: label, cloud: 'kubernetes', containers: [
    containerTemplate(name: 'maven', image: 'maven:3.8.4-jdk-8', ttyEnabled: true, command: 'cat')
], volumes: [
    hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
    nfsVolume(mountPath: '/root/.m2', serverAddress: '10.74.2.71', serverPath: '/nfs/maven')
])
{
    node(label) {
        stage('git') {
            container('jnlp') {
                sh 'git clone --branch master --depth 1 https://gitee.com/jhxxb/MySpringBoot.git'
            }
        }
        stage('maven') {
            container('maven') {
                stage('maven install') {
                    sh """
                    cd MySpringBoot
                    mvn -B -DskipTests=true clean install
                    """
                }
                stage('maven package') {
                    sh """
                    cd MySpringBoot
                    mvn -DskipTests=true package
                    """
                }
            }
        }
    }
}
View Code

若构建过程中出现 process apparently never started in,请检查 Jenkins 的系统配置中的全局属性项,是否配置有 PATH 环境变量,将 :/sbin:/usr/sbin:/usr/bin:/usr/local/bin:/bin 加入其中

 

三、部署应用到指定 Node 节点

两种方式:NodeName  和 NodeSelector

一、NodeName

以部署 RabbitMQ 为例,注意 nodeName 属性值为节点名称

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rabbitmq-deployment
spec:
  selector:
    matchLabels:
      app: rabbitmq-label
  replicas: 1
  template:
    metadata:
      labels:
        app: rabbitmq-label
    spec:
      nodeName: k8s-node-8
      containers:
        - name: rabbitmq
          image: rabbitmq:management-alpine
          resources:
            limits:
              cpu: 1
              memory: 512Mi
            requests:
              cpu: 0.5
              memory: 128Mi
          env:
            - name: RABBITMQ_DEFAULT_VHOST
              value: my_vhost
            - name: RABBITMQ_DEFAULT_USER
              value: guest
            - name: RABBITMQ_DEFAULT_PASS
              value: guest
          ports:
            - containerPort: 5672
            - containerPort: 15672
---
apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-service
spec:
  selector:
    app: rabbitmq-label
  type: NodePort
  ports:
    - name: app
      port: 5672
      targetPort: 5672
      nodePort: 5672
    - name: ui
      port: 15672
      targetPort: 15672
      nodePort: 15672
View Code

部署查看

kubectl apply -f rabbitmq.yaml
kubectl get pods -o wide

二、NodeSelector

给 Node 设置标签

kubectl label nodes k8s-node-8 deploy=hello
kubectl get nodes --show-labels

已部署 MQ 为例,注意 nodeSelector 属性值为标签属性值

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rabbitmq-deployment
spec:
  selector:
    matchLabels:
      app: rabbitmq-label
  replicas: 1
  template:
    metadata:
      labels:
        app: rabbitmq-label
    spec:
      nodeSelector:
        deploy: hello
      containers:
        - name: rabbitmq
          image: rabbitmq:management-alpine
          resources:
            limits:
              cpu: 1
              memory: 512Mi
            requests:
              cpu: 0.5
              memory: 128Mi
          env:
            - name: RABBITMQ_DEFAULT_VHOST
              value: my_vhost
            - name: RABBITMQ_DEFAULT_USER
              value: guest
            - name: RABBITMQ_DEFAULT_PASS
              value: guest
          ports:
            - containerPort: 5672
            - containerPort: 15672
---
apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-service
spec:
  selector:
    app: rabbitmq-label
  type: NodePort
  ports:
    - name: app
      port: 5672
      targetPort: 5672
      nodePort: 5672
    - name: ui
      port: 15672
      targetPort: 15672
      nodePort: 15672
View Code

 


http://www.mydlq.club/article/65

posted @ 2021-09-17 21:07  江湖小小白  阅读(514)  评论(0编辑  收藏  举报