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
一、使用任意端口暴露
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
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
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
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
部署並修改遠程連接可以數據庫

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
Docker 鏡像倉庫
https://github.com/Joxit/docker-registry-ui/tree/main/examples/kubernetes
先創建 https 證書和密碼文件:https://www.cnblogs.com/jhxxb/p/13637834.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
創建
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 """ } } } } }
三、部署應用到指定 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
部署查看
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