1.配置分离 1.1什么是ConfigMap ConfigMap 是 Kubernetes 中用于存储非敏感配置数据的资源对象。它允许您将配置信息与应用程序代码分离,从而提高应用程序的可移植性和可维护性。
配置分离的核心理念是将应用程序的配置(如数据库连接字符串、API密钥、环境变量等)与应用程序代码分开管理。这意味着开发人员和运维人员可以独立于应用程序代码来修改和管理配置,从而实现更灵活的部署和管理。
在Kubernetes中,配置分离主要通过以下资源来实现:
ConfigMap :用于存储非敏感的配置信息,如配置文件、环境变量等。
Secret :用于存储敏感的配置信息,如密码、API密钥、证书等。
这种做法有几个主要优点:
提高灵活性:可以在不重建容器镜像的情况下更改配置。
增强安全性:敏感信息可以与代码分开存储和管理。
简化部署:同一个容器镜像可以在不同环境中使用不同的配置。
1.2创建ConfigMap的方式 1 2 3 4 5 6 7 8 kubectl create configmap -h kubectl create cm cmfromdir --from-file=conf/ kubectl create cm cmfromfile --from-file=conf/redis.conf kubectl create cm cmspecialname --from-file=game-conf=game.conf kubectl create cm cmspecialname2 --from-file=game-conf=game.conf --from-file=redis-conf=redis.conf kubectl create cm gameenvcm --from-env-file=game.conf kubectl create cm envfromliteral --from-literal=level=INFO --from-literal=PASSWORD=redis123 kubectl create -f cm.yaml
基于目录创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 [root@k8s-master01 pra]# mkdir -p /root/pra/configmap/conf [root@k8s-master01 pra]# cd /root/pra/configmap/conf # 演示文件内容随便定义 [root@k8s-master01 conf]# cat game.conf lives=3 secret.code=true [root@k8s-master01 conf]# cat game2.conf color.good=blue user=tomcat # 利用/root/pra/configmap/conf目录中的文件创建configmap(假设该目录中很多配置文件,基于目录创建configmap) # create用于创建kubernetes资源 # configmap表示创建资源的类型 # cmfromdir创建的configmap名称 # --from-file=表示从文件创建 ConfigMap # 指定路径conf/,/表示是目录,而不是文件 [root@k8s-master01 configmap]# kubectl create configmap cmfromdir --from-file=conf/ configmap/cmfromdir created # 查看创建的configmap # configmap可以缩写为cm [root@k8s-master01 configmap]# kubectl get cm NAME DATA AGE cmfromdir 2 4m26s kube-root-ca.crt 1 35d # 查看cm的具体信息 [root@k8s-master01 configmap]# kubectl get cm cmfromdir -o yaml apiVersion: v1 data: game.conf: | lives=3 secret.code=true game2.conf: | color.good=blue user=tomcat kind: ConfigMap metadata: creationTimestamp: "2024-07-27T15:43:41Z" name: cmfromdir namespace: default resourceVersion: "3297203" uid: 704eadb3-6ea1-480a-802a-eeb141a6f951
基于单个文件创建config 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [root@k8s-master01 configmap]# cat conf/redis.conf bind 127.0.0.1 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes pidfile /var/run/redis/redis.pid loglevel notice logfile /usr/local/redis/var/redis.log databases 16 # 通过单个文件创建configmap [root@k8s-master01 configmap]# kubectl create cm cmfromfile --from-file=conf/redis.conf configmap/cmfromfile created # 查看创建cm [root@k8s-master01 ~]# kubectl get cm NAME DATA AGE cmfromdir 2 11h cmfromfile 1 11h kube-root-ca.crt 1 35d
自定义key名创建cm 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 # --from-file=redis-conf=/root/pra/configmap/conf/game.conf使用redis-conf自定义key名称 [root@k8s-master01 ~]# kubectl create cm cmspecialname --from-file=redis-conf=/root/pra/configmap/conf/game.conf configmap/cmspecialname created # redis-conf是自定义的名称而不是根据创建的文件名称命名 [root@k8s-master01 ~]# kubectl get cm cmspecialname -o yaml apiVersion: v1 data: redis-conf: | lives=3 secret.code=true kind: ConfigMap metadata: creationTimestamp: "2024-07-28T03:42:03Z" name: cmspecialname namespace: default resourceVersion: "3311656" uid: 9076adfa-58e4-4de9-8a19-7ebfa0397a28 # 一次自定义多个 [root@k8s-master01 ~]# kubectl create cm cmspecialname2 --from-file=redis-conf=/root/pra/configmap/conf/game.conf --from-file=nginx-conf=/root/pra/configmap/conf/game2.conf configmap/cmspecialname2 created # nginx-conf和redis-conf是自定义的名称而不是根据创建的文件名称命名 [root@k8s-master01 ~]# kubectl get cm cmspecialname2 -oyaml apiVersion: v1 data: nginx-conf: | color.good=blue user=tomcat redis-conf: | lives=3 secret.code=true kind: ConfigMap metadata: creationTimestamp: "2024-07-28T03:44:48Z" name: cmspecialname2 namespace: default resourceVersion: "3312103" uid: 2fd983c5-3f10-4871-86c3-37de6e9b0464
基于env环境变量创建cm 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@k8s-master01 conf]# kubectl create cm gameenvcm --from-env-file=game.conf configmap/gameenvcm created [root@k8s-master01 conf]# kubectl get cm gameenvcm -oyaml apiVersion: v1 data: lives: "3" secret.code: "true" kind: ConfigMap metadata: creationTimestamp: "2024-07-28T04:03:06Z" name: gameenvcm namespace: default resourceVersion: "3315062" uid: f3d0507d-aaa6-413b-b03c-bec9145269a5
基于命令行直接创建configmap的键值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # --from-literal: 这个参数允许你直接在命令行中指定 ConfigMap 的键值对。 [root@k8s-master01 conf]# kubectl create cm fromenvliteral --from-literal=level=3 --from-literal=PASSWD=redis123456 configmap/fromenvliteral created [root@k8s-master01 conf]# kubectl get cm fromenvliteral -oyaml apiVersion: v1 data: PASSWD: redis123456 level: "3" kind: ConfigMap metadata: creationTimestamp: "2024-07-28T04:12:13Z" name: fromenvliteral namespace: default resourceVersion: "3316540" uid: 68709d37-9c2e-4f41-83d9-783bbb240b31
1.3使用ConfigMap 1.3.1使用valueFrom定义环境变量(适用少数环境变量场景) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 利用命令快速创建一个deployment,用这个deploy引用configmap [root@k8s-master01 conf]# kubectl create deployment dp-cm --image=registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine --dry-run=client -oyaml >dp-cm.yaml # 这是创建的configmap [root@k8s-master01 configmap]# kubectl get cm gameenvcm -oyaml apiVersion: v1 data: lives: "3" secret.code: "true" kind: ConfigMap metadata: creationTimestamp: "2024-07-28T04:03:06Z" name: gameenvcm namespace: default resourceVersion: "3315062" uid: f3d0507d-aaa6-413b-b03c-bec9145269a5
在pod中使用configmap中定义环境变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 # 使用valueFrom引用configmap中的环境变量 [root@k8s-master01 configmap]# cat dp-cm.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx env: - name: TEST_ENV value: testenv - name: LIVES valueFrom: configMapKeyRef: name: gameenvcm key: lives ---------------------------- env中字段解释: - name: LIVES valueFrom: configMapKeyRef: name: gameenvcm key: lives name: LIVES: 这定义了环境变量的名称。在容器内,可以通过 $LIVES 访问这个变量。 valueFrom: 这表示值将从外部源获取,而不是直接设置。 configMapKeyRef: 这指定值将从 ConfigMap 中获取。 name: gameenvcm: 这是 ConfigMap 的名称。 key: lives: 这是要从 ConfigMap 中获取的特定键。在容器中查看LIVES的值就是configmap中lives的值,这种配置方式用于从 ConfigMap 动态获取值。根据之前显示的 ConfigMap 内容,这个环境变量 LIVES 的值将被设置为 "3"。 ------------------------------ # 创建这个deployment [root@k8s-master01 configmap]# kubectl create -f dp-cm.yaml # pod成功运行 [root@k8s-master01 configmap]# kubectl get po NAME READY STATUS RESTARTS AGE dp-cm-6d9d86cb4f-8jqj2 1/1 Running 0 14m # 进入pod查看配置的环境变量 [root@k8s-master01 configmap]# kubectl exec -it dp-cm-6d9d86cb4f-8jqj2 -- sh / # / # echo $TEST_ENV testenv / # echo $LIVES 3 # 不进入容器查看环境变量 [root@k8s-master01 configmap]# kubectl exec dp-cm-6d9d86cb4f-8jqj2 -- env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=dp-cm-6d9d86cb4f-8jqj2 NGINX_VERSION=1.27.0 PKG_RELEASE=2 NJS_VERSION=0.8.4 NJS_RELEASE=2 TEST_ENV=testenv LIVES=3 KUBERNETES_PORT_443_TCP_PROTO=tcp KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1 SERVICE_EXTERNAL_IP_SERVICE_PORT=80 SERVICE_EXTERNAL_IP_SERVICE_PORT_HTTP=80 SERVICE_EXTERNAL_IP_PORT_80_TCP=tcp://10.96.20.32:80 SERVICE_EXTERNAL_IP_PORT_80_TCP_PROTO=tcp SERVICE_EXTERNAL_IP_PORT_80_TCP_ADDR=10.96.20.32 KUBERNETES_SERVICE_PORT=443 SERVICE_FOR_NGINX_DEPLOYMENT_SERVICE_PORT=80 SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_PORT=80 KUBERNETES_SERVICE_HOST=10.96.0.1 KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443 SERVICE_FOR_NGINX_DEPLOYMENT_PORT=tcp://10.96.227.196:80 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT=tcp://10.96.0.1:443 KUBERNETES_PORT_443_TCP_PORT=443 SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP=tcp://10.96.227.196:80 SERVICE_EXTERNAL_IP_SERVICE_HOST=10.96.20.32 SERVICE_EXTERNAL_IP_PORT=tcp://10.96.20.32:80 SERVICE_EXTERNAL_IP_PORT_80_TCP_PORT=80 SERVICE_FOR_NGINX_DEPLOYMENT_SERVICE_HOST=10.96.227.196 SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_PROTO=tcp SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_ADDR=10.96.227.196 HOME=/root
1.3.2使用envFrom定义环境变量(适用多数环境变量的场景) configmap内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [root@k8s-master01 configmap]# kubectl get cm gameenvcm -oyaml apiVersion: v1 data: game.conf: |+ lives=3 secret.code=true color=red user=root password=1234 lives: "3" secret.code: "true" kind: ConfigMap metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"game.conf":"lives=3\nsecret.code=true\ncolor=red\nuser=root\npassword=1234\n\n"},"kind":"ConfigMap","metadata":{"annotations":{},"creationTimestamp":null,"name":"gameenvcm","namespace":"default"}} creationTimestamp: "2024-07-28T04:03:06Z" name: gameenvcm namespace: default resourceVersion: "3339558" uid: f3d0507d-aaa6-413b-b03c-bec9145269a5
配置envFrom的引用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 # 在pod中containers.envFrom引用configmap [root@k8s-master01 configmap]# cat dp-cm.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx envFrom: #envFrom: 该字段用于指定容器的环境变量来源。它可以从 ConfigMap、Secret 或其他来源中获取环境变量。 - configMapRef: #该字段用于指定 ConfigMap 的引用。它是一个对象,包含了 ConfigMap 的名称和其他信息。 name: gameenvcm #该字段用于指定 ConfigMap 的名称。在本例中,ConfigMap 的名称是 gameenvcm。 env: - name: TEST_ENV value: testenv - name: LIVES valueFrom: configMapKeyRef: name: gameenvcm key: lives
更新deploy,并查看它管理的pod中的环境变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml [root@k8s-master01 configmap]# kubectl exec dp-cm-7b5f78b75c-lkpvz -- env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=dp-cm-7b5f78b75c-lkpvz NGINX_VERSION=1.27.0 PKG_RELEASE=2 NJS_VERSION=0.8.4 NJS_RELEASE=2 secret.code=true TEST_ENV=testenv LIVES=3 game.conf=lives=3 secret.code=true color=red user=root password=1234 lives=3 KUBERNETES_SERVICE_HOST=10.96.0.1 SERVICE_EXTERNAL_IP_SERVICE_HOST=10.96.20.32 SERVICE_EXTERNAL_IP_SERVICE_PORT_HTTP=80 SERVICE_EXTERNAL_IP_PORT=tcp://10.96.20.32:80 SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_ADDR=10.96.227.196 SERVICE_FOR_NGINX_DEPLOYMENT_PORT=tcp://10.96.227.196:80 SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_PORT=80 KUBERNETES_SERVICE_PORT=443 KUBERNETES_PORT=tcp://10.96.0.1:443 KUBERNETES_PORT_443_TCP_PROTO=tcp SERVICE_EXTERNAL_IP_SERVICE_PORT=80 SERVICE_EXTERNAL_IP_PORT_80_TCP_PORT=80 SERVICE_FOR_NGINX_DEPLOYMENT_SERVICE_PORT=80 KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443 KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1 SERVICE_EXTERNAL_IP_PORT_80_TCP_PROTO=tcp SERVICE_FOR_NGINX_DEPLOYMENT_SERVICE_HOST=10.96.227.196 KUBERNETES_SERVICE_PORT_HTTPS=443 SERVICE_EXTERNAL_IP_PORT_80_TCP=tcp://10.96.20.32:80 SERVICE_EXTERNAL_IP_PORT_80_TCP_ADDR=10.96.20.32 SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP=tcp://10.96.227.196:80 SERVICE_FOR_NGINX_DEPLOYMENT_PORT_80_TCP_PROTO=tcp HOME=/root
1.3.3以文件的形式挂载ConfigMap 案例:以redis.conf创建configmap,并挂载到容器中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 # redis的配置文件如下:(仅供演示) [root@k8s-master01 configmap]# cat conf/redis.conf bind 127.0.0.1 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes pidfile /var/run/redis/redis.pid loglevel notice logfile /usr/local/redis/var/redis.log databases 16 # 基于redis.conf创建一个名字是reids-conf的configmap [root@k8s-master01 configmap]# kubectl create cm redis-conf --from-file=conf/redis.conf configmap/redis-conf created # 在容器中引用这个configmap [root@k8s-master01 configmap]# cat dp-cm.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx volumeMounts: - name: redisconf mountPath: /etc/config volumes: - name: redisconf configMap: name: redis-conf # 更新这个deploy [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml deployment.apps/dp-cm replaced
验证是否将redis.conf文件挂载到容器中了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 查看创建的pod [root@k8s-master01 configmap]# kubectl get po NAME READY STATUS RESTARTS AGE dp-cm-df468cf55-mfbfd 1/1 Running 0 10m # 进入pod(dp-cm-df468cf55-mfbfd)中 [root@k8s-master01 configmap]# kubectl exec -ti dp-cm-df468cf55-mfbfd -- sh / # / # ls -l /etc/config/ # redis.conf文件已经存在 total 0 lrwxrwxrwx 1 root root 17 Jul 28 07:27 redis.conf -> ..data/redis.conf /etc/config # cat redis.conf bind 127.0.0.1 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes pidfile /var/run/redis/redis.pid loglevel notice logfile /usr/local/redis/var/redis.log databases 16
更新configmap的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 # 直接使用edit编辑configmap,程序需要有热加载功能,才会同步到容器内,程序如果没有热加载就需要重启 # 我们使用redis-conf configmap演示 [root@k8s-master01 configmap]# kubectl get cm NAME DATA AGE kube-root-ca.crt 1 35d redis-conf 1 48m # 使用edit编辑名字是redis-conf的cm,将port 6379改为port 6380 [root@k8s-master01 configmap]# kubectl edit cm redis-conf # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 data: redis.conf: | bind 127.0.0.1 protected-mode yes port 6380 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes pidfile /var/run/redis/redis.pid loglevel notice logfile /usr/local/redis/var/redis.log databases 16 kind: ConfigMap metadata: creationTimestamp: "2024-07-28T06:55:59Z" name: redis-conf namespace: default resourceVersion: "3343543" uid: ff3cd3a9-c6e6-4150-91be-dc523b01a099 # 修改后保存退出,不重启pod的情况下,查看pod中挂载的redis.conf的内容, 是否有port 6380的参数 # 进入pod中 [root@k8s-master01 configmap]# kubectl exec -ti dp-cm-df468cf55-mfbfd -- sh / # cat /etc/config/ ..2024_07_28_07_45_52.1762584904/ ..data/ redis.conf / # cat /etc/config/redis.conf bind 127.0.0.1 protected-mode yes port 6380 #可以看到此时已经改为6380 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes pidfile /var/run/redis/redis.pid loglevel notice logfile /usr/local/redis/var/redis.log databases 16
挂载多个configmap配置案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx volumeMounts:# 该参数指定了容器中的卷挂载点。它是一个列表,包含了多个卷挂载点的配置。 - name: redisconf # 该参数指定了卷的名称,要和下面volumes.name一致。在本例中,卷的名称是 redisconf。 mountPath: /etc/config #该参数指定了卷挂载点的路径 - name: nginxconf # 必须与 volumes 中的 name 匹配 mountPath: /etc/config2 volumes: #该参数指定了容器中的卷。它是一个列表,包含了多个卷的配置。 - name: redisconf #该参数定义了卷的名称。在本例中,卷的名称是 redisconf。 configMap: # 该参数指定卷的类型为 ConfigMap name: redis-conf #该参数指定了 ConfigMap 的名称。在本例中,ConfigMap 的名称是 redis-conf。 - name: nginxconf #必须与 volumeMounts 中的 name 匹配 configMap: name: nginx-conf
1.3.4自定义挂载名称和权限
自定义挂载名称
通过 items:参数可以自定义挂载的文件名称
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 # deployment配置文件内容如下: [root@k8s-master01 configmap]# cat dp-cm.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx volumeMounts: - name: redisconf mountPath: /etc/config volumes: - name: redisconf configMap: name: redis-conf items: #定义要从 ConfigMap 中挂载的特定键值对 - key: redis.conf #指定configmap中的键,这里是redis.conf path: zidingyi.conf #指定容器中的路径。将键redis.conf内容挂载到/etc/config/zidingyi.conf路径 # 创建这个deployment [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml deployment.apps/dp-cm replaced # 验证挂载的文件是不是自定义的zidingyi.conf名称 [root@k8s-master01 configmap]# kubectl exec dp-cm-6b84964f55-vp6kv -- ls -l /etc/config total 0 lrwxrwxrwx 1 root root 20 Jul 28 10:29 zidingyi.conf -> ..data/zidingyi.conf
自定义挂载权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 [root@k8s-master01 configmap]# cat dp-cm.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx volumeMounts: - name: redisconf mountPath: /etc/config volumes: - name: redisconf configMap: name: redis-conf items: - key: redis.conf #选择 ConfigMap 中的 redis.conf作为键。 path: zidingyi.conf - key: redis.conf path: test.conf mode: 0400 #定义挂载文件的权限,优先级高于defaultMode defaultMode: 0755 #定义挂载文件的默认权限,如果单个key中没有配置mode,那么该值生效 # 更新这个deployment,进入pod中查看文件的权限 [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml deployment.apps/dp-cm replaced [root@k8s-master01 configmap]# kubectl exec -ti dp-cm-5d4b745d47-4d9t9 -- sh / # ls -l /etc/config/..data/ total 8 -r-------- 1 root root 203 Jul 28 11:59 test.conf #文件权限400 -rwxr-xr-x 1 root root 203 Jul 28 11:59 zidingyi.conf #文件权限755
1.4Secret 在 Kubernetes 中,Secret 是一种资源对象,用于存储和管理敏感信息,如密码、令牌和密钥等。使用 Secret 可以避免将敏感数据硬编码到应用程序的代码或配置文件中,提高安全性和管理的便捷性。而 ConfigMap 用于存储应用程序的配置数据。
1.4.1Secret常用的几种类型(加粗代表常用的类型) ◆ Opaque:通用型Secret,默认类型;使用最多的类型
◆ kubernetes.io/service-account-token:作用于ServiceAccount,包含一个令牌,用于标识API服务账户;
◆ kubernetes.io/dockerconfigjson:下载私有仓库镜像使用的Secret,和宿主机的/root/.docker/config.json一致,宿主机登录后即可产生该文件;
◆ kubernetes.io/basic-auth:用于使用基本认证(账号密码)的Secret,可以使用Opaque取代;
◆ kubernetes.io/ssh-auth:用于存储ssh密钥的Secret;
◆ kubernetes.io/tls:用于存储HTTPS域名证书文件的Secret,可以被Ingress使用;
◆ bootstrap.kubernetes.io/token:一种简单的 bearer token,用于创建新集群或将新节点添加到现有集群,在集群安装时可用于自动颁发集群的证书。
参考连接:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/
1.4.2创建Secret 参考链接:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/#creating-a-secret
1.4.2.1使用命令创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # 准备两个演示文件,用来存储账号和密码 [root@k8s-master01 secret]# cd /root/pra/secret [root@k8s-master01 secret]# echo -n 'admin' > ./username.txt [root@k8s-master01 secret]# echo -n 'S!B\*d$zDsb=' > ./password.txt # 使用命令创建secret [root@k8s-master01 secret]# kubectl create secret generic db-user-pass --from-file=username.txt --from-file=password.txt secret/db-user-pass created # 查看创建的secret [root@k8s-master01 secret]# kubectl get secrets NAME TYPE DATA AGE db-user-pass Opaque 2 18s # 以yaml格式输出 db-user-pass这个secret [root@k8s-master01 secret]# kubectl get secrets db-user-pass -o yaml apiVersion: v1 data: password.txt: UyFCXCpkJHpEc2I9 #这里不是明文,进行软加密 username.txt: YWRtaW4= #这里不是明文,进行软加密 kind: Secret metadata: creationTimestamp: "2024-07-28T12:56:01Z" name: db-user-pass namespace: default resourceVersion: "3401907" uid: dcf18ce5-0cc6-4b56-be98-6844e688869a type: Opaque
1.4.2.2使用–from-literal创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # 命令行中直接使用--from-literal创建 [root@k8s-master01 secret]# kubectl create secret generic dev-db-user-pass --from-literal=username=devuser --from-literal=passwd='123456' #这里不能使用双引号 secret/dev-db-user-pass created # 查看创建的secret [root@k8s-master01 secret]# kubectl get secrets NAME TYPE DATA AGE db-user-pass Opaque 2 10m dev-db-user-pass Opaque 2 43s # 以yaml格式输出dev-db-user-pass这个secret [root@k8s-master01 secret]# kubectl get secrets dev-db-user-pass -oyaml apiVersion: v1 data: passwd: MTIzNDU2 username: ZGV2dXNlcg== kind: Secret metadata: creationTimestamp: "2024-07-28T13:05:32Z" name: dev-db-user-pass namespace: default resourceVersion: "3403451" uid: 2025ec26-9e7b-4682-9544-e0f5fefda193 type: Opaque
1.4.2.3基于yaml文件创建secret 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #将dmin和1f2d1e2e67df进行base64编码转换 [root@k8s-master01 secret]# echo -n 'admin' | base64 YWRtaW4= [root@k8s-master01 secret]# echo -n '1f2d1e2e67df' | base64 MWYyZDFlMmU2N2Rm #创建secret的yaml文件 [root@k8s-master01 secret]# cat secret.yaml apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: MWYyZDFlMmU2N2Rm #利用yaml文件创建secret [root@k8s-master01 secret]# kubectl create -f secret.yaml secret/mysecret created #查看刚才创建的secret [root@k8s-master01 secret]# kubectl get secrets NAME TYPE DATA AGE db-user-pass Opaque 2 23m dev-db-user-pass Opaque 2 13m mysecret Opaque 2 24s #以yaml格式输出mysecret [root@k8s-master01 secret]# kubectl get secrets mysecret -oyaml apiVersion: v1 data: password: MWYyZDFlMmU2N2Rm username: YWRtaW4= kind: Secret metadata: creationTimestamp: "2024-07-28T13:18:53Z" name: mysecret namespace: default resourceVersion: "3405611" uid: 3cebc767-eb57-42c5-b032-98d62e1d38d4 type: Opaque #可以看到YWRtaW4=解码后的值是admin,和上面的步骤对应 [root@k8s-master01 secret]# echo -n 'YWRtaW4='|base64 -d admin
上述操作是在创建secret前先对数据进行base64编码,也可以不用编码,下面是不事先对数据编码的yaml格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 # 不事先对数据编码需要配置stringData:参数 [root@k8s-master01 secret]# cat secret-stringdata.yaml apiVersion: v1 kind: Secret metadata: name: my-springdata-secret type: Opaque stringData: username: admin password: asdqwe123@ # 创建secret [root@k8s-master01 secret]# kubectl create -f secret-stringdata.yaml secret/my-springdata-secret created # 查看创建的secret [root@k8s-master01 secret]# kubectl get secrets NAME TYPE DATA AGE db-user-pass Opaque 2 34m dev-db-user-pass Opaque 2 24m my-springdata-secret Opaque 2 19s mysecret Opaque 2 11m # 可以看到创建的secret中的数据也被编码过了 [root@k8s-master01 secret]# kubectl get secrets my-springdata-secret -oyaml apiVersion: v1 data: password: YXNkcXdlMTIzQA== username: YWRtaW4= kind: Secret metadata: creationTimestamp: "2024-07-28T13:29:49Z" name: my-springdata-secret namespace: default resourceVersion: "3407379" uid: 6b5baaf9-1bc6-4b56-b26a-24e483fd764a type: Opaque
1.4.3使用secret拉取私有仓库镜像 使用阿里云私有仓库作为演示仓库
从私有仓库拉取镜像需要账号密码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 [root@k8s-master01 secret]# docker pull registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx Using default tag: latest Error response from daemon: pull access denied for registry.cn-beijing.aliyuncs.com/java-demo-test/nginx, repository does not exist or may require 'docker login': denied: requested access to the resource is denied # 登录镜像仓库 [root@k8s-master01 secret]# docker login --username=794940840@qq.com registry.cn-beijing.aliyuncs.com Password: #这里输入的密码是wawxy1314@ WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded #提示登录成功 # 拉取镜像成功 [root@k8s-master01 secret]# docker pull registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.24.0 1.24.0: Pulling from k8s-liujunwei/nginx 04e7578caeaa: Pull complete 57a1056ea484: Pull complete 6989106bacf0: Pull complete c00d1142b331: Pull complete cb49393af980: Pull complete 5ac1ebd8aebe: Pull complete Digest: sha256:47e27097c9c6a7ee3b07d44888a6c441af465cfb79bb6b9d205a1294093bb9d0 Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.24.0 registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.24.0 # 可以看到镜像已经存在 [root@k8s-master01 secret]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx-lotsys v1 582eff85ec45 9 days ago 293MB registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx 1.24.0 6c0218f16876 15 months ago 142MB
在k8s中演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 # 编辑deploy的yaml文件,将镜像的拉取策略改为Always(总是从仓库拉取) [root@k8s-master01 configmap]# cat dp-cm.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx imagePullPolicy: Always volumeMounts: - name: redisconf mountPath: /etc/config # - name: redisconf # mountPath: /etc/config2 volumes: - name: redisconf configMap: name: redis-conf items: - key: redis.conf path: zidingyi.conf - key: redis.conf path: test.conf mode: 0400 defaultMode: 0755 # 创建这个deployment [root@k8s-master01 configmap]# kubectl delete -f dp-cm.yaml deployment.apps "dp-cm" deleted # 查看pod的创建情况 [root@k8s-master01 configmap]# kubectl get pod NAME READY STATUS RESTARTS AGE dp-cm-58d5d8d9-tnw54 0/1 ImagePullBackOff 0 2m48s # 使用describe查看具体报错信息 [root@k8s-master01 configmap]# kubectl describe po dp-cm-58d5d8d9-tnw54 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m10s default-scheduler Successfully assigned default/dp-cm-58d5d8d9-tnw54 to k8s-node01 Normal Pulling 113s (x4 over 3m10s) kubelet Pulling image "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine" Warning Failed 113s (x4 over 3m10s) kubelet Failed to pull image "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine": failed to pull and unpack image "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine": failed to resolve reference "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed Warning Failed 113s (x4 over 3m10s) kubelet Error: ErrImagePull Warning Failed 84s (x6 over 3m9s) kubelet Error: ImagePullBackOff Normal BackOff 72s (x7 over 3m9s) kubelet Back-off pulling image "registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine" # 从错误信息提示中可以看出访问被拒绝,没有授权 # 接下来演示创建一个docker-registry类型的secret用来存储镜像仓库的地址,用户名以及密码,用来拉取私有仓库的镜像 [root@k8s-master01 configmap]# kubectl create secret docker-registry my-aliyun-registry --docker-username=794940840@qq.com --docker-password=wawxy1314@ --docker-email=794940840@qq.com --docker-server=registry.cn-beijing.aliyuncs.com secret/my-aliyun-registry created # 以下是对这条命令中每个参数的解释 ---------------------------- kubectl: 是 Kubernetes 的命令行工具。 create: 是用于创建资源的命令。 secret: 是用于创建 Secret 资源的命令。 docker-registry: 是 Secret 资源的类型,用于存储 Docker Registry 的认证信息。 my-aliyun-registry: 是 Secret 资源的名称。 --docker-username: 是用于指定 Docker Registry 的用户名的参数,794940840@qq.com: 是 Docker Registry 的用户名。 --docker-password: 是用于指定 Docker Registry 的密码的参数,wawxy1314@: 是 Docker Registry 的密码。 --docker-email: 是用于指定 Docker Registry 的电子邮件地址的参数。794940840@qq.com: 是 Docker Registry 的电子邮件地址。邮箱信息可以为空 --docker-server: 是用于指定 Docker Registry 的服务器地址的参数。registry.cn-beijing.aliyuncs.com: 是 Docker Registry 的服务器地址。 总的来说,这条命令用于创建一个名为 my-aliyun-registry 的 Secret 资源,用于存储 Docker Registry 的认证信息,包括用户名、密码、电子邮件地址和服务器地址。 这个 Secret 资源可以被用于在 Kubernetes 中访问 Docker Registry,例如拉取镜像或推送镜像。 ---------------------------- # 查看创建的这个secret # 可以看到名称my-aliyun-registry 的secret的格式是kubernetes.io/dockerconfigjson格式 [root@k8s-master01 configmap]# kubectl get secrets NAME TYPE DATA AGE db-user-pass Opaque 2 93m dev-db-user-pass Opaque 2 84m my-aliyun-registry kubernetes.io/dockerconfigjson 1 2m36s mysecret Opaque 2 70m # 如果命令忘记了可以是explain查看帮助 [root@k8s-master01 configmap]# kubectl explain po.spec.imagePullSecrets # 在pod中使用这个secret [root@k8s-master01 configmap]# cat dp-cm.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: imagePullSecrets: #用于指定 Docker Registry 的认证信息。它是一个列表,可以包含了多个 Secret 资源的名称。 - name: my-aliyun-registry #指定名字是my-aliyun-registry的secret - name: my-dockerhub-registry containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx imagePullPolicy: Always volumeMounts: - name: redisconf mountPath: /etc/config # - name: redisconf # mountPath: /etc/config2 volumes: - name: redisconf configMap: name: redis-conf items: - key: redis.conf path: zidingyi.conf - key: redis.conf path: test.conf mode: 0400 defaultMode: 0755 总结:在 Kubernetes 中,一个 Pod 可以包含多个容器,而每个容器可能需要从不同的 Docker Registry 中拉取镜像。如果我们将 imagePullSecrets 配置在 spec.containers 区域,那么我们需要为每个容器指定一个单独的 Secret 资源,这样会很麻烦。
更新以下之前没有拉取成功的deployment
1 2 3 4 5 6 7 [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml deployment.apps/dp-cm replaced #查看pod的状态,已经成功运行 [root@k8s-master01 configmap]# kubectl get po NAME READY STATUS RESTARTS AGE dp-cm-bfcf596d8-85psj 1/1 Running 0 31s
1.4.4secret管理https证书 首先使用命令生产证书,生产环境应该是买的正式证书,这里使用命令生成的证书只用于测试环境:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=test.com" # 该命令会生成tls.crt和tls.key两个文件 [root@k8s-master01 configmap]# openssl req -x509 -nodes -days 365 \ > -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=test.com" Generating a 2048 bit RSA private key ..+++ .......+++ writing new private key to 'tls.key' ----- [root@k8s-master01 configmap]# ll total 12 drwxr-xr-x 2 root root 59 Jul 28 14:25 conf -rw-r--r-- 1 root root 896 Jul 28 22:37 dp-cm.yaml -rw-r--r-- 1 root root 1090 Jul 28 22:51 tls.crt -rw-r--r-- 1 root root 1704 Jul 28 22:51 tls.key # 利用证书的tls.crt和tls.key的两个文件生成secret [root@k8s-master01 configmap]# kubectl create secret tls nginx-test-tls --cert=tls.crt --key=tls.key secret/nginx-test-tls created # 这条命令是用于创建一个 TLS 证书的 Secret 资源。 以下是命令的解释: * `kubectl`: 是 Kubernetes 的命令行工具。 * `create`: 是用于创建资源的命令。 * `secret`: 是用于创建 Secret 资源的命令。 * `tls`: 是 Secret 资源的类型,用于存储 TLS 证书。 * `nginx-test-tls`: 是 Secret 资源的名称。 * `--cert`: 是用于指定 TLS 证书文件的参数。 * `tls.crt`: 是 TLS 证书文件的名称。 * `--key`: 是用于指定 TLS 私钥文件的参数。 * `tls.key`: 是 TLS 私钥文件的名称。 总的来说,这条命令用于创建一个名为 `nginx-test-tls` 的 Secret 资源,用于存储 TLS 证书和私钥。 这个 Secret 资源可以被用于在 Kubernetes 中配置 TLS 加密的服务,例如 HTTPS 服务。 注意:TLS 证书和私钥文件需要是 PEM 格式的。 在这个例子中,我们指定了一个名为 `tls.crt` 的证书文件和一个名为 `tls.key` 的私钥文件,这些文件将被用于创建 Secret 资源。 # 查看创建的secret [root@k8s-master01 configmap]# kubectl get secrets NAME TYPE DATA AGE nginx-test-tls kubernetes.io/tls 2 2m5s [root@k8s-master01 configmap]# kubectl get secrets nginx-test-tls -oyaml apiVersion: v1 data: tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrVENDQWVHZ0F3SUJBZ0lKQU9UWGJocTZvMlJvTUEwR0NTcUdTSWIzRFFFQkN3VUFNQk14RVRBUEJnTlYKQkFNTUNIUmxjM1F1WTI5dE1CNFhEVEkwTURjeU9ERTBOVEUwTWxvWERUSTFNRGN5T0RFME5URTBNbG93RXpFUgpNQThHQTFVRUF3d0lkR1Z6ZEM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCCkFRQ2d5MmNOVFFlK0NuS2d5eFEwbkhKallOZkZTUUtGSHZyZFZaZTBwZXRURXVvSEM1WDJ6NWdTQ3huYWJHRjQKSmVjMG13ZForejZtSXlYRWVMTlVsVGRqWERTay8xOVBkYnNFVkJlSVYzMjBuZ3prMTdIUEVvbmZNcWRBZ09seApabCtVSkZYTWVadklkWCthNzNxVVBEUWlRVERSaXNHN04vSlpVRG0rOVlHN3QxOWluaXdKaHBmQmZZeTM3cVovCmZlSU9WTTVSSk00WkFOTHE0ZE9OYjg5Uk41M3RzZWVaTlUrRi9LQnp3N1dhbml2QnZFdldsWkpBdFZhejB3WEcKRWFNd0lCODNVN3BCaXdPSnlOTWdFK2I1MGpBNzFvWFdkRlNIcVhwODJBcDhUeVBHT2Nna0VyZC9VdzUvQjN5awpqNlNYSHdrY0VHR0ZxUTc1QVV0S01rUHZBZ01CQUFHalVEQk9NQjBHQTFVZERnUVdCQlRuNmNQcThrTGpFTW8yCnJPNmErUXdXRGd2NVJ6QWZCZ05WSFNNRUdEQVdnQlRuNmNQcThrTGpFTW8yck82YStRd1dEZ3Y1UnpBTUJnTlYKSFJNRUJUQURBUUgvTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCUkRKdkVFYXBZT0JOd1NBdUFOTU1OWmtmVwpoYjJrN2ZqcVhXbWhEai9ZdFp1VEhkcUhLZFJDRm9PbDB2SEpIcVEvS0pQaVRwZXJDV3V2U1Z0Z1REUS80ZVovCkJ2dEZnV2p3NTdzcExQR2xMdGNYM2lQVTEwdjhsbVQ2WWppeU1CVGFwd2ZrditDVUJ0WlpIdThvWlM2ZkJhemkKc3JEVWcva3BTa2ZqejBVSXFOT0VXNmV1TTlydUxXZU1OWnRTV2hyQW5UYTh2b2lPNnpSY0Eza1pVUVlhOGpzQgovSm1Lc3FNRm1KTFlveUFidmVOOUtvM1hxbEpYMFNBVVZlZjFqVG9CcG42STNzeUN6TDVzZXhMTEQvcFNHdTlkCkJmTUovNHlCZlJRZlB3ODRmVGp5bmgrY3ErYnl1OGZ4MFdkWkpkMktxMG1WTU9kU3NwN2cwMkVKcmpZRQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2d5MmNOVFFlK0NuS2cKeXhRMG5ISmpZTmZGU1FLRkh2cmRWWmUwcGV0VEV1b0hDNVgyejVnU0N4bmFiR0Y0SmVjMG13ZForejZtSXlYRQplTE5VbFRkalhEU2svMTlQZGJzRVZCZUlWMzIwbmd6azE3SFBFb25mTXFkQWdPbHhabCtVSkZYTWVadklkWCthCjczcVVQRFFpUVREUmlzRzdOL0paVURtKzlZRzd0MTlpbml3SmhwZkJmWXkzN3FaL2ZlSU9WTTVSSk00WkFOTHEKNGRPTmI4OVJONTN0c2VlWk5VK0YvS0J6dzdXYW5pdkJ2RXZXbFpKQXRWYXowd1hHRWFNd0lCODNVN3BCaXdPSgp5Tk1nRStiNTBqQTcxb1hXZEZTSHFYcDgyQXA4VHlQR09jZ2tFcmQvVXc1L0IzeWtqNlNYSHdrY0VHR0ZxUTc1CkFVdEtNa1B2QWdNQkFBRUNnZ0VBTzRxV1ltcC96M04yOXV1OFU2OEsvSm5Eeko0NGZLcjRJaldyczQwdEV0b1MKSndHM1NtbWMyakdhSlRPMDlCUzFCTm5UWXhLU0pGc25oUlZjOHBrK3BXQmpiaVhTV1U0ekxtc2xPNnVLTlBQQgp1b3ZVbitVeGdLRDFKZ0dXY0JPRW1RckxhcWd0YzVGdTZ5UjZzNkdIZkplL1NCaWxuSG9mRjh1SlZwajZyVk9uCmdBWDFKVUhSS3NpUGh1SHh1cFAzNURETzQwbHVMbGg1UGZWUVl1WkN5Y3Z0cDFRclcyeTR5YlY3RWRwTExKWUUKQXhnazl3dEFJdS8ralloVXBGaTVXRDM2SjMvS2MwNUZsOXNZY3l6dXdxZy9pTlVlVG9zRjROTTgwYVR0TGt5TApFM1Z6SVgwYkpwK3NNaFVxNWh3TFF5MW1HcEoyZ016d0NhcGpZWS9ob1FLQmdRRFE0Z0VKRUZYOXk4QWlKNFF1CnpYd1RFSFRSZXZmdFplOXE1YVZxK2RqVmMwdWNBVFlNeVJ2Y1ZnNGUvWE95akRyUG9pNXZEN1RJWDFmYWdEVmoKUmpJeWlvY3dnWUZqQW9mS0YzOG1TaWFLaGN6blVxbnpxNlpqSVBrUFJLcWJOL2tHTmdRQlBFY1p1djBDSDNGNwpkcjNxNE4vdlhaSkNGMjZDN1p6RU5sa0tqUUtCZ1FERkVJYjR2bmIxT1BCbi92Nm0wbnJNbGJxbmhDK2xxNTBUCjVqSUE4VEdQLzNCTDBONWxJa3VlUGtFUzlZOUxXVkNUbVQ2SXhqTmZzWU9kT1g0aVRXOVBESS9BTWZ1QXhxblkKU2p5cyt3Q2Z3bU5iak1KVThmUC90UDMvdlAyT0hyaldvZmdFaGFWc01Lb1NibGNKNFA0TzlIcFVXcHdubFFNaQpzbllSNXJVSGF3S0JnRTRPUm1qR3EvdWRLZjBaV3pIS0k3VlVEdk5BeW1qeUVKZVhuVXJ1ZG5LOUZPSUZLZGQ1ClIybjgxbVlLUERQYVp4ZXorVG9UV25FTi85eHMwSVo2Y3NPa05JU1J3SEhwUGlqc3d0emlGS2pxK3ZqdVVRZjMKZXNQTVRJWENHU2JMc2NqNlltQzd6NjN6ekJ3QTkvMDFFQjgzVFRjN2RpNHdaMkdSdldVdEVmVDVBb0dCQUpTUwphMUFxT1FHVTFodHg4b2ZQZEdtK0VTV3UwVVYwWjA3VFpLdTFMSXJHS09IZ0xXdk9PWGlxc3VFYVpkaUhFK3JUCnhJUFYrbkdSSWd0dGh4MVJpRFB1NG9vaXBOMW42akY1ZHRscnZBSzJ5YllDSDVsdmVXZzJDckcreU9OWFlqL2YKaVYvUGF2SndsaWlqSzlmMDIxWm5GN3QxUFBuU3JMU0NHK1pQSy9qVkFvR0FKd1k4MVR5NVlNQjZxbFJPM2hvNgpFLy9PeStiNE1Da2g5cVROcmlwZ01kUzllYUp3TjZ2K2FIejk1SEdOQUVab2JCL3JpNU1DOU0vMytxYWUzaVlJCnhKTHRvRWwrR01hMk1KemtRQUpkSkxVQzBFMFA3aGJLbm5NT2sxY000b3gyakdSZXNMekVzSzdPeHF3VVQ3TUIKRFJ1TEo3dTdCLytNbjljSDFiczh5ZFE9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K kind: Secret metadata: creationTimestamp: "2024-07-28T14:55:26Z" name: nginx-test-tls namespace: default resourceVersion: "3421361" uid: 2a07ae0e-4862-441e-a36f-665b518b2cb9 type: kubernetes.io/tls
在ingress中引用这个secret:使用tls参数进行配置
注意:这样配置的前提是ingress暴露在公网,如果ingress前面有slb负载,那么ssl证书应该配置在slb上
1.5使用SubPath解决挂载覆盖的问题 上述configmap挂载中的演示都是把文件挂载到一个空的目录中,所以没有问题
如果挂载到一个有文件的目录中,例如把nginx.conf挂载到容器的/etc/nginx中,nginx.conf会覆盖容器的/etc/nginx,目录中只会有一个nginx.conf,这样会导致nginx无法启动,下面进行演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # 准备一个nginx.conf [root@k8s-master01 configmap]# cat nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 512; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }
基于nginx.conf创建一个configmap
1 2 3 4 5 [root@k8s-master01 configmap]# kubectl create configmap nginx-conf --from-file=nginx.conf configmap/nginx-conf created [root@k8s-master01 configmap]# kubectl get cm NAME DATA AGE nginx-conf 1 9s
在pod中引用这个名字是nginx-conf的cm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 [root@k8s-master01 configmap]# cat dp-cm.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: imagePullSecrets: - name: my-aliyun-registry containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx imagePullPolicy: Always volumeMounts: - name: nginxconf mountPath: /etc/nginx #这样配置会覆盖/etc/nginx目录所有文件,只有一个nginx.conf的文件,容器会启动失败 volumes: - name: nginxconf configMap: name: nginx-conf # 创建deployment [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml deployment.apps/dp-cm replaced # 查看pod状态,状态Error [root@k8s-master01 configmap]# kubectl get po NAME READY STATUS RESTARTS AGE dp-cm-6f5859f7df-dcm8q 0/1 Error 3 (40s ago) 57s # 查看日志 [root@k8s-master01 configmap]# kubectl logs -f dp-cm-6f5859f7df-dcm8q /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf is not a file or does not exist /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh /docker-entrypoint.sh: Configuration complete; ready for start up 2024/07/28 15:28:11 [emerg] 1#1: open() "/etc/nginx/mime.types" failed (2: No such file or directory) in /etc/nginx/nginx.conf:15 nginx: [emerg] open() "/etc/nginx/mime.types" failed (2: No such file or directory) in /etc/nginx/nginx.conf:15 # 日志提示无法找到文件或目录,原因是覆盖导致nginx核心文件被清理了,nginx的容器无法启动 # 这种情况就可以是subpath解决文件覆盖的问题 [root@k8s-master01 configmap]# cat dp-cm.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: dp-cm name: dp-cm spec: replicas: 1 selector: matchLabels: app: dp-cm template: metadata: labels: app: dp-cm spec: imagePullSecrets: - name: my-aliyun-registry containers: - image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine name: nginx imagePullPolicy: Always volumeMounts: - name: nginxconf mountPath: /etc/nginx/nginx.conf subPath: nginx.conf #使用这个参数解决挂载覆盖的问题 volumes: - name: nginxconf configMap: name: nginx-conf # 创建deploy [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml deployment.apps/dp-cm replaced # 查看pod状态 [root@k8s-master01 configmap]# kubectl get po NAME READY STATUS RESTARTS AGE dp-cm-85dfcf698d-fvdmz 1/1 Running 0 7m29s # 查看nginx.conf的worker_connections 是不是512,如果是证明挂载成功,并没有把其他文件覆盖 [root@k8s-master01 configmap]# kubectl exec dp-cm-85dfcf698d-fvdmz -- cat /etc/nginx/nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 512; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }
subPath总结:
1 `subPath` 是一个可选参数,用于指定卷挂载点的子路径。它允许你将 ConfigMap 中的单个文件挂载到容器中的特定路径。
1.6configmap&secret热更新 方式一:更新通过yaml文件方式创建的资源
1 直接对yaml文件进行修改,然后执行replace命令对configmap进行更新即可(kubectl replace -f configmap.yaml)
方式二:通过–from-file创建的configmap使用下面指令进行更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 # 对于使用--from-file创建的configmap资源,通过先对文件进行修改,在将文件导入configmap中 # 例如需要修改名字是nginx-conf的conf [root@k8s-master01 ~]# kubectl get cm NAME DATA AGE nginx-conf 1 5d23h redis-conf 1 6d7h # nginx-conf创建是--from-file指定的文件是nginx.conf(可以通过kubectl get cm nginx-conf -oyaml命令中的data字段获取) # 直接对nginx.conf进行修改,例如将worker_connections的值修改为2048; [root@k8s-master01 configmap]# kubectl create cm nginx-conf --from-file=nginx.conf --dry-run=client -oyaml|kubectl replace -f - configmap/nginx-conf replaced # 查看修改的2048是否生效 [root@k8s-master01 configmap]# kubectl get cm nginx-conf -o yaml apiVersion: v1 data: nginx.conf: |2 user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 2048; #这里修改已经生效 } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; } kind: ConfigMap metadata: creationTimestamp: "2024-07-28T15:18:36Z" name: nginx-conf namespace: default resourceVersion: "3691636" uid: b7d278c1-2e09-46cf-8022-649d930621ef
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 命令: kubectl create cm nginx-conf --from-file=nginx.conf --dry-run=client -oyaml|kubectl replace -f - # 第一部分: kubectl create cm nginx-conf --from-file=nginx.conf --dry-run=client -oyaml kubectl create cm nginx-conf # 创建一个名为 nginx-conf 的 ConfigMap --from-file=nginx.conf # 使用名为 nginx.conf 的文件内容创建 ConfigMap --dry-run=client # 模拟创建操作,但不实际提交到集群 -oyaml # 输出 YAML 格式的结果 # 第二部分: | (管道操作符) # 将第一部分的输出作为第二部分的输入 # 第三部分: kubectl replace -f - kubectl replace # 替换已存在的资源 -f - # 从标准输入(stdin)读取配置文件
1.7configmap&secret使用限制
使用configmap和secret需要提前创建,才能在pod中引用,否则会提示资源不存在或者pod一直处于pending状态
引用的key必须存在
使用envFrom和valueFrom无法热更新环境变量,此时需要重启pod
使用envFrom配置环境变量,如果key是无效的,它会忽略掉无效的key
configmap和secret必须要和pod或者是引用它的资源在同一个命名空间
使用subPath也是无法热更新的
configmap和secret最好不要太大(不要超过2m)
1.8配置只读的configmap和secret 1 在资源的yaml文件添加immutable: true参数即可,该配置和kind同级。