kubernetes(16):k8s的配置管理configmap
K8s的配置管理configmap
https://www.qinzc.me/post-230.html
https://www.cnblogs.com/wzlinux/p/10159340.html
https://pdf.us/2019/03/13/2994.html
1 k8s中的配置修改需求
很多情况下我们为某一应用做好镜像,当我们想修改其中的一些参数的时候,就变得比较麻烦,又要重新制作镜像,我们是不是有一种方式,让镜像根据不同的场景调用我们不同的配置文件呢,那我们就需要用到 k8s 的另外一种资源,那就是 ConfigMap。
我们知道,在几乎所有的应用开发中,都会涉及到配置文件的变更,比如说在web的程序中,需要连接数据库,缓存甚至是队列等等。而我们的一个应用程序从写第一行代码开始,要经历开发环境、测试环境、预发布环境只到最终的线上环境。而每一个环境都要定义其独立的各种配置。如果我们不能很好的管理这些配置文件,你的运维工作将顿时变的无比的繁琐。为此业内的一些大公司专门开发了自己的一套配置管理中心,如360的Qcon,百度的disconf等。kubernetes也提供了自己的一套方案,即ConfigMap。kubernetes通过ConfigMap来实现对容器中应用的配置管理。
给Kubernetes管理员或用户提供从集群外部向POD内部的应用注入配置信息的方式.类似一个配置中心。把配置文件存入配置中心。配置有变化,让POD重载这些配置文件,极大方便管理。可以理解为configMap就是K8S上的配置中心。但是configMap存储的数据是明文保存的,Secret则是BASE64编码机制保存的。
2 创建 ConfigMap的4个方法
ConfigMap是用来存储配置文件的kubernetes资源对象,所有的配置内容都存储在etcd中。
创建ConfigMap的方式有4种:
l 通过直接在命令行中指定configmap参数创建,即--from-literal;
l 通过指定文件创建,即将一个配置文件创建为一个ConfigMap,--from-file=<文件>;
l 通过一个文件内多个键值对,--from-env-file=<文件>;
l 事先写好标准的configmap的yaml文件,然后kubectl create -f 创建。
2.1 通过--from-literal
kubectl create configmap test-config --from-literal=db.host=192.168.1.2 --from-literal=db.port=3306 --from-literal=user=admin --from-literal=password=123456
[root@k8s-master configmap]# kubectl get cm test-config NAME DATA AGE test-config 4 18s [root@k8s-master configmap]# kubectl get cm test-config -o yaml apiVersion: v1 data: db.host: 192.168.1.2 db.port: "3306" password: "123456" user: admin kind: ConfigMap metadata: creationTimestamp: "2019-09-03T08:38:54Z" name: test-config namespace: default resourceVersion: "680690" selfLink: /api/v1/namespaces/default/configmaps/test-config uid: fc3ef6c3-6b97-4b73-8692-9db6f175659d [root@k8s-master configmap]#
2.2 通过--from-file
echo -n '192.168.0.1' > ./db.host echo -n '3306' > ./db.port echo -n 'admin' > ./user echo -n '123456' > ./password kubectl create cm test-config2 --from-file=./db.host --from-file=./db.port --from-file=user --from-file=password
[root@k8s-master configmap]# kubectl get cm test-config2NAME DATA AGE test-config2 4 6s [root@k8s-master configmap]# kubectl get cm test-config2 -o yamlapiVersion: v1 data: db.host: 192.168.0.1 db.port: "3306" password: "123456" user: admin kind: ConfigMap metadata: creationTimestamp: "2019-09-03T08:42:46Z" name: test-config2 namespace: default resourceVersion: "681058" selfLink: /api/v1/namespaces/default/configmaps/test-config2 uid: 9176b7e2-0ac5-4891-9040-5bb8b3e1450c [root@k8s-master configmap]#
2.3 通过--from-env-file
cat << EOF > env-config.txt db.host=192.168.0.1 db.port=3306 user=admin password=123456 EOF kubectl create cm test-config3 --from-env-file=env-config.txt
[root@k8s-master configmap]# kubectl get cm test-config3NAME DATA AGE test-config3 4 5s [root@k8s-master configmap]# kubectl get cm test-config3 -o yamlapiVersion: v1 data: db.host: 192.168.0.1 db.port: "3306" password: "123456" user: admin kind: ConfigMap metadata: creationTimestamp: "2019-09-03T08:46:02Z" name: test-config3 namespace: default resourceVersion: "681371" selfLink: /api/v1/namespaces/default/configmaps/test-config3 uid: 882cd303-9d94-4f04-bc10-2cd205293df3 [root@k8s-master configmap]#
2.4 通过yaml文件
# cat config.yaml apiVersion: v1 kind: ConfigMap metadata: name: test-config4 data: db.host: 192.168.0.200 db.port: "3306" user: "admin" password: "123456"
[root@k8s-master configmap]# kubectl apply -f config.yaml configmap/test-config4 created [root@k8s-master configmap]# kubectl get cm test-config4 NAME DATA AGE test-config4 4 4s [root@k8s-master configmap]# kubectl get cm test-config4 -o yaml apiVersion: v1 data: db.host: 192.168.0.200 db.port: "3306" password: "123456" user: admin kind: ConfigMap metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"db.host":"192.168.0.200","db.port":"3306","password":"123456","user":"admin"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"test-config4","namespace":"default"}} creationTimestamp: "2019-09-03T08:48:31Z" name: test-config4 namespace: default resourceVersion: "681609" selfLink: /api/v1/namespaces/default/configmaps/test-config4 uid: 3101d4c0-e130-46da-8b18-8bf0116b11f1 [root@k8s-master configmap]#
3 ConfigMap 使用
使用ConfigMap有二种方式:
l 第一种是通过环境变量的方式,直接传递给pod;
l 第二种是作为volume的方式挂载到pod内。
3.1 Nginx通过环境变量使用
使用valueFrom
、configMapKeyRef
、name
、key
指定要用的key。
https://www.cnblogs.com/lovelinux199075/p/11294987.html
docker官方给出的Nginx安装文档
常见的变量
- NGINX_HOST=foobar.com
- NGINX_PORT=80
创建configmap
[root@k8s-master configmap]# kubectl create configmap nginx-config --from-literal=NGINX_PORT=888 --from-literal=SERVER_NAME=www.wx.com configmap/nginx-config created [root@k8s-master configmap]# kubectl describe configmap nginx-config Name: nginx-config Namespace: default Labels: <none> Annotations: <none> Data ==== NGINX_PORT: ---- 888 SERVER_NAME: ---- www.wx.com Events: <none> [root@k8s-master configmap]# [root@k8s-master configmap]# [root@k8s-master configmap]# kubectl get cm nginx-config -o yaml apiVersion: v1 data: NGINX_PORT: "888" SERVER_NAME: www.wx.com kind: ConfigMap metadata: creationTimestamp: "2019-09-04T07:43:15Z" name: nginx-config namespace: default resourceVersion: "812366" selfLink: /api/v1/namespaces/default/configmaps/nginx-config uid: b8c71e6f-8a37-45b3-ac87-eb9547b78d8d [root@k8s-master configmap]#
创建Nginx-deployment
# cat nginx_dep.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 envFrom: - configMapRef: name: nginx-config # env: #两种方法都行 # - name: NGINX_SERVER_PORT #pod容器中的环境变量名字 # valueFrom: # configMapKeyRef: # name: nginx-config #configmap的名字 # key: nginx_port #configmap中定义的key # # - name: NGINX_SERVER_NAME # valueFrom: # configMapKeyRef: # name: nginx-config # key: server_name
验证
[root@k8s-master configmap]# kubectl exec -it nginx-deployment-b7cbfc4c-6w6p6 env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=nginx-deployment-b7cbfc4c-6w6p6 TERM=xterm NGINX_SERVER_PORT=888 NGINX_SERVER_NAME=www.wx.com KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT=tcp://10.96.0.1:443 KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443 KUBERNETES_PORT_443_TCP_PROTO=tcp KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1 KUBERNETES_SERVICE_HOST=10.96.0.1 KUBERNETES_SERVICE_PORT=443 NGINX_VERSION=1.17.3 NJS_VERSION=0.3.5 PKG_RELEASE=1~buster HOME=/root
Dashboard查看
3.2 NGINX通过volumeMount使用ConfigMap
https://blog.51cto.com/passed/2348256
文件创建configmap
# cat config.yaml apiVersion: v1 kind: ConfigMap metadata: name: nginx-config2 data: nginx.conf: |+ ##这一段就是内容,nginx.conf是该文件的键 server { listen 8081; server_name www.sb.com 127.0.0.1; root /html; location / { } }
[root@k8s-master configmap]# kubectl apply -f config.yaml configmap/nginx-config2 unchanged [root@k8s-master configmap]# kubectl get cm nginx-config2 NAME DATA AGE nginx-config2 1 18m [root@k8s-master configmap]# kubectl describe cm nginx-config2 Name: nginx-config2 Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","data":{"nginx.conf":"server {\n listen 8081;\n server_name www.sb.com 127.0.0.1;\n root /html;\n\... Data ==== nginx.conf: ---- server { listen 8081; server_name www.sb.com 127.0.0.1; root /html; location / { } } Events: <none>
创建Nginx-dep和svc
# cat nginx_dep.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: #挂载 - name: nginxconfig #调用下面定义的存储卷, 名字要一致 mountPath: /etc/nginx/conf.d/ #pod容器目录 readOnly: true #只读 volumes: #创建一个存储卷 - name: nginxconfig #定义存储卷名字 configMap: #定义存储卷类型为configMap name: nginx-config2 #引用名字叫nginx-file的configmap, --- apiVersion: v1 kind: Service metadata: name: nginx-svc spec: type: NodePort selector: app: nginx ports: - protocol: TCP port: 8081 targetPort: 8081 nodePort: 30081
验证
[root@k8s-master configmap]# kubectl exec -it nginx-deployment-6c7bc64dbf-dd9s7 /bin/bash root@nginx-deployment-6c7bc64dbf-dd9s7:/# cd /etc/nginx/ root@nginx-deployment-6c7bc64dbf-dd9s7:/etc/nginx# cd conf.d/ root@nginx-deployment-6c7bc64dbf-dd9s7:/etc/nginx/conf.d# ls -al total 4 drwxrwxrwx 3 root root 74 Sep 4 08:05 . drwxr-xr-x 3 root root 4096 Aug 15 21:22 .. drwxr-xr-x 2 root root 23 Sep 4 08:05 ..2019_09_04_08_05_02.735756292 lrwxrwxrwx 1 root root 31 Sep 4 08:05 ..data -> ..2019_09_04_08_05_02.735756292 lrwxrwxrwx 1 root root 17 Sep 4 08:05 nginx.conf -> ..data/nginx.conf #可以看到这个配置文件是一个相对路径不是实体文件 root@nginx-deployment-6c7bc64dbf-dd9s7:/etc/nginx/conf.d# root@nginx-deployment-6c7bc64dbf-dd9s7:/# mkdir /html root@nginx-deployment-6c7bc64dbf-dd9s7:/# cd /html/ root@nginx-deployment-6c7bc64dbf-dd9s7:/html# ls root@nginx-deployment-6c7bc64dbf-dd9s7:/html# echo 'cc' >> index.html root@nginx-deployment-6c7bc64dbf-dd9s7:/html# exit [root@k8s-master configmap]# [root@k8s-master configmap]# [root@k8s-master configmap]# curl 10.254.2.74:8081 cc [root@k8s-master configmap]# [root@k8s-master configmap]# curl 10.6.76.24:30091 cc [root@k8s-master configmap]#
3.3 ConfigMap的热更新
使用该 ConfigMap 挂载的 Env 不会同步更新;
使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新。
# cat config.yaml apiVersion: v1 kind: ConfigMap metadata: name: nginx-config2 data: nginx.conf: |+ ##这一段就是内容,nginx.conf是该文件的键 server { listen 8081; server_name www.new-sb.com 127.0.0.1; root /html; location / { } }
# cat config.yaml apiVersion: v1 kind: ConfigMap metadata: name: nginx-config2 data: nginx.conf: |+ ##这一段就是内容,nginx.conf是该文件的键 server { listen 8081; server_name www.new-sb.com 127.0.0.1; root /html; location / { } }
3.4 通过configmap更新Mysql配置文件
https://www.cnblogs.com/chy-op/p/9811852.html
大多数情况下,配置信息都以文件形式提供,所以在创建 ConfigMap 时通常采用 --from-file 或 YAML 方式,读取 ConfigMap 时通常采用 Volume 方式。
比如我们的 MySQL 配置文件/etc/my.cnf。
创建configmap
# cat my.conf.yaml apiVersion: v1 kind: ConfigMap metadata: name: mysql-config data: my.cnf: |+ [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 [mysqld_safe] log-error=/var/log/mysql/mysql.log pid-file=/var/run/mysql/mysql.pid
[root@k8s-master configmap]# kubectl apply -f my.conf.yaml
configmap/mysql-config unchanged
查看创建的cm
[root@k8s-master configmap]# kubectl get cm mysql-config NAME DATA AGE mysql-config 1 50s [root@k8s-master configmap]# kubectl describe cm mysql-config Name: mysql-config Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","data":{"my.cnf":"[mysqld]\ndatadir=/var/lib/mysql\nsocket=/var/lib/mysql/mysql.sock\nsymbolic-links=0\n[mysqld_safe]\n... Data ==== my.cnf: ---- [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 [mysqld_safe] log-error=/var/log/mysql/mysql.log pid-file=/var/run/mysql/mysql.pid Events: <none> [root@k8s-master configmap]#
在Pod 中使用此 ConfigMap
Version: apps/v1 kind: Deployment metadata: name: mysql-dev namespace: default labels: app: mysql-dev spec: replicas: 1 selector: matchLabels: app: mysql-dev template: metadata: labels: app: mysql-dev spec: containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD value: "123456" ports: - containerPort: 3306 volumeMounts: - name: mysqlconfig-volume #<--(1) mountPath: "/etc/mysql/mysql.conf.d/" #<--(2) volumes: - name: mysqlconfig-volume # <--(3) configMap: # <--(4) name: mysql-config # <--(5)
其中,(1)表示一个挂载点的名称
(2)表示新挂载点的路径,这里就是mysql配置文件的路径
(3)表示挂载点的名称
(4)使用configmap
(5)使用名为mysql-config,configmap的name
创建 Pod 并读取配置信息
[root@k8s-master configmap]# kubectl apply -f mysql.yaml deployment.apps/mysql-dev unchanged [root@k8s-master configmap]# kubectl get pod NAME READY STATUS RESTARTS AGE mysql-dev-767875cf5f-pqd6x 1/1 Running 0 4m46s [root@k8s-master configmap]# kubectl exec -it mysql-dev-767875cf5f-pqd6x /bin/bash root@mysql-dev-767875cf5f-pqd6x:/# cd /etc/mysql/ root@mysql-dev-767875cf5f-pqd6x:/etc/mysql# ls -al total 12 drwxr-xr-x 4 root root 94 Aug 14 06:09 . drwxr-xr-x 33 root root 4096 Sep 4 09:11 .. drwxr-xr-x 2 root root 62 Aug 14 06:09 conf.d lrwxrwxrwx 1 root root 24 Aug 14 06:09 my.cnf -> /etc/alternatives/my.cnf -rw-r--r-- 1 root root 839 Jul 9 2016 my.cnf.fallback -rw-r--r-- 1 root root 796 Jun 10 14:58 mysql.cnf drwxrwxrwx 3 root root 70 Sep 4 09:11 mysql.conf.d root@mysql-dev-767875cf5f-pqd6x:/etc/mysql# cd mysql.conf.d/ root@mysql-dev-767875cf5f-pqd6x:/etc/mysql/mysql.conf.d# ls -al total 0 drwxrwxrwx 3 root root 70 Sep 4 09:11 . drwxr-xr-x 4 root root 94 Aug 14 06:09 .. drwxr-xr-x 2 root root 19 Sep 4 09:11 ..2019_09_04_09_11_55.727621531 lrwxrwxrwx 1 root root 31 Sep 4 09:11 ..data -> ..2019_09_04_09_11_55.727621531 lrwxrwxrwx 1 root root 13 Sep 4 09:11 my.cnf -> ..data/my.cnf root@mysql-dev-767875cf5f-pqd6x:/etc/mysql/mysql.conf.d# cat my.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 [mysqld_safe] log-error=/var/log/mysql/mysql.log pid-file=/var/run/mysql/mysql.pid root@mysql-dev-767875cf5f-pqd6x:/etc/mysql/mysql.conf.d#