ConfigMap && Secret
ConfigMap && Secret 是K8S中的針對應用的配置中心,它有效的解決了應用掛載的問題,並且支持加密以及熱更新等功能,可以說是一個k8s提供的一件非常好用的功能。
配置中心ConfigMap
在生產環境中經常會遇到需要修改配置文件的情況,傳統的修改方式不僅會影響到服務的正常運行,而且操作步驟也很繁瑣。為了解決這個問題,kubernetes項目從1.2版本引入了ConfigMap功能,用於將應用的配置信息與程序的分離。這種方式不僅可以實現應用程序被的復用,而且還可以通過不同的配置實現更靈活的功能。在創建容器時,用戶可以將應用程序打包為容器鏡像后,通過環境變量或者外接掛載文件的方式進行配置注入。
創建ConfigMap
創建ConfigMap有兩種方式,一種是配置清單的模式,另一種是kubectl的當時。
1、通過kubectl創建configmap
- 指定配置文件
[root@kubernetes-master-01 ~]# kubectl create configmap file --from-file=ss.yaml
configmap/file created
[root@kubernetes-master-01 ~]# kubectl get configmaps
NAME DATA AGE
file 1 8s
redis-admin 1 2d2h
redis-cluster-operator-lock 0 2d2h
[root@kubernetes-master-01 ~]# kubectl describe configmaps file
Name: file
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
ss.yaml:
----
kind: Namespace
apiVersion: v1
metadata:
name: docsCopy to clipboardErrorCopied
- 指定配置目錄
[root@kubernetes-master-01 test]# mkdir configmap
[root@kubernetes-master-01 test]# touch configmap/index.html
[root@kubernetes-master-01 test]# echo "index" > configmap/index.html
[root@kubernetes-master-01 test]# kubectl create configmap catalog --from-file=configmap/
configmap/catalog created
[root@kubernetes-master-01 test]# kubectl describe configmaps catalog
Name: catalog
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
index.html:
----
index
Events: <none>Copy to clipboardErrorCopied
- 指定配置項
[root@kubernetes-master-01 test]# kubectl create configmap calue --from-literal=key=value --from-literal=key1=value1
configmap/calue created
[root@kubernetes-master-01 test]# kubectl describe configmaps calue
Name: calue
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
key:
----
value
key1:
----
value1
Events: <none>Copy to clipboardErrorCopied
2、通過配置清單的方式創建configmap
[root@kubernetes-master-01 configmap]# cat test.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: configmap-yaml
labels:
app: configmap
data:
key: value
nginx_config: |-
upstream tomcatserver1 {
server 192.168.72.49:8081;
}
upstream tomcatserver2 {
server 192.168.72.49:8082;
}
server {
listen 80;
server_name 8081.max.com;
location / {
proxy_pass http://tomcatserver1;
index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
[root@kubernetes-master-01 configmap]# kubectl apply -f test.yaml
configmap/configmap-yaml created
[root@kubernetes-master-01 configmap]# kubectl describe co
componentstatuses configmaps controllerrevisions.apps
[root@kubernetes-master-01 configmap]# kubectl describe configmaps configmap-yaml
Name: configmap-yaml
Namespace: default
Labels: app=configmap
Annotations: <none>
Data
====
key:
----
value
nginx_config:
----
upstream tomcatserver1 {
server 192.168.72.49:8081;
}
upstream tomcatserver2 {
server 192.168.72.49:8082;
}
server {
listen 80;
server_name 8081.max.com;
location / {
proxy_pass http://tomcatserver1;
index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Events: <none>Copy to clipboardErrorCopied
使用ConfigMap
一般情況下,我們是通過掛載的方式使用configmap。
[root@kubernetes-master-01 configmap]# cat test.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: configmap-yaml
labels:
app: configmap
data:
key: value
nginx_config: |-
upstream tomcatserver1 {
server 192.168.72.49:8081;
}
upstream tomcatserver2 {
server 192.168.72.49:8082;
}
server {
listen 80;
server_name 8081.max.com;
location / {
proxy_pass http://tomcatserver1;
index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
---
kind: Pod
apiVersion: v1
metadata:
name: configmap-pod
labels:
app: configmap-pod
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/demo
name: conf
volumes:
- name: conf
configMap:
name: configmap-yaml
items:
- key: nginx_config
path: nginx_config
- key: key
path: key
[root@kubernetes-master-01 configmap]# kubectl apply -f test.yaml
configmap/configmap-yaml unchanged
pod/configmap-pod created
[root@kubernetes-master-01 configmap]# kubectl get pod -l app=configmap-pod
NAME READY STATUS RESTARTS AGE
configmap-pod 1/1 Running 0 25s
[root@kubernetes-master-01 configmap]# kubectl exec -it configmap-pod -- bash
root@configmap-pod:/# cd /usr/share/nginx/
root@configmap-pod:/usr/share/nginx# ls -l
total 8
drwxrwxrwx 3 root root 4096 Oct 7 12:57 demo
drwxr-xr-x 2 root root 4096 Sep 10 12:33 html
root@configmap-pod:/usr/share/nginx# cd demo/
root@configmap-pod:/usr/share/nginx/demo# ls
key nginx_config
root@configmap-pod:/usr/share/nginx/demo# cat nginx_config
upstream tomcatserver1 {
server 192.168.72.49:8081;
}
upstream tomcatserver2 {
server 192.168.72.49:8082;
}
server {
listen 80;
server_name 8081.max.com;
location / {
proxy_pass http://tomcatserver1;
index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
root@configmap-pod:/usr/share/nginx/demo# cat key
valueroot@configmap-pod:/usr/share/nginx/demo#Copy to clipboardErrorCopied
1、subPath
mountPath結合subPath(也可解決多個configmap掛載同一目錄,導致覆蓋)作用。
[root@kubernetes-master-01 configmap]# cat test.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: configmap-yaml
labels:
app: configmap
data:
key: value
nginx_config: |-
upstream tomcatserver1 {
server 192.168.72.49:8081;
}
upstream tomcatserver2 {
server 192.168.72.49:8082;
}
server {
listen 80;
server_name 8081.max.com;
location / {
proxy_pass http://tomcatserver1;
index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
---
kind: Pod
apiVersion: v1
metadata:
name: configmap-pod
labels:
app: configmap-pod
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/nginx.conf
name: conf
subPath: nginx_config
volumes:
- name: conf
configMap:
name: configmap-yaml
items:
- key: nginx_config
path: nginx_config
[root@kubernetes-master-01 configmap]# kubectl apply -f test.yaml
configmap/configmap-yaml created
pod/configmap-pod created
[root@kubernetes-master-01 configmap]# kubectl get pods
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 5 3d
configmap-pod 1/1 Running 0 8s
nfs-nfs-client-provisioner-867cff4fd7-9wm9z 1/1 Running 5 3d4h
nginx-6cf7488b57-bd887 1/1 Running 5 7d21h
redis-cluster-operator-545d888d7d-7m7fc 1/1 Running 0 2d3h
[root@kubernetes-master-01 configmap]# kubectl exec -it configmap-pod -- bash
root@configmap-pod:/# cd /usr/share/nginx/html/
root@configmap-pod:/usr/share/nginx/html# ls -l
total 12
-rw-r--r-- 1 root root 494 Aug 11 14:50 50x.html
-rw-r--r-- 1 root root 612 Aug 11 14:50 index.html
-rw-r--r-- 1 root root 340 Oct 7 13:32 nginx.conf
root@configmap-pod:/usr/share/nginx/html# cat nginx.conf
upstream tomcatserver1 {
server 192.168.72.49:8081;
}
upstream tomcatserver2 {
server 192.168.72.49:8082;
}
server {
listen 80;
server_name 8081.max.com;
location / {
proxy_pass http://tomcatserver1;
index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Copy to clipboardErrorCopied
ConfigMap使用注意
- ConfigMap必須在Pod之前創建。
- ConfigMap受Namespace限制,只有處於相同Namespace中的Pod才可以引用它。
ConfigMap熱更新
熱更新指在不停服的情況下,更新configMap配置。
我們都知道,在K8S中,所有的配置信息全部都存在ETCD中,我們也可以查看:
ETCDCTL_API=3 etcdctl \
--cacert=/etc/etcd/ssl/etcd.pem \
--cert=/etc/etcd/ssl/etcd.pem \
--key=/etc/etcd/ssl/etcd-key.pem \
--endpoints="https://172.16.0.50:2379,https://172.16.0.51:2379,https://172.16.0.52:2379" \
/registry/configmaps/default/file | python -m json.toolCopy to clipboardErrorCopied
如果使用subpath,configmap將不支持熱更新。
創建Deployment及ConfigMpa
DEBUG[root@kubernetes-master-01 configmap]# cat test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 1
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: env-config
volumeMounts:
- mountPath: /usr/share/nginx/demo/
name: config
volumes:
- name: config
configMap:
name: env-config
items:
- key: log_level
path: log_level
---
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: default
data:
log_level: INFO
[root@kubernetes-master-01 configmap]# kubectl apply -f test.yaml
deployment.apps/my-nginx configured
configmap/env-config unchanged
[root@kubernetes-master-01 configmap]# kubectl exec my-nginx-6947589dc-tbvs5 -- cat /usr/share/nginx/demo/log_level
INFO
[root@kubernetes-master-01 configmap]# kubectl edit configmaps env-config
configmap/env-config edited
[root@kubernetes-master-01 configmap]# kubectl exec my-nginx-6947589dc-tbvs5 -- cat /usr/share/nginx/demo/log_level
DEBUGCopy to clipboardErrorCopied
我們可以看到,容器中的內容已經發生了改變。
Secret
Secret解決了密碼、token、密鑰等敏感數據的配置問題,而不需要把這些敏感數據暴露到鏡像或者Pod Spec中。Secret可以以Volume或者環境變量的方式使用。
Secret有三種類型:
- Service Account :用來訪問Kubernetes API,由Kubernetes自動創建,並且會自動掛載到Pod的
/run/secrets/kubernetes.io/serviceaccount目錄中; - Opaque :base64編碼格式的Secret,用來存儲密碼、密鑰等;
- kubernetes.io/dockerconfigjson :用來存儲私有docker registry的認證信息。
Opaque Secret
Opaque類型的數據是一個map類型,要求value是base64編碼格式
[root@kubernetes-master-01 ~]# echo -n "oldboy" | base64
b2xkYm95
[root@kubernetes-master-01 ~]# echo "oldboy123" | base64
b2xkYm95MTIzCg==Copy to clipboardErrorCopied
編寫secret配置清單
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: b2xkYm95MTIzCg==
username: b2xkYm95Copy to clipboardErrorCopied
創建secret資源
[root@kubernetes-master-01 secret]# vim secret.yaml
[root@kubernetes-master-01 secret]# kubectl apply -f secret.yaml
secret/mysecret created
[root@kubernetes-master-01 secret]# kubectl describe secrets mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 10 bytes
username: 6 bytesCopy to clipboardErrorCopied
編寫測試應用配置清單
kind: Deployment
apiVersion: apps/v1
metadata:
name: mysecret
spec:
selector:
matchLabels:
app: mysecret
template:
metadata:
labels:
app: mysecret
spec:
containers:
- name: nginx
imagePullPolicy: IfNotPresent
image: nginx
volumeMounts:
- name: mysecret
mountPath: "/opt/secrets"
readOnly: true
volumes:
- name: mysecret
secret:
secretName: mysecretCopy to clipboardErrorCopied
創建測試資源
[root@kubernetes-master-01 secret]# kubectl apply -f secret.yaml
deployment.apps/mysecret created
secret/mysecret unchanged
[root@kubernetes-master-01 secret]# kubectl exec -it mysecret-5bcb897fff-77bn5 -- bash
root@mysecret-5bcb897fff-77bn5:/# cd /opt/secrets/
root@mysecret-5bcb897fff-77bn5:/opt/secrets# ls
password username
root@mysecret-5bcb897fff-77bn5:/opt/secrets# cat username
oldboyroot@mysecret-5bcb897fff-77bn5:/opt/secrets# cat password
oldboy123Copy to clipboardErrorCopied
kubernetes.io/dockerconfigjson
用來存儲私有docker registry的認證信息。
創建secret
export DOCKER_REGISTRY_SERVER=10.0.0.100
export DOCKER_USER=root
export DOCKER_PASSWORD=root@123
export DOCKER_EMAIL=root@123.com
kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
[root@kubernetes-master-01 secret]# export DOCKER_REGISTRY_SERVER=10.0.0.100
[root@kubernetes-master-01 secret]# export DOCKER_USER=root
[root@kubernetes-master-01 secret]# export DOCKER_PASSWORD=root@123
[root@kubernetes-master-01 secret]# export DOCKER_EMAIL=root@123.com
[root@kubernetes-master-01 secret]#
[root@kubernetes-master-01 secret]# kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret/myregistrykey created
[root@kubernetes-master-01 secret]# kubectl describe secret myregistrykey
Name: myregistrykey
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 161 bytesCopy to clipboardErrorCopied
創建測試secret
kind: Deployment
apiVersion: apps/v1
metadata:
name: mysecret
spec:
selector:
matchLabels:
app: mysecret
template:
metadata:
labels:
app: mysecret
spec:
containers:
- name: nginx
imagePullSecrets:
- name: myregistrykeyCopy to clipboardErrorCopied
Service Account
Service Account用來訪問Kubernetes API,由Kubernetes自動創建,並且會自動掛載到Pod的/run/secrets/kubernetes.io/serviceaccount目錄中。
[root@kubernetes-master-01 secret]# kubectl exec nginx-6cf7488b57-bd887 -- ls /run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
tokenCopy to clipboardErrorCopied
