仍是老规矩先来了解下什么是ConfigMap,那么在了解ConifigMap的同时也得了解下另外一个概念就是Secret。可能会有人说,你这不是在讲ConfigMap么,怎么还要扯Secret,别着急等我慢慢道来,那为何要有这两个东西呢?由于在实际应用的过程当中,咱们常常会须要传一些配置给咱们的应用,好比配置文件变动啊、用户名密码啊等等之类的。可能这个时候就会有童鞋说了咱们有好多种方案能够实现啊,好比:html
1.咱们能够直接在打包镜像的时候写在应用配置文件里面。node
2.咱们能够在配置文件里面经过env环境变量传入。mysql
3.咱们能够在应用启动的时候去数据库或者某个特定的地方拿。 web
确实能够实现,但每一个方案的弊端也显而易见,好比:sql
1.这种方式的坏处显而易见并且很是明显,几乎是绑死了配置,不便于后续操做。docker
2.这样的话咱们要修改env就必须去修改yaml文件,并且须要重启全部的Container才行。数据库
3.第三个方案实现起来麻烦,另外若是配置的地方变了怎么办?这个跟第一种方式有点相似,太过于锁死。api
固然还有别的方案,可是各类方案都有各自的问题,并且还有一个问题就是,若是说个人一个配置,是要多个应用一块儿使用的,以上除了第三种方案,都没办法进行配置的共享,就是说我若是要改配置的话,那得一个一个手动改。假如咱们有100个应用,就得改100份配置,以此类推……bash
Kubernetes对这个问题提供了一个很好的解决方案,就是用ConfigMap和Secret。前面说了那么多那么究竟这俩是什么概念,相信聪明的童鞋已经知道是干什么的了。app
根据字面意思就能够理解到,ConfigMap是存储通用的配置变量的,相似于配置文件,使用户能够将分布式系统中用于不一样模块的环境变量统一到一个对象中管理;而它与配置文件的区别在于它是存在集群的“环境”中的,而且支持K8S集群中全部通用的操做调用方式。而Secret呢就是存储一些比较敏感的信息,好比:密码、密钥之类的信息。
从数据角度来看,ConfigMap的类型只是键值组,用于存储被Pod或者其余资源对象(如RC)访问的信息。这与secret的设计理念有殊途同归之妙,主要区别在于ConfigMap一般不用于存储敏感信息,而只存储简单的文本信息。
本文呢咱们拿Myql举例来看看如何实现ConfigMap也就是说配置文件与Container解耦的,建立ConfigMap的方式有两种,一种是经过yaml文件来建立,另外一种是经过kubectl直接在命令行下建立。
因为是测试我这里随便找了一个my.cnf,比较简洁。
[root@k8smaster configmap]# cat mysqld.cnf [client] port = 3306 socket = /var/run/mysqld/mysqld.sock [mysql] no-auto-rehash [mysqld] user = mysql port = 3306 socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql [mysqld_safe] log-error= /var/log/mysql/mysql_oldboy.err pid-file = /var/run/mysqld/mysqld.pid
注意:
这个名字为何是mysqld.cnf,是由于容器里读取的配置文件名字就是这个,最少修改的原则,直接取代覆盖,还用原名字。
用这个文件建立ConfigMap
[root@k8smaster configmap]# kubectl create configmap mysql-config --from-file=mysqld.cnf configmap "mysql-config" created
有两种方式让pod使用,第一种是环境变量或参数,第二种是文件挂载。咱们今天以Volume形式挂载进Mysql容器,并读取这个文件启动,挂载到哪里呢?确定是挂载到默认的存放配置文件处,并取代它。好比Mysql,它的配置文件就在/etc/mysql/mysql.conf.d/。
[root@k8smaster configmap]# cat mysql-svc2.yml apiVersion: v1 kind: Service metadata: name: mysql2 spec: ports: - port: 3306 selector: app: mysql1 --- apiVersion: apps/v1beta1 kind: Deployment metadata: name: mysql-t1 spec: selector: matchLabels: app: mysql1 template: metadata: labels: app: mysql1 spec: containers: - image: mysql:5.7 name: mysql-t env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-t1 mountPath: /etc/mysql/mysql.conf.d ##注意路径 volumes: - name: mysql-t1 configMap: name: mysql-config
注意:
当ConfigMap以数据卷的形式挂载进Pod时,更新ConfigMap(或删掉重建ConfigMap),Pod内挂载的配置信息会热更新,但使用环境变量方式加载到pod,则不会自动更新。
[root@k8smaster configmap]# kubectl apply -f mysql-svc2.yml service "mysql2" created deployment.apps "mysql-t1" created
最后咱们来验证下是否把镜像里面默认的配置文件换成了咱们刚才修改的配置文件。
[root@k8snode1 ~]# docker ps | grep mysql 23c3846564ec docker.io/mysql@sha256:e8f85df0b02606e573ad3dfa31ad6dd1d659ad72ea927f8f307b28fa19ab9cc5 "docker-entrypoint..." 4 minutes ago Up 4 minutes [root@k8snode1 ~]# docker exec -it 23c3846564ec bash root@mysql-t1-6fbf57db97-dvh42:/# root@mysql-t1-6fbf57db97-dvh42:/# root@mysql-t1-6fbf57db97-dvh42:/# cd /etc/mysql/mysql.conf.d/ root@mysql-t1-6fbf57db97-dvh42:/etc/mysql/mysql.conf.d# ls mysqld.cnf root@mysql-t1-6fbf57db97-dvh42:/etc/mysql/mysql.conf.d# cat mysqld.cnf [client] port = 3306 socket = /var/run/mysqld/mysqld.sock [mysql] no-auto-rehash [mysqld] user = mysql port = 3306 socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql [mysqld_safe] log-error= /var/log/mysql/mysql_oldboy.err pid-file = /var/run/mysqld/mysqld.pid
能够看到已经覆盖原文件。好了,本文关于ConfigMap就介绍到这里,关于另一种方式,能够本身琢磨下,这里就不在赘述了,后续有机会能够在介绍下。
本文参考了:
https://blog.51cto.com/goome/2155871
https://www.kubernetes.org.cn/3400.html