1.1什么是ConfigMap和Secret
ConfigMap和Secret是Kubernetes系统上两种特殊类型的存储卷,ConfigMap对象用于为容器中的应用提供配置文件等信息。但是比较敏感的数据,例如密钥、证书等由Secret对象来进行配置。它们将相应的配置信息保存于对象中,而后在Pod资源上以存储卷的形式挂载并获取相关的配置,以实现配置与镜像文件的解耦。
2.1 configmap
2.1.1创建configmap的几种形式
按大类可分为两种方式,细分共有五种方式:
(一)kubectl create configmap
创建
- (1)通过命令行参数字面直接创建
- (2)通过指定文件创建
- (3)通过指定目录创建
- (4)通过指定环境变量配置文件创建
(二)yaml
文件创建
2.1.1.1从命令创建:
通过参数--from-literal
直接指定键值对。这种方式比较适用于临时测试使用,而且不适合配置很多的情况。
[root@k8s-master01 2-21]# kubectl create configmap test-cm1 \
> --from-literal=name=Larry \
> --from-literal=age=18 \
> --from-literal=web=www.wangming.com
configmap/test-cm1 created
查看内容如下:
[root@k8s-master01 2-21]# kubectl get cm test-cm1 -oyaml
apiVersion: v1
data:
age: "18"
name: Larry
web: www.wangming.com
kind: ConfigMap
metadata:
creationTimestamp: "2024-02-21T07:02:46Z"
name: test-cm1
namespace: default
resourceVersion: "301060"
uid: 9ec55f02-0484-401c-b8af-f9e644ab6039
或者
[root@k8s-master01 2-21]# kubectl describe cm test-cm1
Name: test-cm1
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
age:
----
18
name:
----
Larry
web:
----
www.wangming.com
BinaryData
====
Events: <none>
2.1.1.2 从文件创建
通过参数--from-file
来指定文件
txt.yaml文件内容如下:
[root@k8s-master01 2-21]# cat txt.yaml
server:
port: 8080
pkslow:
name: wyt
age: 18
webSite: www.wangming.link
txt1.yaml文件内容如下:
[root@k8s-master01 2-21]# cat txt1.yaml
server:
port: 8080
pkslow:
name: liming
age: 20
webSite: https://www.baidu.com
命令如下:
[root@k8s-master01 2-21]# kubectl create configmap test-cm2 \
> --from-file=txt.yaml \
> --from-file=txt1.yaml
configmap/test-cm2 created
查看内容通过-oymal查看或者describe cm查看
2.1.1.3 从目录创建
如上一种方式没有太大差别,只是--from-file
后面的参数是目录,而不是文件。
命令如下:
kubectl create configmap pkslow-directory --from-file=./
2.1.1.4 从环境变量配置文件创建
这种方式如之前的从文件创建很不一样。它的(key, value)
不是(文件名,文件内容)
,而是文件中一个个的配置。
配置文件txt.env内容如下:
PKSLOW_NAME=wangming
PKSLOW_AGE=18
PKSLOW_WEBSITE=www.baidu.com
创建命令如下:
[root@k8s-master01 2-21]# kubectl create cm test-env --from-env-file=txt.env
configmap/test-env created
查看内容如下:
[root@k8s-master01 2-21]# kubectl get cm test-env -oyaml
apiVersion: v1
data:
PKSLOW_AGE: "18"
PKSLOW_NAME: wangming
PKSLOW_WEBSITE: www.baidu.com
kind: ConfigMap
metadata:
creationTimestamp: "2024-02-21T07:12:42Z"
name: test-env
namespace: default
resourceVersion: "302510"
uid: 7611344b-37a1-4fc6-858e-770f2efdb6a4
2.1.1.5 通过yaml
文件创建
通过yaml
文件创建就很常规了,跟普通的kubernetes
资源创建没有什么区别。先准备yaml
文件如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: test-yaml
data:
PKSLOW_AGE: "18"
PKSLOW_NAME: wangming
PKSLOW_WEBSITE: www.baidu.com
application-uat.yaml: |-
server:
port: 8080
pkslow:
name: edge
age: 20
webSite: https://www.edge.com
application.yaml: |-
server:
port: 8080
pkslow:
name: Larry
age: 18
webSite: www.google.com
再通过以下文件创建:
[root@k8s-master01 2-21]# kubectl apply -f configmap.yaml
configmap/test-yaml created
2.1.2 Pod使用ConfigMap
在Pod
中使用ConfigMap
有以下四种方式:
- 在容器命令和参数内
- 容器的环境变量
- 在只读卷里面添加一个文件,让应用来读取
- 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap
其中第1种和第2种方式类似,只是启动命令添加环境变量,所以还是要把ConfigMap
映射为容器的环境变量。
第4种方式要访问API
,可以使用相关的库,如Spring Cloud Kubernetes
,这里不介绍,因为我不会。
所以我们主要讲解第2、3种方式。
2.1.2.1 Pod的环境变量映射
把ConfigMap
的值映射到环境变量,主要有两种方式,valueFrom
和envFrom
。
2.1.2.1.1 valueFrom一一映射
通过valueFrom
来配置环境变量,Pod
的环境变量名与ConfigMap
不必相同。
apiVersion: v1
kind: Pod
metadata:
name: env-value-from
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: wm_NAME
valueFrom:
configMapKeyRef:
name: test-yaml
key: PKSLOW_NAME
- name: wm_WEBSITE
valueFrom:
configMapKeyRef:
name: test-yaml
key: PKSLOW_WEBSITE
restartPolicy: Never
查看结果:
[root@k8s-master01 2-21]# kubectl logs -f env-value-from | grep wm_NAME
wm_NAME=wangming
也可以把application-uat.yaml
这种文件映射成环境变量,但因为文件内容可能是多行的,一般不会这样做。
2.1.2.1.2 envFrom全部映射
通过envFrom
会把ConfigMap
的所有键值对都映射到Pod
的环境变量中去。使用如下:
apiVersion: v1
kind: Pod
metadata:
name: cm-envfrom
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: test-yaml
restartPolicy: Never
查看环境变量如下:
[root@k8s-master01 2-21]# kubectl logs -f cm-envfrom
MY_NGINX_SERVICE_PORT=80
MY_NGINX_PORT=tcp://192.168.92.236:80
KUBERNETES_PORT=tcp://192.168.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=cm-envfrom
SHLVL=1
MY_NGINX_PORT_80_TCP_ADDR=192.168.92.236
HOME=/root
PKSLOW_WEBSITE=www.baidu.com
application.yaml=server:
port: 8080
pkslow:
name: Larry
age: 18
webSite: www.google.com
MY_NGINX_PORT_80_TCP_PORT=80
MY_NGINX_PORT_80_TCP_PROTO=tcp
MY_NGINX_PORT_80_TCP=tcp://192.168.92.236:80
KUBERNETES_PORT_443_TCP_ADDR=192.168.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
MY_NGINX_SERVICE_PORT_HTTP=80
application-uat.yaml=server:
port: 8080
pkslow:
name: edge
age: 20
webSite: https://www.edge.com
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://192.168.0.1:443
PKSLOW_AGE=18
MY_NGINX_SERVICE_HOST=192.168.92.236
KUBERNETES_SERVICE_HOST=192.168.0.1
PWD=/
PKSLOW_NAME=wangming
显然看起来这种方式更简便,不用每个环境变量都配一遍,但它可能会带来脏数据,就看怎么使用了
2.1.3 加载文件
2.1.3.1 通过volume加载
可以通过volume
的方式把ConfigMap
加载进Pod
,如下:
apiVersion: v1
kind: Pod
metadata:
name: mount-volume
spec:
volumes:
- name: config-volume
configMap:
name: test-yaml
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "sleep 1000000" ]
imagePullPolicy: IfNotPresent
volumeMounts:
- name: config-volume
mountPath: /data/config
restartPolicy: Never
查看结果:
[root@k8s-master01 2-21]# kubectl exec -it mount-volume -- cat /data/config/PKSLOW_AGE
18
如果只想要ConfigMap
的部分内容,并自定义文件名,可通过items
来配置,如下:
apiVersion: v1
kind: Pod
metadata:
name: mount-volume
spec:
volumes:
- name: config-volume
configMap:
name: test-yaml
items:
- key: application.yaml
path: app.yaml
- key: application-uat.yaml
path: uat.yaml
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "sleep 1000000" ]
imagePullPolicy: IfNotPresent
volumeMounts:
- name: config-volume
mountPath: /data/config
restartPolicy: Never
2.1.3.2 通过subPath加载
通过配置subPath
字段,把文件一个一个加载到Pod
中去。
apiVersion: v1
kind: Pod
metadata:
name: pkslow-mount-subpath
spec:
volumes:
- name: config-volume
configMap:
name: pkslow-yaml
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "sleep 1000000" ]
imagePullPolicy: IfNotPresent
volumeMounts:
- name: config-volume
mountPath: /data/config/dev.yaml
subPath: application.yaml
- name: config-volume
mountPath: /data/config/uat.yaml
subPath: application-uat.yaml
restartPolicy: Never
查看内容如下:
$ kubectl exec -it pkslow-mount-subpath -- /bin/sh
/ # cd /data/config/
/data/config # ls -lrt
total 8
-rw-r--r-- 1 root root 89 Feb 21 17:31 uat.yaml
-rw-r--r-- 1 root root 78 Feb 21 17:31 dev.yaml
/data/config # cat dev.yaml
server:
port: 8080
pkslow:
name: Larry
age: 18
webSite: www.pkslow.com
/data/config # cat uat.yaml
server:
port: 8080
pkslow:
name: LarryDpk
age: 20
webSite: https://www.pkslow.com
2.1.4 不可变的ConfigMap
可以禁止修改ConfigMap
,好处有:
- 保护应用,使之免受意外(不想要的)更新所带来的负面影响。
- 通过大幅降低对 kube-apiserver 的压力提升集群性能,这是因为系统会关闭 对已标记为不可变更的 ConfigMap 的监视操作。
此功能特性由 ImmutableEphemeralVolumes
特性门控 来控制。你可以通过将 immutable
字段设置为 true
创建不可变更的 ConfigMap。 例如:
apiVersion: v1
kind: ConfigMap
metadata:
...
data:
...
immutable: true
一旦某 ConfigMap 被标记为不可变更,则 无法 逆转这一变化,也无法更改 data
或 binaryData
字段的内容。你只能删除并重建 ConfigMap。 因为现有的 Pod 会维护一个对已删除的 ConfigMap 的挂载点,建议重新创建 这些 Pods。
3 总结
Secret
与ConfigMap
的创建与使用也是类似的,不再详细介绍了。