一、自定义挂载文件权限

ConfigMap在挂载使用时可以更改文件的权限(默认是0644),比如将上述的文件挂载权限自定义为0666(对应Linux的文件权限为rw-rw-rw-)。

1.查看key名,这里观察到为redis.conf

[root@k8s-master01 conf]# kubectl get cm redis-conf -oyaml
apiVersion: v1
data:
  redis.conf: |
    Password=456
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-03T08:19:26Z"
  name: redis-conf
  namespace: default
  resourceVersion: "33521"
  uid: acf5f51a-5cd8-413e-bf81-14a779b2f2fa

2.定义一个yaml文件,这里0666是八进制写法

[root@k8s-master01 conf]# vim 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-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: redisconf
           mountPath: /etc/config
      volumes:
       - name: redisconf
         configMap:
          name: redis-conf
          items:
            - key: redis.conf
              path: redis.conf.bak
          defaultMode: 0666

上面的配置文件是通过defaultMode来自定义挂载文件权限,也可以通过mode来实现相同的目的。且mode的优先级高于defaultMode

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-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: redisconf
           mountPath: /etc/config
      volumes:
       - name: redisconf
         configMap:
          name: redis-conf
          items:
            - key: redis.conf
              path: redis.conf.bak
              mode: 0666

3.重新部署

[root@k8s-master01 conf]# kubectl replace -f dp-cm.yaml

4.验证,观察到实际权限为666

[root@k8s-master01 conf]# kubectl get po
NAME                               READY   STATUS    RESTARTS        AGE
dp-cm-6fdff654c5-fbw75             1/1     Running   0               5s

[root@k8s-master01 conf]# kubectl exec -it dp-cm-6fdff654c5-fbw75 -- sh
#软链接权限
/# ls /etc/config/redis.conf.bak -l
lrwxrwxrwx 1 root root 21 Dec  3 11:35 /etc/config/redis.conf.bak -> ..data/redis.conf.bak
root@dp-cm-6fdff654c5-fbw75:/# cd /etc/config/..data/
#实际权限
root@dp-cm-6fdff654c5-fbw75:/etc/config/..data# ls -l
total 4
-rw-rw-rw- 1 root root 13 Dec  3 11:35 redis.conf.bak

二、ConfigMap限制

ConfigMap在使用时有很多局限性,如果没有正确使用ConfigMap,可能会导致Pod不能正常操作。目前具有的限制如下:

  • 必须先创建ConfigMap才能在Pod中引用它,如果Pod引用的ConfigMap不存在,Pod将无法启动,一直处于Pending状态。

  • Pod引用的键必须存在于ConfigMap中,否则Pod无法启动,一直处于ContainerCreating状态。

  • ConfigMap和引用它的Pod需要在同一个命名空间

  • ConfigMap最好不要太大

三、ConfigMap热更新

3.1 以Yaml文件创建的方式进行热更新

1.定义一个yaml文件

[root@k8s-master01 conf]# vim cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  player_initial_lives: '3'
  ui_properties_file_name: "user-interface.properties"
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true

2.创建cm

[root@k8s-master01 conf]# kubectl create -f cm.yaml
configmap/game-demo created

3.查看名为game-demo的cm的yaml文件

[root@k8s-master01 conf]# kubectl get cm game-demo -oyaml
apiVersion: v1
data:
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  player_initial_lives: "3"
  ui_properties_file_name: user-interface.properties
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-04T02:05:57Z"
  name: game-demo
  namespace: default
  resourceVersion: "80329"
  uid: c01cdd86-8b0d-4b97-ac1a-40bd6e14c1ad

[root@k8s-master01 conf]# cat cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  player_initial_lives: '3'
  ui_properties_file_name: "user-interface.properties"
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true

4.通过yaml文件更新cm

[root@k8s-master01 conf]# cat cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  player_initial_lives: '3'
  ui_properties_file_name: "user-interface.properties"
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  user-interface.properties: |
    color.good=purple
    color.bad=blue  #以前是yellow现在修改为blue
    allow.textmode=true

[root@k8s-master01 conf]# kubectl replace -f cm.yaml
configmap/game-demo replaced

5.验证,观察到 color.bad已变为blue

[root@k8s-master01 conf]# kubectl get cm game-demo -oyaml
apiVersion: v1
data:
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  player_initial_lives: "3"
  ui_properties_file_name: user-interface.properties
  user-interface.properties: |
    color.good=purple
    color.bad=blue
    allow.textmode=true
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-04T02:05:57Z"
  name: game-demo
  namespace: default
  resourceVersion: "81162"
  uid: c01cdd86-8b0d-4b97-ac1a-40bd6e14c1ad

3.2 以Kubectl命令创建的方式进行热更新

1.修改nginx.conf配置文件,将worker_connections修改为256

[root@k8s-master01 conf]# vim nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  256;
}

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;
}

2.重新替换文件

[root@k8s-master01 conf]# kubectl create cm nginx-conf --from-file=nginx.conf --dry-run=client -oyaml | kubectl replace -f -

上面参数说明:

  • nginx-conf:ConfigMap的名称
  • --dry-run=client -oyaml:只运行命令,并不真正地创建,并以YAML的格式输出
  • kubectl replace -f -:通过文件创建的Secret和ConfigMap不能被直接替换,但是通过YAML文件创建可以被替换,所以先使用dry-run -oyaml生成YAML文件,再进行replace即可实现热更新,该方法可以用于其他资源类型,通过YAML文件替换已经创建的资源也是可以的。

3.验证,观察到worker_connections已修改为256

[root@k8s-master01 conf]# kubectl get cm nginx-conf -oyaml
apiVersion: v1
data:
  nginx.conf: |2

    user  nginx;
    worker_processes  1;

    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;

    events {
        worker_connections  256;
    }

    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: "2022-12-03T13:40:18Z"
  name: nginx-conf
  namespace: default
  resourceVersion: "82836"
  uid: dc01f210-9d48-4b91-a76a-1840f9bb50cf

四、不可变更的ConfigMap

Kubernetes 特性 Immutable Secret 和 ConfigMaps提供了一种将各个 Secret 和 ConfigMap 设置为不可变更的选项。对于大量使用 ConfigMap 的集群 (至少有数万个各不相同的 ConfigMap 给 Pod 挂载)而言,禁止更改 ConfigMap 的数据有以下好处:

  • 保护应用,使之免受意外(不想要的)更新所带来的负面影响。
  • 通过大幅降低对 kube-apiserver 的压力提升集群性能, 这是因为系统会关闭对已标记为不可变更的 ConfigMap 的监视操作。

此功能特性由 ImmutableEphemeralVolumes 特性门控来控制。 你可以通过将 immutable 字段设置为 true 创建不可变更的 ConfigMap。 例如:

1.创建一个名为test-immutable的cm

[root@k8s-master01 conf]# kubectl create cm test-immutable --from-file=/etc/kubernetes/admin.conf

2.在线编辑cm文件

[root@k8s-master01 conf]# kubectl edit cm test-immutable

#在末尾处添加,和apiVersion属于同一列
immutable: true

#示例演示
apiVersion: v1
data:
  redis.conf: |
    Password=123
immutable: true
kind: ConfigMap
metadata:
  creationTimestamp: "2025-03-02T02:31:36Z"
  name: test-immutable
  namespace: default

3.验证,再次进行在线编辑,提示不可更改

[root@k8s-master01 conf]# kubectl edit cm test-immutable