configmap,Secret
ConfigMap
ConfigMap概述
ConfigMap 用于保存非机密性的配置,通常用来管理应用的配置文件或者环境变量,数据可以用 key/value 键值对的形式保存,也可通过文件的形式保存。
ConfigMap创建方法
命令行创建
直接在命令行中指定 configmap 参数创建,通过--from-literal 指定参数
[root@master config]# kubectl create configmap nginx-config --from-literal=nginx_prot=80 --from-literal=path=/etc/nginx/html
configmap/nginx-config created
查看ConfigMap
[root@master config]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 29d
nginx-config 2 118s
[root@master config]# kubectl describe cm nginx-config
Name: nginx-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
nginx_prot:
----
80
path:
----
/etc/nginx/html
Events: <none>
通过文件/目录创建
通过指定文件创建一个 configmap,--from-env-file=<文件>
[root@master config]# cat mysql.txt
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
[root@master config]# kubectl create configmap mysql-config --from-env-file=mysql.txt
configmap/mysql-config created
查看ConfigMap
[root@master config]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 29d
mysql-config 2 6s
nginx-config 2 7m50s
[root@master config]# kubectl describe cm mysql-config
Name: mysql-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
MYSQL_HOST:
----
127.0.0.1
MYSQL_PORT:
----
3306
Events: <none>
yaml创建
[root@master config]# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
namespace: default
data:
nginx.conf: |
server {
server_name www.nginx.com;
listen 80;
root /home/nginx/www/
}
[root@master config]# kubectl create -f configmap.yaml
configmap/nginx-conf created
查看ConfigMap
[root@master config]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 29d
mysql-config 2 9m40s
nginx-conf 1 5s
nginx-config 2 17m
[root@master config]# kubectl describe cm nginx-conf
Name: nginx-conf
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
nginx.conf:
----
server {
server_name www.nginx.com;
listen 80;
root /home/nginx/www/
}
Events: <none>
ConfigMap的使用
Pod的使用方式:
- 将ConfigMap中的数据设置为容器的环境变量
- 将ConfigMap中的数据设置为命令行参数
- 使用Volume将ConfigMap作为文件或目录挂载
- 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap
案例:
#创建pod,将configmap加到环境变量中
[root@master config]# cat pod-configmap.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
name: nginx-cm
namespace: default
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
env:
- name: nginx_prot #pod中变量名
valueFrom:
configMapKeyRef:
name: nginx-config #ConfigMap名称
key: nginx_prot #ConfigMap中key名称
- name: path
valueFrom:
configMapKeyRef:
name: nginx-config
key: path
[root@master config]# kubectl create -f pod-configmap.yaml
pod/nginx-cm created
#查看pod中的环境变量
[root@master config]# kubectl get pod nginx-cm
NAME READY STATUS RESTARTS AGE
nginx-cm 1/1 Running 0 11s
[root@master config]# kubectl exec nginx-cm env
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-cm
path=/etc/nginx/html
nginx_prot=80
NGINX_TEST1_SVC_PORT=tcp://10.104.50.60:80
NGINX_TEST1_SVC_PORT_80_TCP=tcp://10.104.50.60:80
NGINX_TEST2_SVC_PORT_80_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
NGINX_TEST1_SVC_SERVICE_HOST=10.104.50.60
NGINX_TEST1_SVC_SERVICE_PORT=80
NGINX_TEST1_SVC_SERVICE_PORT_HTTP=80
NGINX_TEST1_SVC_PORT_80_TCP_PORT=80
NGINX_TEST2_SVC_SERVICE_HOST=10.103.247.30
NGINX_TEST2_SVC_SERVICE_PORT=80
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
NGINX_TEST2_SVC_SERVICE_PORT_HTTP=80
NGINX_TEST2_SVC_PORT_80_TCP=tcp://10.103.247.30:80
NGINX_TEST2_SVC_PORT_80_TCP_PORT=80
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
NGINX_TEST1_SVC_PORT_80_TCP_PROTO=tcp
NGINX_TEST2_SVC_PORT=tcp://10.103.247.30:80
KUBERNETES_SERVICE_PORT=443
NGINX_TEST1_SVC_PORT_80_TCP_ADDR=10.104.50.60
NGINX_TEST2_SVC_PORT_80_TCP_ADDR=10.103.247.30
NGINX_VERSION=1.21.5
NJS_VERSION=0.7.1
PKG_RELEASE=1~bullseye
HOME=/root
ConfigMap挂载
注意:
整个configmap文件直接挂载到pod中,若configmap变化,pod会自动感知并拉取到pod内部,但是pod内的进程不会自动重启。
单文件挂载到空目录
[root@master config]# kubectl describe cm nginx-conf
Name: nginx-conf
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
nginx.conf:
----
server {
server_name www.nginx.com;
listen 80;
root /home/nginx/www/
}
Events: <none>
[root@master config]# cat pod-configmap-vol.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
name: nginx-cm-vol
namespace: default
spec:
volumes:
- configMap:
name: nginx-conf #configmap名称
name: config
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
volumeMounts:
- mountPath: "/etc/config" #挂载容器目录
name: config
[root@master config]# kubectl create -f pod-configmap-vol.yaml
pod/nginx-cm-vol created
[root@master config]# kubectl get pod nginx-cm-vol
NAME READY STATUS RESTARTS AGE
nginx-cm-vol 1/1 Running 0 10s
[root@master config]# kubectl exec nginx-cm-vol cat /etc/config/nginx.conf
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
server {
server_name www.nginx.com;
listen 80;
root /home/nginx/www/
}
多文件挂载
创建configmap
[root@master configmap]# cat config1.conf
user=test1
passwd=12345
[root@master configmap]# cat config2.conf
user=test2
passwd=4567
[root@master configmap]# kubectl create configmap test-conf --from-file=config1.conf --from-file=config2.conf
configmap/test-conf created
[root@master configmap]# kubectl get configmap test-conf
NAME DATA AGE
test-conf 2 13s
[root@master configmap]# kubectl describe configmap test-conf
Name: test-conf
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
config2.conf:
----
user=test2
passwd=4567
config1.conf:
----
user=test1
passwd=12345
Events: <none>
创建deployment挂载
[root@master configmap]# cat demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
namespace: default
spec:
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
volumes:
- configMap:
name: test-conf
name: config
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: "/tmp"
name: config
[root@master configmap]# kubectl create -f demo.yaml
deployment.apps/demo created
[root@master configmap]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
demo 1/1 1 1 8s
[root@master configmap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo-dcff5b456-l8v9j 1/1 Running 0 17s
[root@master configmap]# kubectl exec -it demo-dcff5b456-l8v9j -- /bin/bash
root@demo-dcff5b456-l8v9j:/# ls -l /tmp/
total 0
lrwxrwxrwx 1 root root 19 Jun 1 08:15 config1.conf -> ..data/config1.conf
lrwxrwxrwx 1 root root 19 Jun 1 08:15 config2.conf -> ..data/config2.conf
root@demo-dcff5b456-l8v9j:/# cat /tmp/config1.conf
user=test1
passwd=12345
root@demo-dcff5b456-l8v9j:/# cat /tmp/config2.conf
user=test2
passwd=4567
挂载子路径
[root@master configmap]# kubectl describe configmaps test-conf
Name: test-conf
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
config1.conf:
----
user=test1
passwd=12345
config2.conf:
----
user=test2
passwd=4567
Events: <none>
[root@master configmap]# cat demo2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo2
namespace: default
spec:
selector:
matchLabels:
app: demo2
template:
metadata:
labels:
app: demo2
spec:
volumes:
- name: config
configMap:
name: test-conf
items:
- key: config1.conf
path: config1
- key: config2.conf
path: config2
containers:
- name: nginx2
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: "/tmp/config1.conf"
name: config
subPath: config1
- mountPath: "/etc/config2.conf"
name: config
subPath: config2
[root@master configmap]# kubectl delete -f demo2.yaml
deployment.apps "demo2" deleted
[root@master configmap]# kubectl create -f demo2.yaml
deployment.apps/demo2 created
[root@master configmap]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
demo 1/1 1 1 8m11s
demo2 1/1 1 1 6s
[root@master configmap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo-dcff5b456-l8v9j 1/1 Running 0 8m15s
demo2-58998cc654-tlbr4 1/1 Running 0 10s
[root@master configmap]# kubectl exec -it demo2-58998cc654-tlbr4
error: you must specify at least one command for the container
[root@master configmap]# kubectl exec -it demo2-58998cc654-tlbr4 -- /bin/bash
root@demo2-58998cc654-tlbr4:/# ls -l /tmp/config1.conf
-rw-r--r-- 1 root root 24 Jun 1 08:23 /tmp/config1.conf
root@demo2-58998cc654-tlbr4:/# ls -l /etc/config2.conf
-rw-r--r-- 1 root root 23 Jun 1 08:23 /etc/config2.conf
root@demo2-58998cc654-tlbr4:/# cat /tmp/config1.conf
user=test1
passwd=12345
root@demo2-58998cc654-tlbr4:/# cat /etc/config2.conf
user=test2
passwd=4567
修改ConfigMap
[root@master config]# kubectl edit cm nginx-conf
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
nginx.conf: |
server {
server_name www.nginx.com;
listen 8080;
root /home/nginx/www/
}
kind: ConfigMap
metadata:
creationTimestamp: "2023-05-25T08:29:22Z"
name: nginx-conf
namespace: default
resourceVersion: "90828"
selfLink: /api/v1/namespaces/default/configmaps/nginx-conf
uid: 8a7db3b3-7dc2-4f82-9aee-297d2c7f6b62
#修改完后,大概30秒再查看pod内挂载的配置文件
[root@master config]# kubectl exec nginx-cm-vol -- cat /etc/config/nginx.conf
server {
server_name www.nginx.com;
listen 8080;
root /home/nginx/www/
}
Secret
概述
k8s secrets用于存储和管理一些敏感数据,比如密码,token,密钥等敏感信息。它把 Pod 想要访问的加密数据存放到 Etcd 中。然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了。
Secret 可选参数有三种:
- generic: 通用类型,通常用于存储密码数据。
- tls:此类型仅用于存储私钥和证书。
- docker-registry: 若要保存 docker 仓库的认证信息的话,就必须使用此种类型来创建。
Secret有三种类型:
- Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的
/run/secrets/kubernetes.io/serviceaccount
目录中;创建ServiceAccount后,Pod中指定serviceAccount后,自动创建该ServiceAccount对应的secret; - Opaque : base64编码格式的Secret,用来存储密码、密钥等,可以通过 base64 --decode 解码获得原始数据,因此安全性弱。
- kubernetes.io/dockerconfigjson :用来存储私有docker registry的认证信息。
Secret创建方法
命令行创建
键值对创建
[root@master ~]# kubectl create secret generic user --from-literal=username=test
secret/user created
[root@master ~]# kubectl get secrets
NAME TYPE DATA AGE
default-token-w4jbn kubernetes.io/service-account-token 3 35d
user Opaque 1 8s
[root@master ~]# kubectl describe secrets user
Name: user
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
username: 4 bytes
[root@master ~]# kubectl get secrets user -o yaml
apiVersion: v1
data:
username: dGVzdA==
kind: Secret
metadata:
creationTimestamp: "2023-05-31T08:07:46Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:username: {}
f:type: {}
manager: kubectl-create
operation: Update
time: "2023-05-31T08:07:46Z"
name: user
namespace: default
resourceVersion: "112981"
selfLink: /api/v1/namespaces/default/secrets/user
uid: 7076bbf2-7769-494f-abfc-b576c9956e62
type: Opaque
[root@master ~]# echo "dGVzdA=="|base64 --decode
test
本地文件、目录创建(默认情况下key为文件名)
[root@master secrets]# cat user.txt
admin
[root@master secrets]# kubectl create secret generic username --from-file=user.txt
secret/username created
[root@master secrets]# kubectl get secrets
NAME TYPE DATA AGE
default-token-w4jbn kubernetes.io/service-account-token 3 35d
user Opaque 1 4m27s
username Opaque 1 9s
[root@master secrets]# kubectl get secrets username -o yaml
apiVersion: v1
data:
user.txt: YWRtaW4K
kind: Secret
metadata:
creationTimestamp: "2023-05-31T08:12:04Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:user.txt: {}
f:type: {}
manager: kubectl-create
operation: Update
time: "2023-05-31T08:12:04Z"
name: username
namespace: default
resourceVersion: "113472"
selfLink: /api/v1/namespaces/default/secrets/username
uid: e89aa43d-77aa-4557-850c-17e1bf4388d4
type: Opaque
[root@master secrets]# echo YWRtaW4K|base64 --decode
admin
yaml创建
通过yaml创建Opaque类型的Secret值需要base64编码
[root@master secrets]# cat passwd.yaml
apiVersion: v1
kind: Secret
metadata:
name: password
namespace: default
type: Opaque
data:
password: MTIzNDU2 #echo -n 123456|base64加密生成
[root@master secrets]# kubectl create -f passwd.yaml
secret/password created
[root@master secrets]# kubectl get secrets
NAME TYPE DATA AGE
default-token-w4jbn kubernetes.io/service-account-token 3 35d
password Opaque 1 14s
user Opaque 1 16m
username Opaque 1 12m
[root@master secrets]# kubectl describe secrets password
Name: password
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 6 bytes
[root@master secrets]# kubectl get secrets -o yaml password
apiVersion: v1
data:
password: MTIzNDU2
kind: Secret
metadata:
creationTimestamp: "2023-05-31T08:24:13Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:password: {}
f:type: {}
manager: kubectl-create
operation: Update
time: "2023-05-31T08:24:13Z"
name: password
namespace: default
resourceVersion: "114883"
selfLink: /api/v1/namespaces/default/secrets/password
uid: a574afca-5251-44f6-a198-b792005ad7a4
type: Opaque
[root@master secrets]# echo MTIzNDU2|base64 --decode
123456
Secret使用
通过Volume挂载的方式
挂载后key为文件名,value为文件内容
通过Volume挂载到容器内部时,当该Secret的值发生变化时,容器内部具备自动更新的能力,但是通过环境变量设置到容器内部该值不具备自动更新的能力。所以一般推荐使用Volume挂载的方式使用Secret
[root@master secrets]# cat test-secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-projected-volume
spec:
containers:
- name: test-secret-volume
image: busybox
args:
- sleep
- "86400"
volumeMounts:
- name: test-secret
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: test-secret
projected:
sources:
- secret:
name: username
- secret:
name: password
[root@master secrets]# kubectl create -f test-secret-volume.yaml
pod/test-projected-volume created
[root@master secrets]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-pvc-6fb4755795-74v9d 1/1 Running 1 7d23h
nfs-pvc-6fb4755795-h7wcl 1/1 Running 2 7d23h
nginx-cm 1/1 Running 1 6d
nginx-cm-vol 1/1 Running 1 5d23h
nginx-hpa-b9fb96f5c-7n8dx 1/1 Running 0 47h
nginx-hpa-b9fb96f5c-kb4l9 1/1 Running 0 47h
nginx-hpa-b9fb96f5c-qw8sb 1/1 Running 0 47h
php-apache-fc47b9cd7-khgvt 1/1 Running 0 2d
test-projected-volume 1/1 Running 0 24s
[root@master secrets]# kubectl exec -it test-projected-volume -- /bin/sh
/ # ls
bin dev etc home proc projected-volume root sys tmp usr var
/ # cd projected-volume/
/projected-volume # ls -l
total 0
lrwxrwxrwx 1 root root 15 May 31 08:40 password -> ..data/password
lrwxrwxrwx 1 root root 15 May 31 08:40 user.txt -> ..data/user.txt
/projected-volume # cat user.txt
admin
/projected-volume # cat password
123456
环境变量方式
[root@master secrets]# cat test-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: default
type: Opaque
data:
username: YWRtaW4= #echo -n admin|base64加密生成
password: MTIzNDU2 #echo -n 123456|base64加密生成
[root@master secrets]# kubectl create -f test-secret.yaml
secret/mysecret created
[root@master secrets]# kubectl describe secrets mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 6 bytes
username: 5 bytes
[root@master secrets]# cat test-secret-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-projected-env
spec:
containers:
- name: test-secret-env
image: busybox
args:
- sleep
- "86400"
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
[root@master secrets]# kubectl create -f test-secret-env.yaml
pod/test-projected-env created
[root@master secrets]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nfs-pvc-6fb4755795-74v9d 1/1 Running 1 8d
nfs-pvc-6fb4755795-h7wcl 1/1 Running 2 8d
nginx-cm 1/1 Running 1 6d1h
nginx-cm-vol 1/1 Running 1 6d1h
nginx-hpa-b9fb96f5c-7n8dx 1/1 Running 0 2d
nginx-hpa-b9fb96f5c-kb4l9 1/1 Running 0 2d
nginx-hpa-b9fb96f5c-qw8sb 1/1 Running 0 2d
php-apache-fc47b9cd7-khgvt 1/1 Running 0 2d1h
test-projected-env 1/1 Running 0 49s
test-projected-volume 1/1 Running 0 91m
[root@master secrets]# kubectl exec -it test-projected-env -- /bin/sh
/ # env|grep SECRET
SECRET_PASSWORD=123456
SECRET_USERNAME=admin
总结
最后我们来对比下Secret和ConfigMap这两种资源对象的异同点:
相同点:
- key/value的形式
- 属于某个特定的namespace
- 可以导出到环境变量
- 可以通过目录/文件形式挂载
- 通过 volume 挂载的配置信息均可热更新
不同点:
- Secret 可以被 ServerAccount 关联
- Secret 可以存储 docker register 的鉴权信息,用在 ImagePullSecret 参数中,用于拉取私有仓库的镜像
- Secret 支持 Base64 加密
- Secret 分为 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型,而 Configmap 不区分类型