Secret 是用来保存密码、token、密钥等敏感数据的 k8s 资源,这类数据虽然也可以存放在 Pod 或者镜像中,但是放在 Secret 中是为了更方便的控制如何使用数据,并减少暴露的风险。
kubernetes.io/service-account-token:由 Kubernetes 自动创建,用来访问 APIServer 的 Secret,Pod 会默认使用这个 Secret 与 APIServer 通信, 并且会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中;
Opaque :base64 编码格式的 Secret,用来存储用户自定义的密码、密钥等,默认的 Secret 类型;
kubernetes.io/dockerconfigjson :用来存储私有 docker registry 的认证信息。
Pod 需要先引用才能使用某个 secret,Pod 有 3 种方式来使用 secret:
作为挂载到一个或多个容器上的卷 中的文件。
作为容器的环境变量。
由 kubelet 在为 Pod 拉取镜像时使用。
应用场景:凭据
https://kubernetes.io/docs/concepts/configuration/secret/
echo -n 'zhangsan' > username.txt
echo -n 'abc123' > password.txtkubectl create secret generic mysecret --from-file=username.txt --from-file=password.txtkubectl get secrets#get或describe指令都不会展示secret的实际内容,这是出于对数据的保护的考虑
kubectl describe secret mysecret
echo -n zhangsan | base64
emhhbmdzYW4=echo -n abc123 | base64
YWJjMTIzvim secret.yamlapiVersion: v1
kind: Secret
metadata:name: mysecret1
type: Opaque
data:username: emhhbmdzYW4=password: YWJjMTIzkubectl create -f secret.yaml kubectl get secrets
kubectl get secret mysecret1 -o yamlapiVersion: v1
data:password: YWJjMTIzusername: emhhbmdzYW4=
kind: Secret
metadata:creationTimestamp: "2023-03-02T07:15:01Z"managedFields:- apiVersion: v1fieldsType: FieldsV1fieldsV1:f:data:.: {}f:password: {}f:username: {}f:type: {}manager: kubectl-createoperation: Updatetime: "2023-03-02T07:15:01Z"name: mysecret1namespace: defaultresourceVersion: "50956"uid: e611fddd-7ca1-4e75-8d3d-99478ab58a83
type: Opaque
vim secret-test.yamlapiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: nginximage: nginxvolumeMounts:- name: secretsmountPath: "/etc/secrets"readOnly: truevolumes:- name: secretssecret:secretName: mysecretkubectl create -f secret-test.yamlkubectl get podskubectl exec -it seret-test bash
vim secret-test1.yamlapiVersion: v1
kind: Pod
metadata:name: mypod1
spec:containers:- name: nginximage: nginxenv:- name: TEST_USERvalueFrom:secretKeyRef:name: mysecret1key: username- name: TEST_PASSWORDvalueFrom:secretKeyRef:name: mysecret1key: passwordkubectl apply -f secret-test1.yaml kubectl get podskubectl exec -it mypod bash
与Secret类似,区别在于ConfigMap保存的是不需要加密配置的信息。
ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。
应用场景:应用配置
mkdir /opt/configmap/vim /opt/configmap/game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30vim /opt/configmap/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNicels /opt/configmap/
game.properties
ui.propertieskubectl create configmap game-config --from-file=/opt/configmap/
#--from-file 指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容kubectl get cm
kubectl get cm game-config -o yamlapiVersion: v1
data:game.properties: |+enemies=alienslives=3enemies.cheat=trueenemies.cheat.level=noGoodRottensecret.code.passphrase=UUDDLRLRBABASsecret.code.allowed=truesecret.code.lives=30ui.properties: |+color.good=purplecolor.bad=yellowallow.textmode=truehow.nice.to.look=fairlyNicekind: ConfigMap
metadata:creationTimestamp: "2023-03-02T10:31:37Z"managedFields:- apiVersion: v1fieldsType: FieldsV1fieldsV1:f:data:.: {}f:game.properties: {}f:ui.properties: {}manager: kubectl-createoperation: Updatetime: "2023-03-02T10:31:37Z"name: game-confignamespace: defaultresourceVersion: "65700"uid: 33ac77c9-8f0f-4d5e-a14d-763ac6e2be04
只要指定为一个文件就可以从单个文件中创建 ConfigMap
--from-file 这个参数可以使用多次,即可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的
kubectl create configmap game-config-2 --from-file=/opt/configmap/game.properties --from-file=/opt/configmap/ui.propertieskubectl get configmaps game-config-2 -o yamlkubectl describe cm game-config-2
使用文字值创建,利用 --from-literal 参数传递配置信息,该参数可以使用多次,格式如下
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=goodkubectl get configmaps special-config -o yamlapiVersion: v1
data:special.how: very #key-value结构special.type: good
kind: ConfigMap
metadata:creationTimestamp: "2023-03-02T10:41:48Z"managedFields:- apiVersion: v1fieldsType: FieldsV1fieldsV1:f:data:.: {}f:special.how: {}f:special.type: {}manager: kubectl-createoperation: Updatetime: "2023-03-02T10:41:48Z"name: special-confignamespace: defaultresourceVersion: "66554"uid: 56e431fa-4833-458b-9a35-ab19f7dd3f77
kubectl delete cm --allkubectl delete pod --all
vim env.yamlapiVersion: v1
kind: ConfigMap
metadata:name: special-confignamespace: default
data:special.how: veryspecial.type: good
---
apiVersion: v1
kind: ConfigMap
metadata:name: env-confignamespace: default
data:log_level: INFOkubectl create -f env.yaml kubectl get cm
Pod的创建
vim test-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:containers:- name: busyboximage: busybox:1.28.4command: [ "/bin/sh", "-c", "env" ]env:- name: SPECIAL_HOW_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.how- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:- configMapRef:name: env-configrestartPolicy: Neverkubectl create -f test-pod.yamlkubectl get podskubectl logs pod-testKUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=test-pod
SHLVL=1
SPECIAL_HOW_KEY=very #赋值变量 SPECIAL_HOW_KEY 的值为 special-config 的
NGINX_PORT_80_TCP=tcp://10.105.252.176:80
SPECIAL_TYPE_KEY=good #赋值变量 SPECIAL_TYPE_KEY 的值为 special-config 的
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_SERVICE_HOST=10.105.252.176
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
NGINX_PORT=tcp://10.105.252.176:80
NGINX_SERVICE_PORT=80
log_level=INFO #引入 env-config 的变量 log_level: INFO
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
NGINX_PORT_80_TCP_ADDR=10.105.252.176
NGINX_PORT_80_TCP_PORT=80
NGINX_PORT_80_TCP_PROTO=tcp
vim test-pod2.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod2
spec:containers:- name: busyboximage: busybox:1.28.4command: - /bin/sh- -c- echo"$(SPECIAL_HOW_KEY)$(SPECIAL_TYPE_KEY)"env:- name: SPECIAL_HOW_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.how- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:- configMapRef:name: env-configrestartPolicy: Neverkubectl create -f test-pod2.yamlkubectl get podskubectl logs test-pod2
在数据卷里面使用 ConfigMap,就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容
vim test-pod3.yamlapiVersion: v1
kind: Pod
metadata:name: test-pod3
spec:containers:- name: busyboximage: busybox:1.28.4command: [ "/bin/sh", "-c", "sleep 36000" ]volumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: special-configrestartPolicy: Neverkubectl create -f test-pod3.yaml kubectl get podskubectl exec -it test-pod3 sh# cd /etc/config/# ls
special.how special.type# vi special.how # vi special.type
vim test-pod4.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: log-confignamespace: default
data:log_level: INFO
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:name: my-nginx
spec:replicas: 1template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80volumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: log-config
kubectl apply -f test-pod4.yamlkubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-76b6489f44-6dwxh 1/1 Running 0 46skubectl exec -it my-nginx-76b6489f44-6dwxh -- cat /etc/config/log_level
INFOkubectl edit configmap log-config
apiVersion: v1
data:log_level: DEBUG #INFO 修改成 DEBUG
kind: ConfigMap
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"v1","data":{"log_level":"DEBUG"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"log-config","namespace":"default"}} #INFO 修改成 DEBUGcreationTimestamp: 2021-05-25T07:59:18Zname: log-confignamespace: defaultresourceVersion: "93616"selfLink: /api/v1/namespaces/default/configmaps/log-configuid: 1b8115de-bd2f-11eb-acba-000c29d88bba#等大概10秒左右,使用该 ConfigMap 挂载的 Volume 中的数据同步更新
kubectl exec -it my-nginx-76b6489f44-6dwxh -- cat /etc/config/log_level
DEBUG#ConfigMap 更新后滚动更新 Pod
更新 ConfigMap 目前并不会触发相关 Pod 的滚动更新,可以通过在 .spec.template.metadata.annotations 中添加 version/config ,每次通过修改 version/config 来触发滚动更新kubectl patch deployment my-nginx --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20210525" }}}}}'kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-665dd4dc8c-j4k9t 0/1 ContainerCreating 0 4s
my-nginx-76b6489f44-6dwxh 0/1 Terminating 0 10mkubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-665dd4dc8c-j4k9t 1/1 Running 0 74s
PS:更新 ConfigMap 后:
使用该 ConfigMap 挂载的 Env 不会同步更新。
使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新。