ConfigMap(配置中心)
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