configmap 和 secret
Configmap和Secret将应用配置和镜像分开,在启动容器时将应用配置注入到容器中,以挂载的文件或卷或环境变量方式在容器内部公开。这样可以减少运维开销,方便配置更新和共享等。
ConfigMap中存储配置数据。
Secret中存储敏感数据。
configmap
命令创建,配置两个nginx变量
kubectl create configmap nginx --from-literal=NGINX_SERVER_PORT=80 --from-literal=NGINX_SERVER_NAME=web # kubectl describe cm nginx ... Data === NGINX_SERVER_NAME: ---- web NGINX_SERVER_PORT: ---- 80 ...
yaml创建,写入nginx.conf
# cat configmap-demo.yaml apiVersion: v1 kind: ConfigMap metadata: name: cm-nginxconf-demo data: nginx.conf: | user nginx; worker_processes 3; error_log /var/log/nginx/error.log; events { worker_connections 10240; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log ; server { listen 80; server_name www.xlbubble.xyz; root /usr/share/nginx/html; index index.html; } } # kubectl get cm NAME DATA AGE cm-nginxconf-demo 2 5s nginx 2 4m47s
将上面两个configmap写入pod
# configmap-nginx-demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: configmap-nginx-demo namespace: default spec: replicas: 2 selector: matchLabels: demo: configmap-nginx template: metadata: labels: demo: configmap-nginx spec: containers: - name: nginx image: nginx:alpine ports: - name: http containerPort: 80 env: - name: NGINX_SERVER_PORT valueFrom: configMapKeyRef: name: nginx key: NGINX_SERVER_PORT - name: NGINX_SERVER_NAME valueFrom: configMapKeyRef: name: nginx key: NGINX_SERVER_NAME volumeMounts: - name: www-conf mountPath: /etc/nginx readOnly: true - name: www mountPath: /var/log/nginx volumes: - name: www-conf configMap: name: cm-nginxconf-demo items: - key: nginx.conf path: nginx.conf - name: www hostPath: path: /data/pod/hostPath type: Directory
访问测试
# kubectl exec -it configmap-nginx-demo-84c97dcdf5-b7895 sh / # env |grep NGINX_SERVER NGINX_SERVER_PORT=80 NGINX_SERVER_NAME=web / # cat /etc/nginx/nginx.conf user nginx; worker_processes 3; error_log /var/log/nginx/error.log; events { worker_connections 10240; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log ; server { listen 80; server_name www.xlbubble.xyz; root /usr/share/nginx/html; index index.html; } } # 先hosts解析下 # curl www.xlbubble.xyz -I
更新configmap配置测试, 将环境变量和配置文件的80更改为8000
kubectl edit cm cm-nginxconf-demo kubectl edit cm nginx ...等大概10s,再查看pod中配置 # kubectl exec -it configmap-nginx-demo-84c97dcdf5-b7895 cat /etc/nginx/nginx.conf ... server { listen 8000; ... # kubectl exec -it configmap-nginx-demo-84c97dcdf5-b7895 env | grep -i nginx_server NGINX_SERVER_PORT=80 NGINX_SERVER_NAME=web # 可以看到环境变量还是80,配置文件中已更改为8000。 # 然后curl ip访问下,访问端口没变还是80,因为configmap仅更新配置,没有重读配置╮(╯▽╰)╭。 # curl 10.244.1.67:8000 -I curl: (7) Failed connect to 10.244.1.67:8000; Connection refused # curl 10.244.1.67:80 -I HTTP/1.1 200 OK Server: nginx/1.17.6 Date: Mon, 06 Jan 2020 06:39:37 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 19 Nov 2019 15:14:41 GMT Connection: keep-alive ETag: "5dd406e1-264" Accept-Ranges: bytes
测试总结:
- 使用 ConfigMap 挂载的 ENV不会同步更新。ENV 是在容器启动的时候注入的,启动之后 k8s 就不会再改变环境变量的值。
- 使用 ConfigMap 挂载的 Volume 中的数据需要一段时间(大概1min左右)才能同步更新。
ConfigMap 仅更新配置,不会重读配置,也不会触发pod滚动更新来重新挂载configmap。需要手动配置pod滚动更新。
# 滚动更新的其中一种方法 kubectl patch deployment configmap-nginx-demo --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "2019120620" }}}}}' kubectl exec -it configmap-nginx-demo-6bfb994f84-kmkrw env | grep -i nginx_server
不过每次configmap更改,都要手动更新一次,有点麻烦。可以参考以下方式实现自动滚动更新:
Kubernetes 中的 ConfigMap 配置更新
Secret
这个和configmap一样,只不过对挂载的数据进行了加密。
secret可以保存各种认证信息,如ssl证书等,具体可见上一章。也可以保存密码
# kubectl create secret generic mariadb --from-literal=password=xxzx@789 # cat secret-mariadb-demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: secret-mariadb-demo spec: replicas: 1 selector: matchLabels: demo: mariadb template: metadata: labels: demo: mariadb spec: containers: - name: mariadb image: mariadb ports: - containerPort: 3306 name: db-port env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mariadb key: password
访问测试
# kubectl exec -it secret-mariadb-demo-6c7fd46fb7-qvfsb env |grep PASS MYSQL_ROOT_PASSWORD=xxzx@789 # 我这里添加了service映射,通过node访问 # mysql -h172.20.2.84 -P30006 -uroot -pxxzx@789 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 5.5.5-10.4.11-MariaDB-1:10.4.11+maria~bionic mariadb.org binary distribution ...
这个secret也有问题,虽然secret保存机密信息,但secret的机密信息用base64编码,这个直接解码就看到密码了。。。
# kubectl edit secret mariadb apiVersion: v1 data: password: eHh6eEA3ODk= kind: Secret ... # echo eHh6eEA3ODk= |base64 -d xxzx@789
扩展与参考
configmap配置
redis配置案例