五、ConfigMap限制

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

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

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

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

  • ConfigMap最好不要太大

六、ConfigMap热更新

6.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

6.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