在部署应用程序时,我们都会涉及到应用的配置,在容器中,如Docker容器中,如果将配置文件打入容器镜像,这种行为等同于写死配置,每次修改完配置,镜像就得重新构建。当然,我们也可以通过挂载包含该文件的卷进行配置管理和修改。而在k8s中,我们要讲一种更好的方式,即ConfigMap,这种资源对象的出现,更是极大的方便了应用程序的配置管理。
ConfigMap是一个或多个key/value的形式保存在k8s中,内部可以管理变量也可以管理完整的配置文件内容。
spec.env或者spec.envFrom进行引用。spec.volumes引用。注:在使用命令的时候注意单词: configmap等价于cm,cm算是简写,类似于deployment可以使用命令时写成deploy,service可以写成svc,namespace可以写成ns,pod可以写成po。
示例:
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: cm-test01
- data:
- appconf01: value01
- appconf02: value02
命令:
- [root@k8s-master k8s]# kubectl create -f cm-test01.yaml
- configmap/cm-test01 created
--from-file参数从文件中读取。可以指定key的名称,若不指定,则默认使用文件名为key。- [root@k8s-master k8s]# cat test.properties
- key01:value01
- key02:value02
- conf01: value03
命令:
- [root@k8s-master k8s]# kubectl create cm cm-test-file --from-file=test.properties
- configmap/cm-test-file created
- //指定参数方式,通过--from-literal指定keyxx=valuexx创建confimap中的data内配置属性。
- [root@k8s-master k8s]# kubectl create configmap cm-test-literal --from-literal=key01=value01 --from-literal=key02=value02
- configmap/cm-test-literal created
- [root@k8s-master k8s]# kubectl get cm
- NAME DATA AGE
- cm-test-file 1 3m51s
- cm-test-literal 2 3m30s
- cm-test01 2 9m2s
- kube-root-ca.crt 1 4d16h
- [root@k8s-master k8s]# kubectl describe cm cm-test01
- Name: cm-test01
- Namespace: default
- Labels:
- Annotations:
-
- Data
- ====
- appconf01:
- ----
- value01
- appconf02:
- ----
- value02
- Events:
- [root@k8s-master k8s]# kubectl describe cm cm-test-file
- Name: cm-test-file
- Namespace: default
- Labels:
- Annotations:
-
- Data
- ====
- test.properties:
- ----
- key01:value01
- key02:value02
- conf01: value03
-
-
- Events:
- [root@k8s-master k8s]# kubectl describe cm cm-test-literal
- Name: cm-test-literal
- Namespace: default
- Labels:
- Annotations:
-
- Data
- ====
- key01:
- ----
- value01
- key02:
- ----
- value02
- Events:
- [root@k8s-master k8s]# kubectl get cm cm-test01 -o yaml
- apiVersion: v1
- data:
- appconf01: value01
- appconf02: value02
- kind: ConfigMap
- metadata:
- creationTimestamp: "2022-08-07T00:18:47Z"
- name: cm-test01
- namespace: default
- resourceVersion: "44876"
- uid: 7492a928-b163-4b86-a3dd-54a7fbe59a10
- [root@k8s-master k8s]# kubectl get configmap cm-test-file -o yaml
- apiVersion: v1
- data:
- test.properties: |+
- key01:value01
- key02:value02
- conf01: value03
-
- kind: ConfigMap
- metadata:
- creationTimestamp: "2022-08-07T00:23:58Z"
- name: cm-test-file
- namespace: default
- resourceVersion: "45341"
- uid: 818a39b4-cbaf-4643-9541-1119b4d61982
- [root@k8s-master k8s]# kubectl get cm cm-test-literal -o yaml
- apiVersion: v1
- data:
- key01: value01
- key02: value02
- kind: ConfigMap
- metadata:
- creationTimestamp: "2022-08-07T00:24:19Z"
- name: cm-test-literal
- namespace: default
- resourceVersion: "45372"
- uid: 051849e0-bf0a-4926-a549-2405dc4963cc
[root@k8s-master k8s]# kubectl edit cm cm-test01
configmap/cm-test01 edited
- [root@k8s-master k8s]# kubectl edit cm cm-test01
- configmap/cm-test01 edited

通过kubectl describe cm cm-test01查看更新是否生效
- [root@k8s-master k8s]# kubectl describe cm cm-test01
- Name: cm-test01
- Namespace: default
- Labels: <none>
- Annotations: <none>
-
- Data
- ====
- appconf02:
- ----
- value02
- appconf01:
- ----
- value001
- Events: <none>

直接更新yaml文件里的值,通过 kubectl apply -f configmap-test01.yaml重新发布一遍进行更新
$ kubectl delete -f configmap-test01.yaml
kubectl delet cm cm-test01
容器应用对ConfigMap的使用主要是两种:
1)通过环境变量获取ConfigMap的内容:spec.env和spec.envFrom
2)通过卷volume挂载的方式将ConfigMap的内容挂载到容器内部的文件或目录:spec.volumes
以下内容均以上述的ConfigMap资源cm-test01为例
sepc.env方式
- [root@k8s-master k8s]# vim pod-test01.yaml
-
- apiVersion: v1
- kind: Pod
- metadata:
- name: cm-pod-test001
- spec:
- containers:
- - name: cm-test
- image: tomcat:8
- command: [ "/bin/sh", "-c", "env | grep APP"]
- env:
- - name: APPCONF01 # 定义环境变量的名称
- valueFrom: # key “appconf01”的值获取
- configMapKeyRef:
- name: cm-test01 # 环境变量的值来自于configmap cm-test01
- key: appconf01 # configmap中的配置key为appconf01
- - name: APPCONF02 # 定义环境变量的名称
- valueFrom: # key “appconf02”的值获取
- configMapKeyRef:
- name: cm-test01 # 环境变量的值来自于configmap cm-test01
- key: appconf02 # configmap中的配置key为appconf02
- restartPolicy: Never # 重启策略:从不。

执行创建pod:
- [root@k8s-master k8s]# kubectl create -f pod-test01.yaml
- pod/cm-test001 created
- [root@k8s-master k8s]# kubectl get pods
- [root@k8s /cm/test]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- cm-pod-test001 0/1 Completed 0 1h
-
- [root@k8s-master k8s]# kubectl logs cm-pod-test001
- APPCONF01=value01
- APPCONF02=value02
说明容器内部的环境变量使用ConfigMap中进行读取的
spec.envFrom方式
yaml文件
- [root@k8s-master k8s]# vim pod-test02.yaml
-
- piVersion: v1
- kind: Pod
- metadata:
- name: cm-pod-test002
- spec:
- containers:
- - name: cm-test2
- image: tomcat:8
- command: [ "/bin/sh", "-c", "env"]
- envFrom:
- - configMapRef:
- name: cm-test01 # 根据ConfigMap cm-test01资源自动生成环境变量
- restartPolicy: Never

执行创建pod:
[root@k8s-master k8s]# kubectl create -f pod-test02.yaml
- [root@k8s-master k8s]# kubectl get po
- NAME READY STATUS RESTARTS AGE
- cm-pod-test001 0/1 Completed 0 2h
- cm-pod-test002 0/1 Completed 0 1h
注意:
环境变量的名称受限制:[a-zA-Z][a-zA-Z0-9_]*,不能以数字或非法字符开头。
指定items
- [root@k8s-master k8s]# vim pod-test03.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: cm-pod-test003
- spec:
- containers:
- - name: cm-test3
- image: tomcat:8
- volumeMounts:
- - name: vm-01-1
- mountPath: /conf
- volumes:
- - name: vm-01-1
- configMap:
- name: cm-test-file
- items:
- - key: key-testproperties
- path: test.properties
- restartPolicy: Never
不指定items
- [root@k8s-master k8s]# vim pod-test04.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: cm-pod-test004
- spec:
- containers:
- - name: cm-test4
- image: tomcat:8
- volumeMounts:
- - name: vm-02-2
- mountPath: /conf
- volumes:
- - name: vm-02-2
- configMap:
- name: cm-test-file
- restartPolicy: Never
进入容器中查看
[root@k8s-master k8s]# kubectl exec -it cm-pod-test004 -c cm-test4 -- bash
进入容器后,ls /conf查看是否有test.properties文件。
- [root@k8s-master k8s]# kubectl exec -it cm-pod-test004 -c cm-test4 -- bash
- root@cm-pod-test004:/usr/local/tomcat# ls /conf
- test.properties
关于--from-file的方式的创建指定key和不指定key的区别
1)不指定key名
- 创建:
- [root@k8s-master k8s]# kubectl create cm cm-test-file --from-file=test.properties
- 输出:
- [root@k8s-master k8s]# kubectl get cm cm-test-file -o yaml

2)指定key
- 2)指定key
- 创建:
- [root@k8s-master k8s]# kubectl create cm cm-test-file02 --from-file=tp=test.properties
- 输出:
- [root@k8s-master k8s]# kubectl get cm cm-test-file -o yaml

若指定key的名称,configmap中将会使用指定名称;若不指定,则默认使用文件名为key。
Secret对象与ConfigMap对象类似,但它主要用于存储以下敏感信息,例如密码,OAuth token和SSH key等等。将这些信息存储在secret中,和直接存储在Pod的定义中,或Docker镜像定义中相比,更加安全和灵活。
Secret有三种类型:
Opaque类型的Secret,其value为base64编码后的值。
其他的参考Secret | Kubernetes
分别创建两个名为username.txt和password.txt的文件:
- [root@k8s-master k8s]# echo -n "admin" > ./username.txt
- [root@k8s-master k8s]# echo -n "123456" > ./password.txt
- [root@k8s-master k8s]# kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
- secret/db-user-pass created
- [root@k8s-master k8s]# echo -n 'name' | base64
- bmFtZQ==
- [root@k8s-master k8s]# echo -n '123456' | base64
- MTIzNDU2
创建secret
- [root@k8s-master k8s]# cat secret.yaml
- apiVersion: v1
- kind: Secret
- metadata:
- name: mysecret
- type: Opaque
- data:
- username: bmFtZQ==
- password: MTIzNDU2
- [root@k8s-master k8s]# kubectl create -f secret.yaml
- secret/mysecret created

查看secret
- [root@k8s-master k8s]# kubectl get secrets | grep myse
- mysecret Opaque 2 109s
- [root@k8s-master k8s]# kubectl describe secrets mysecret
- Name: mysecret
- Namespace: default
- Labels:
- Annotations:
-
- Type: Opaque
-
- Data
- ====
- password: 6 bytes
- username: 4 bytes
- [root@k8s-master k8s]# kubectl get secrets mysecret -o yaml
- apiVersion: v1
- data:
- password: MTIzNDU2
- username: bmFtZQ==
- kind: Secret
- metadata:
- creationTimestamp: "2022-08-07T02:21:23Z"
- name: mysecret
- namespace: default
- resourceVersion: "58148"
- uid: 261bd305-2376-47bd-a0fe-5563fdde8752
- type: Opaque
创建好Secret之后,可以通过两种方式使用:
- [root@k8s-master k8s]# cat mypod1.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: mypod
- spec:
- containers:
- - name: mypod
- image: redis
- volumeMounts:
- - name: foo
- mountPath: "/etc/foo"
- readOnly: true
- volumes:
- - name: foo
- secret:
- secretName: mysecret

- [root@k8s-master k8s]# kubectl create -f mypod1.yaml
- pod/mypod created
-
- [root@k8s-master k8s]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
-
- mypod 0/1 ContainerCreating 0 12s
-
- [root@k8s-master k8s]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
-
- mypod 1/1 Running 0 30s
进入pod查看挂载的Secret:
- [root@k8s-master k8s]# kubectl exec -it mypod /bin/bash
- kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
- root@mypod:/data# cd /etc/foo/
- root@mypod:/etc/foo# ls
- password username
- root@mypod:/etc/foo# cat password
- 123456root@mypod:/etc/foo# cat username
- nameroot@mypod:/etc/foo#
也可以只挂载Secret中特定的key:
- apiVersion: v1
- kind: Pod
- metadata:
- name: mypod
- spec:
- containers:
- - name: mypod
- image: redis
- volumeMounts:
- - name: foo
- mountPath: "/etc/foo"
- readOnly: true
- volumes:
- - name: foo
- secret:
- secretName: mysecret
- items:
- - key: username
- path: my-group/my-username
在这种情况下:
username 存储在/etc/foo/my-group/my-username中
password未被挂载
- apiVersion: v1
- kind: Pod
- metadata:
- name: secret-env-pod
- spec:
- containers:
- - name: mycontainer
- image: redis
- env:
- - name: SECRET_USERNAME
- valueFrom:
- secretKeyRef:
- name: mysecret
- key: username
- - name: SECRET_PASSWORD
- valueFrom:
- secretKeyRef:
- name: mysecret
- key: password
- restartPolicy: Never
- [root@k8s-master k8s]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- mypod 1/1 Running 0 10m
- secret-env-pod 1/1 Running 0 37s
- [root@k8s-master secret]# kubectl exec -it secret-env-pod /bin/bash
- root@secret-env-pod:/data# env | grep -E "USERNAME|PASSWORD"
- SECRET_USERNAME=admin
- SECRET_PASSWORD=123456
- root@secret-env-pod:/data#
[root@k8s-master k8s]# kubectl create secret generic test --from-literal=MYSQL_ROOT_PASSWORD=1234567
-
- [root@k8s-master k8s]# vim myapp-demo.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: myapp-demo
- namespace: default
- spec:
- replicas: 1
- selector:
- matchLabels:
- app: myapp
- template:
- metadata:
- labels:
- app: myapp
- spec:
- containers:
- - name: myapp
- image: ikubernetes/myapp:v1
- imagePullPolicy: IfNotPresent
- ports:
- - name: http
- containerPort: 80
- volumeMounts:
- - name: mysql
- mountPath: /test/
- volumes:
- - name: mysql
- secret:
- secretName: test
目录