ConfigMap和Secret
ConfigMap的概念
用来存储配置文件的 kubernetes 资源对象,配置内容都存储在 etcd 中
ConfigMap创建方式
- 通过直接在命令行中指定 configmap 参数创建,即--from-literal
root@master:/home/guanwu/k8s/cm# kubectl create configmap test-config1 --from-literal=db.host=10.5.10.116 --from-literal=db.port='3306'
configmap/test-config1 created
root@master:/home/guanwu/k8s/cm# k get cm test-config1
NAME DATA AGE
test-config1 2 9s
root@master:/home/guanwu/k8s/cm# k describe cm test-config1
Name: test-config1
Namespace: test
Labels: <none>
Annotations: <none>
Data
====
db.host:
----
10.5.10.116
db.port:
----
3306
BinaryData
====
Events: <none>
- 通过指定文件创建,即将一个配置文件创建为一个 ConfigMap --from-file=<文件>
root@master:/home/guanwu/k8s/cm# cat test-config2
db.host=10.5.10.116
db.port=3306
root@master:/home/guanwu/k8s/cm# kubectl create configmap test-config2 --from-env- file=./test-config2
configmap/test-config2 created
root@master:/home/guanwu/k8s/cm# k get cm test-config2 -o yaml
apiVersion: v1
data:
db.host: 10.5.10.116
db.port: "3306"
kind: ConfigMap
metadata:
creationTimestamp: "2024-01-10T14:42:55Z"
name: test-config2
namespace: test
resourceVersion: "349424"
uid: d0451b58-6339-4bb1-9b21-9a22a2899a81
- 通过指定目录创建,即将一个目录下的所有配置文件创建为一个 ConfigMap,--from-file=< 目录>
使用find命令查看test目录下的两个子文件
root@master:/home/guanwu/k8s/cm# find test -type f -exec bash -c 'basename $0;cat $0;echo "==="' {} \;
sub-config1
sub1.host=10.2.2.2
sub1.port=8080
===
sub-config2
sub2.host=10.2.2.3
sub1.port=8081
===
root@master:/home/guanwu/k8s/cm# kubectl create configmap test-config3 --from-file=./test
configmap/test-config3 created
可以看到name为test-config3的cm已经创建,test目录下的sub-config1和sub-config2都已经创建,如下所示:
root@master:/home/guanwu/k8s/cm# kubectl get cm test-config3 -o yaml
apiVersion: v1
data:
sub-config1: |
sub1.host=10.2.2.2
sub1.port=8080
sub-config2: |
sub2.host=10.2.2.3
sub1.port=8081
kind: ConfigMap
metadata:
creationTimestamp: "2024-01-10T14:52:16Z"
name: test-config3
namespace: test
resourceVersion: "350571"
uid: 2167537c-126f-4b1f-b9ad-ffbc46c7dced
- 事先写好标准的 configmap 的 yaml 文件,然后 kubectl create -f 创建
root@master:/home/guanwu/k8s/cm# cat test-config4.yaml
apiVersion: v1
data:
sub-config3: |
sub1.host=10.2.2.2
sub1.port=8080
sub-config4: |
sub2.host=10.2.2.3
sub1.port=8081
kind: ConfigMap
metadata:
name: test-config4
namespace: test
root@master:/home/guanwu/k8s/cm# k apply -f test-config4.yaml
configmap/test-config4 created
root@master:/home/guanwu/k8s/cm# k get cm test-config4 -o yaml
apiVersion: v1
data:
sub-config3: |
sub1.host=10.2.2.2
sub1.port=8080
sub-config4: |
sub2.host=10.2.2.3
sub1.port=8081
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"sub-config3":"sub1.host=10.2.2.2\nsub1.port=8080\n","sub-config4":"sub2.host=10.2.2.3\nsub1.port=8081\n"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"test-config4","namespace":"test"}}
creationTimestamp: "2024-01-10T14:59:23Z"
name: test-config4
namespace: test
resourceVersion: "351437"
uid: b1c4d73d-c1a5-472e-bc05-aed2fff51195
root@master:/home/guanwu/k8s/cm#
ConfigMap的主要使用形式
1. 容器的环境变量和启动命令使用
创建configmap,可以看到configmap定义了两个变量SPECIAL_LEVEL和SPECIAL_TYPE,value分别为T0和T1
root@master:/home/guanwu/k8s/configmap# k create cm special-config --from-literal=SPECIAL_LEVEL=T0 --from-literal=SPECIAL_TYPE=T1
configmap/special-config created
root@master:/home/guanwu/k8s/configmap# k get cm special-config -o yaml
apiVersion: v1
data:
SPECIAL_LEVEL: T0
SPECIAL_TYPE: T1
kind: ConfigMap
metadata:
creationTimestamp: "2024-01-11T13:42:29Z"
name: special-config
namespace: test
resourceVersion: "360475"
uid: 68b46324-ea71-46a2-99a3-467e66eab5d6
创建pod,可以看到,执行kubectl logs dapi-test-pod命令时,输出的两个值是configmap定义的值
root@master:/home/guanwu/k8s/configmap# cat busybox.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: SPECIAL_LEVEL
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: SPECIAL_TYPE
restartPolicy: Never
root@master:/home/guanwu/k8s/configmap# k apply -f busybox.yaml
pod/dapi-test-pod created
root@master:/home/guanwu/k8s/configmap# k logs dapi-test-pod
T0 T1
root@master:/home/guanwu/k8s/configmap#
2. Volume形式使用 创建cm
root@master:/home/guanwu/k8s/configmap# cat game-demo-config.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
root@master:/home/guanwu/k8s/configmap# k apply -f game-demo-config.yaml
configmap/game-demo unchanged
在容器中使用
root@master:/home/guanwu/k8s/configmap# cat configure-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: busybox
command: ["sleep", "3600"]
env:
# 定义环境变量
- name: PLAYER_INITIAL_LIVES # 请注意这里和 ConfigMap 中的键名是不一样的
valueFrom:
configMapKeyRef:
name: game-demo # 这个值来自 ConfigMap
key: player_initial_lives # 需要取值的键
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: game-demo
key: ui_properties_file_name
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# 你可以在 Pod 级别设置卷,然后将其挂载到 Pod 内的容器中
- name: config
configMap:
# 提供你想要挂载的 ConfigMap 的名字
name: game-demo
# 来自 ConfigMap 的一组键,将被创建为文件
items:
- key: "game.properties"
path: "game.properties"
- key: "user-interface.properties"
path: "user-interface.properties"
创建容器并进入容器,可以看到容器/config目录下创建了两个配置文件,并打印环境变量
root@master:/home/guanwu/k8s/configmap# k apply -f configure-pod.yaml
pod/configmap-demo-pod created
root@master:/home/guanwu/k8s/configmap# k exec -it configmap-demo-pod -- sh
/ #
/ # ls /config
game.properties user-interface.properties
/config # cat /config/game.properties
enemy.types=aliens,monsters
player.maximum-lives=5
/config # cat /config/user-interface.properties
color.good=purple
color.bad=yellow
allow.textmode=true
/config # echo $PLAYER_INITIAL_LIVES
3
/config # echo $UI_PROPERTIES_FILE_NAME
user-interface.properties
/config #
如果纯粹将configMap当文件使用也是可以的,game-demo下的每个key都会创建相应的文件
root@master:/home/guanwu/k8s/configmap# cat configure-pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod-2
spec:
containers:
- name: demo
image: busybox
command: ["sleep", "3600"]
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# 你可以在 Pod 级别设置卷,然后将其挂载到 Pod 内的容器中
- name: config
configMap:
# 提供你想要挂载的 ConfigMap 的名字
name: game-demo
root@master:/home/guanwu/k8s/configmap# k apply -f configure-pod2.yaml
pod/configmap-demo-pod-2 created
root@master:/home/guanwu/k8s/configmap# k exec -it configmap-demo-pod-2 -- sh
/ #
/ # ls /config
game.properties player_initial_lives ui_properties_file_name user-interface.properties
Secret类型
在k8s官方文档找到Secret的说明:
Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 Pod 规约中或者镜像中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。
由于创建 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防措施, 例如避免将敏感数据写入非易失性存储。
Secret 类似于 ConfigMap 但专门用于保存机密数据。
Secret的几种类型
| 内置类型 | 用法 |
|---|---|
Opaque | 用户定义的任意数据 |
kubernetes.io/service-account-token | 服务账号令牌 |
kubernetes.io/dockercfg | ~/.dockercfg 文件的序列化形式 |
kubernetes.io/dockerconfigjson | ~/.docker/config.json 文件的序列化形式 |
kubernetes.io/basic-auth | 用于基本身份认证的凭据 |
kubernetes.io/ssh-auth | 用于 SSH 身份认证的凭据 |
kubernetes.io/tls | 用于 TLS 客户端或者服务器端的数据 |
bootstrap.kubernetes.io/token | 启动引导令牌数据 |
Secret创建方式
- kubectl命令创建, 可以看到密码被base64编码了
root@master:/home/guanwu/k8s/configmap# kubectl create secret generic test --from-literal=username=admin --from-literal=passw
ord=1f2d1e2e67df
secret/test created
root@master:/home/guanwu/k8s/configmap# k get secret test -o yaml
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2024-01-11T14:30:06Z"
name: test
namespace: test
resourceVersion: "367766"
uid: dbaf81b2-a482-4e02-972f-4ec9a91ea02b
type: Opaque
root@master:/home/guanwu/k8s/configmap# echo 'MWYyZDFlMmU2N2Rm' | base64 -d | tee && echo
1f2d1e2e67df
- yaml文件创建
root@master:/home/guanwu/k8s/configmap# echo -n 'admin' | base64
YWRtaW4=
root@master:/home/guanwu/k8s/configmap# echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
root@master:/home/guanwu/k8s/configmap# cat mysecret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
root@master:/home/guanwu/k8s/configmap# k apply -f mysecret.yaml
secret/mysecret created
root@master:/home/guanwu/k8s/configmap# k get secret
NAME TYPE DATA AGE
mysecret Opaque 2 93s
test Opaque 2 10m
tls-secret kubernetes.io/tls 2 22d
Secret 使用方式
- 以环境变量方式 ,创建Pod
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "echo ${SECRET_USERNAME}:${SECRET_PASSWORD}" ]
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
验证,可以看到命令输出的时username和password的值
root@master:/home/guanwu/k8s/configmap# k apply -f busybox-secret.yaml
pod/secret-test-pod created
root@master:/home/guanwu/k8s/configmap# k get pod secret-test-pod
NAME READY STATUS RESTARTS AGE
secret-test-pod 0/1 Completed 0 36s
root@master:/home/guanwu/k8s/configmap# k logs secret-test-pod
admin:1f2d1e2e67df
- 以 Volume 方式 创建secret
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBw
password: Mzk1MjgkdmRnN0pi
创建Pod
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBw
password: Mzk1MjgkdmRnN0pi
创建pod
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx:1.9
volumeMounts:
- name: secret-volume
mountPath: /etc/secret-volume
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: test-secret
验证,进入容器后,可以看到/etc/secret-volume目录下多了两个文件,分别是password和username
root@master:/home/guanwu/k8s/configmap# k apply -f secret-pod.yaml
pod/secret-test-pod configured
root@master:/home/guanwu/k8s/configmap# k get pod secret-test-pod
NAME READY STATUS RESTARTS AGE
secret-test-pod 1/1 Running 0 2m5s
root@master:/home/guanwu/k8s/configmap# k exec -it secret-test-pod -- sh
# ls /etc/secret-volume
password username
# cat /etc/secret-volume/password
39528$vdg7Jb#
# cat /etc/secret-volume/password && echo
39528$vdg7Jb
# cat /etc/secret-volume/username && echo
my-app
#
Secret使用场景
作为容器环境变量
可以参考Secret的使用方式
带 SSH 密钥的 Pod
root@master:/home/guanwu/k8s/configmap# kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/root/.ssh/id
_rsa --from-file=ssh-publickey=/root/.ssh/id_rsa.pub
secret/ssh-key-secret created
root@master:/home/guanwu/k8s/configmap# k get secret
NAME TYPE DATA AGE
mysecret Opaque 2 34m
ssh-key-secret Opaque 2 7s
test Opaque 2 43m
test-secret Opaque 2 10m
tls-secret kubernetes.io/tls 2 22d
root@master:/home/guanwu/k8s/configmap# k get secret ssh-key-secret -o yaml
apiVersion: v1
data:
ssh-privatekey: LS0tLS1CRUdJTiBPUEVOU1NIIFB... #省略
ssh-publickey: c3NoLXJzYSBBQUFBQjNOe... # 省略
kind: Secret
metadata:
creationTimestamp: "2024-01-11T15:13:31Z"
name: ssh-key-secret
namespace: test
resourceVersion: "374410"
uid: 54fae324-7cee-4864-b2bb-fe7e3acd4900
type: Opaque
创建pod
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: nginx:1.9
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
可以看到,/etc/secret-volume目录下有ssh所需要的两个文件
root@master:/home/guanwu/k8s/configmap# k apply -f secret-test-pod.yaml
pod/secret-test-pod created
root@master:/home/guanwu/k8s/configmap# k get pod secret-test-pod
NAME READY STATUS RESTARTS AGE
secret-test-pod 1/1 Running 0 49s
root@master:/home/guanwu/k8s/configmap# k exec -it secret-test-pod -- sh
# ls /etc/secret-volume
ssh-privatekey ssh-publickey
#
使用 Secret 为 Pod 提供生产环境或测试环境的凭据
你可以创建一个带有 secretGenerator 字段的 kustomization.yaml 文件或者运行 kubectl create secret 来创建 Secret。
分别为生产和测试创建secret
生产使用
kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
测试使用
kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
创建
root@master:/home/guanwu/k8s/configmap# kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
secret/prod-db-secret created
root@master:/home/guanwu/k8s/configmap# kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
secret/test-db-secret created
root@master:/home/guanwu/k8s/configmap# k get secret
NAME TYPE DATA AGE
mysecret Opaque 2 47m
prod-db-secret Opaque 2 16s
ssh-key-secret Opaque 2 13m
test Opaque 2 56m
test-db-secret Opaque 2 7s
test-secret Opaque 2 23m
tls-secret kubernetes.io/tls 2 22d
root@master:/home/guanwu/k8s/configmap#
cat <<EOF > pod.yaml
apiVersion: v1
kind: List
items:
- kind: Pod
apiVersion: v1
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: prod-db-secret
containers:
- name: db-client-container
image: nginx:1.9
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
- kind: Pod
apiVersion: v1
metadata:
name: test-db-client-pod
labels:
name: test-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: test-db-secret
containers:
- name: db-client-container
image: nginx:1.9
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
EOF
执行创建生产和测试Pod命令
root@master:/home/guanwu/k8s/configmap# k apply -f pod.yaml
pod/prod-db-client-pod created
pod/test-db-client-pod created
验证生成的pod是否成功挂载secret
root@master:/home/guanwu/k8s/configmap# pods=$(k get pods | grep db-client | awk -F ' ' ' {print $1}')
root@master:/home/guanwu/k8s/configmap# for pod in ${pods[@]}; do echo $pod; done
prod-db-client-pod
test-db-client-pod
root@master:/home/guanwu/k8s/configmap# k apply -f pod.yaml
pod/prod-db-client-pod created
pod/test-db-client-pod created
iluvtestsroot@master:/home/guanwu/k8s/configmap# for pod in ${pods[@]}; do echo $pod; kubectl exec -t $pod -- bash -c "ls /etc/secret-volume; cat /etc/secret-volume/username; cat /etc/secret-volume/password" && echo; done
prod-db-client-pod
password
username
produserY4nys7f11
test-db-client-pod
password
username
testuseriluvtests
root@master:/home/guanwu/k8s/configmap#
## 参考
https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod