1. Secret
Secret is a k8s resource used to store sensitive data such as passwords, tokens, keys, etc. Although this type of data can also be stored in Pods or mirrors, it is placed in Secret to more conveniently control how the data is used and reduce exposure. risk.
1. There are three types of Secrets
- kubernetes.io/service-account-token: automatically created by Kubernetes and used to access the APIServer's Secret. The Pod will use this Secret to communicate with the APIServer by default and will be automatically mounted to the Pod's /run/secrets/kubernetes.io/serviceaccount in the directory;
- Opaque: Secret in base64 encoding format, used to store user-defined passwords, keys, etc., the default Secret type;
- kubernetes.io/dockerconfigjson: used to store authentication information for private docker registry.
A Pod needs to reference a secret before it can use it. There are three ways for a Pod to use a secret:
- As a file mounted to a volume on one or more containers.
- As environment variables of the container.
- Used by kubelet when pulling images for Pods.
Application scenario: Credentials
https://kubernetes.io/docs/concepts/configuration/secret/
2. Create a secret instance
2.1 Use kubectl create secret command to create Secret
echo -n 'zhangsan' > username.txt
echo -n 'abc123' > password.txt
kubectl create secret generic mysecret --from-file=username.txt --from-file=password.txt
kubectl get secrets
#get或describe指令都不会展示secret的实际内容,这是出于对数据的保护的考虑
kubectl describe secret mysecret
2.2 Encode the content with base64 and create a secret
echo -n zhangsan | base64
emhhbmdzYW4=
echo -n abc123 | base64
YWJjMTIz
vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret1
type: Opaque
data:
username: emhhbmdzYW4=
password: YWJjMTIz
kubectl create -f secret.yaml
kubectl get secrets
kubectl get secret mysecret1 -o yaml
apiVersion: v1
data:
password: YWJjMTIz
username: emhhbmdzYW4=
kind: Secret
metadata:
creationTimestamp: "2023-03-02T07:15:01Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:password: {}
f:username: {}
f:type: {}
manager: kubectl-create
operation: Update
time: "2023-03-02T07:15:01Z"
name: mysecret1
namespace: default
resourceVersion: "50956"
uid: e611fddd-7ca1-4e75-8d3d-99478ab58a83
type: Opaque
3. How to use
3.1 Mount Secret to Volume and mount it to a directory of Pod in the form of Volume
vim secret-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: secrets
mountPath: "/etc/secrets"
readOnly: true
volumes:
- name: secrets
secret:
secretName: mysecret
kubectl create -f secret-test.yaml
kubectl get pods
kubectl exec -it seret-test bash
3.2 Export secret to environment variables
vim secret-test1.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod1
spec:
containers:
- name: nginx
image: nginx
env:
- name: TEST_USER
valueFrom:
secretKeyRef:
name: mysecret1
key: username
- name: TEST_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret1
key: password
kubectl apply -f secret-test1.yaml
kubectl get pods
kubectl exec -it mypod bash
2. ConfigMap
与Secret类似,区别在于ConfigMap保存的是不需要加密配置的信息。
ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。
应用场景:应用配置
1、创建 ConfigMap
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=30
vim /opt/configmap/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
ls /opt/configmap/
game.properties
ui.properties
kubectl create configmap game-config --from-file=/opt/configmap/
#--from-file 指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容
kubectl get cm
kubectl get cm game-config -o yaml
apiVersion: v1
data:
game.properties: |+
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties: |+
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
creationTimestamp: "2023-03-02T10:31:37Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:game.properties: {}
f:ui.properties: {}
manager: kubectl-create
operation: Update
time: "2023-03-02T10:31:37Z"
name: game-config
namespace: default
resourceVersion: "65700"
uid: 33ac77c9-8f0f-4d5e-a14d-763ac6e2be04
1.1 使用文件创建
只要指定为一个文件就可以从单个文件中创建 ConfigMap
--from-file 这个参数可以使用多次,即可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的
kubectl create configmap game-config-2 --from-file=/opt/configmap/game.properties --from-file=/opt/configmap/ui.properties
kubectl get configmaps game-config-2 -o yaml
kubectl describe cm game-config-2
1.2 使用字面值创建
使用文字值创建,利用 --from-literal 参数传递配置信息,该参数可以使用多次,格式如下
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=good
kubectl get configmaps special-config -o yaml
apiVersion: v1
data:
special.how: very #key-value结构
special.type: good
kind: ConfigMap
metadata:
creationTimestamp: "2023-03-02T10:41:48Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:special.how: {}
f:special.type: {}
manager: kubectl-create
operation: Update
time: "2023-03-02T10:41:48Z"
name: special-config
namespace: default
resourceVersion: "66554"
uid: 56e431fa-4833-458b-9a35-ab19f7dd3f77
kubectl delete cm --all
kubectl delete pod --all
2、Pod 中使用 ConfigMap
2.1 使用 ConfigMap 来替代环境变量
vim env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
special.type: good
---
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: default
data:
log_level: INFO
kubectl create -f env.yaml
kubectl get cm
Pod的创建
vim test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: busybox
image: busybox:1.28.4
command: [ "/bin/sh", "-c", "env" ]
env:
- name: SPECIAL_HOW_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.type
envFrom:
- configMapRef:
name: env-config
restartPolicy: Never
kubectl create -f test-pod.yaml
kubectl get pods
kubectl logs pod-test
KUBERNETES_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
2.2 用 ConfigMap 设置命令行参数
vim test-pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod2
spec:
containers:
- name: busybox
image: busybox:1.28.4
command:
- /bin/sh
- -c
- echo "$(SPECIAL_HOW_KEY) $(SPECIAL_TYPE_KEY)"
env:
- name: SPECIAL_HOW_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.type
envFrom:
- configMapRef:
name: env-config
restartPolicy: Never
kubectl create -f test-pod2.yaml
kubectl get pods
kubectl logs test-pod2
2.3 通过数据卷插件使用ConfigMap
在数据卷里面使用 ConfigMap,就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容
vim test-pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod3
spec:
containers:
- name: busybox
image: busybox:1.28.4
command: [ "/bin/sh", "-c", "sleep 36000" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
restartPolicy: Never
kubectl create -f test-pod3.yaml
kubectl get pods
kubectl exec -it test-pod3 sh
# cd /etc/config/
# ls
special.how special.type
# vi special.how
# vi special.type
3、ConfigMap 的热更新
vim test-pod4.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: log-config
namespace: default
data:
log_level: INFO
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: log-config
kubectl apply -f test-pod4.yaml
kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-76b6489f44-6dwxh 1/1 Running 0 46s
kubectl exec -it my-nginx-76b6489f44-6dwxh -- cat /etc/config/log_level
INFO
kubectl 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 修改成 DEBUG
creationTimestamp: 2021-05-25T07:59:18Z
name: log-config
namespace: default
resourceVersion: "93616"
selfLink: /api/v1/namespaces/default/configmaps/log-config
uid: 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 10m
kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-665dd4dc8c-j4k9t 1/1 Running 0 74s
PS:更新 ConfigMap 后:
- 使用该 ConfigMap 挂载的 Env 不会同步更新。
- 使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新。