跳转至

Kubernetes配置与密钥管理 ConfigMap

什么是 configmap

什么是 configmap

  • kubernetes 集群可以使用 ConfigMap 来实现对容器中应用的配置管理
  • 可以把 ConfigMap 看作是一个挂载到 pod 中的存储卷

创建 ConfigMap 的 4 种方式

在命令行指定参数创建

1. 通过直接在命令行中指定configmap参数创建,即 '--from-literal=key=value'
[root@k8smaster001 cm]# kubectl create configmap configmap-001 --from-literal=host=127.0.0.1 --from-literal=port=3306
configmap/configmap-001 created

[root@k8smaster001 cm]# kubectl get cm
NAME               DATA   AGE
configmap-001      2      18s
2. 查看创建的 configmap-001 详细信息
[root@k8smaster001 cm]# kubectl describe cm configmap-001
Name:         configmap-001
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
host:
----
127.0.0.1
port:
----
3306

BinaryData
====

Events:  <none>

在命令行通过多个文件创建

1. 通过指定文件创建,即将一个配置文件创建为一个ConfigMap,'--from-file=文件路径';
[root@k8smaster001 cm]# echo -n 127.0.0.1 > host && echo -n 3306 > port

[root@k8smaster001 cm]# cat host  port 
127.0.0.1 3306

[root@k8smaster001 cm]# kubectl create configmap configmap-002 --from-file=./host --from-file=./port
configmap/configmap-002 created

[root@k8smaster001 cm]# kubectl get cm
NAME               DATA   AGE
configmap-001      2      7m48s
configmap-002      2      37s
2. 查看创建的 configmap-002 详细信息
[root@k8smaster001 cm]# kubectl describe cm configmap-002
Name:         configmap-002
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
host:
----
127.0.0.1
port:
----
3306

BinaryData
====

Events:  <none>

在命令行通过文件提供多个键值对创建

1. 通过一个文件内多个键值对,'--from-env-file=文件路径';
[root@k8smaster001 cm]# cat env.txt 
host=127.0.0.1
port=3306

[root@k8smaster001 cm]# kubectl create configmap configmap-003 --from-env-file=env.txt
configmap/configmap-003 created
2. 查看创建的 configmap-003 详细信息
[root@k8smaster001 cm]# kubectl get cm
NAME               DATA   AGE
configmap-001      2      28m
configmap-002      2      20m
configmap-003      2      17s

[root@k8smaster001 cm]# kubectl describe cm configmap-003
Name:         configmap-003
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
host:
----
127.0.0.1
port:
----
3306

BinaryData
====

Events:  <none>

通过 YAML 资源清单文件创建

1. 通过 'kubectl create/apply -f YMAL文件' 创建
[root@k8smaster001 cm]# kubectl create configmap configmap-004 --from-literal=host=127.0.0.1  -o yaml --dry-run=client  >> configmap-004.yaml
2. 编写 configmap-004.yaml 资源清单
apiVersion: v1
data:
  host: 127.0.0.1
  port: "3306"
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: configmap-003
3. apply 创建 configmap-004.yaml 资源清单
[root@k8smaster001 cm]# kubectl apply -f configmap-004.yaml 
configmap/configmap-004 created
4. 查看创建的 configmap-004 详细信息
[root@k8smaster001 cm]# kubectl get cm
NAME               DATA   AGE
configmap-001      2      34m
configmap-002      2      26m
configmap-003      2      6m19s
configmap-004      2      55s

[root@k8smaster001 cm]# kubectl describe cm configmap-004
Name:         configmap-004
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
host:
----
127.0.0.1
port:
----
3306

BinaryData
====

Events:  <none>

ConfigMap 的 2 种使用方式

通过环境变量的方式传递给 pod

1. 编写资源清单 pod-cm1.yml
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm1
spec:
  containers:
  - name: busybox
    image: busybox
    args: [ "/bin/sh", "-c", "sleep 10000" ]
    envFrom:                            # env方式
    - configMapRef:
        name: configmap-001                     # configmap名称
2. 创建 configmap 资源
[root@k8smaster001 cm]# kubectl apply -f  pod-cm1.yml
pod/pod-cm1 created
3. 查看创建的 pod-cm1 详细信息
[root@k8smaster001 cm]# kubectl get pods pod-cm1 
NAME      READY   STATUS    RESTARTS   AGE
pod-cm1   1/1     Running   0          30s

[root@k8smaster001 cm]# kubectl exec pod-cm1 -- env|grep 'host\|port'
host=127.0.0.1
port=3306

通过 volume 的方式挂载到 pod 内

1. 编写资源清单 pod-cm2.yml
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm2
spec:
  containers:
  - name: busybox
    image: busybox
    args: [ "/bin/sh", "-c", "sleep 10000" ]
    volumeMounts:                               # 用volume挂载方式
    - name: volume-cm                              # 对应下面的volume名
      mountPath: "/etc/mysql"                   # 挂载到容器内部的路径
      readOnly: true                            # 只读

  volumes:
  - name: volume-cm                                # 卷名称
    configMap:
      name: configmap-002                                 # configmap的名称
2. 创建 configmap 资源
[root@k8smaster001 cm]# kubectl apply -f pod-cm2.yaml 
pod/pod-cm2 created
3. 查看创建的 pod-cm2 详细信息
[root@k8smaster001 cm]# kubectl get pods pod-cm2 
NAME      READY   STATUS    RESTARTS   AGE
pod-cm2   1/1     Running   0          26s

[root@k8smaster001 cm]# kubectl exec pod-cm2 -- ls /etc/mysql/
host
port

[root@k8smaster001 cm]# kubectl exec pod-cm2 -- cat /etc/mysql/host
127.0.0.1

[root@k8smaster001 cm]# kubectl exec pod-cm2 -- cat /etc/mysql/port
3306

ConfigMap 的热更新

ConfigMap 热更新方式

如果修改了 value, 那容器内部会不会更新?

  • 通过环境变量的方式传递给 pod。这种方式不会热更新
  • 通过 volume 的方式挂载到 pod 内。这种方式会热更新,大概需要半分钟左右。

ConfigMap 热更新验证

通过环境变量方式(此种方式不会热更新)

1. 编辑修改对应的 configmap configmap-001
[root@k8smaster001 cm]# kubectl edit cm configmap-001
# 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:
  host: 127.0.0.1
  port: "3307"    3306修改成3307
kind: ConfigMap
metadata:
  creationTimestamp: "2024-04-01T08:15:31Z"
  name: configmap-001
  namespace: default
  resourceVersion: "3999033"
  uid: e7978727-1cad-4258-ba85-e92195492a43
2. 验证对应的pod里的变化,发现很久都不会改变(**环境变量方式**)
[root@k8smaster001 cm]# kubectl exec pod-cm1 -- env |grep port
port=3306

通过 volume 方式(此种方式会热更新)

1. 编辑修改对应的 configmap configmap-002
[root@k8smaster001 cm]# kubectl edit cm configmap-002
# 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:
  host: 127.0.0.1
  port: "13306"      # 修改为 13306
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"host":"127.0.0.1","port":"3306"},"kind":"ConfigMap","metadata":{"annotations":{},"creationTimestamp":null,"name":"configmap-004","namespace":"default"}}
  creationTimestamp: "2024-04-01T08:48:41Z"
  name: configmap-004
  namespace: default
  resourceVersion: "4004920"
  uid: d0e4e87c-ccee-40be-b200-b40485ef27ab
2. 验证对应的 pod 里的变化,一段时间后会改变(**卷挂载方式**)
[root@k8smaster001 cm]# kubectl exec pod-cm2 -- cat /etc/mysql/port 
13306  # 大概半分钟后更新

自动刷新策略:

  • 使用Reloader实现配置热加载
  • 通过Sidecar监控文件变化(如git-sync)

总结

总结

应用程序需要正确处理配置项的重新加载逻辑,以便在检测到配置变化时重新加载并使用新的配置。这可能需要在应用程序中实现一些逻辑来监听环境变量的变化并触发配置的重新加载。具体的实现方式取决于你的应用程序架构和使用的编程语言。