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 [email protected]
# 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
[email protected]
# 我這裡添加了service映射,通過node通路
# mysql -h172.20.2.84 -P30006 -uroot [email protected]
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
[email protected]
擴充與參考
configmap配置
redis配置案例