仍是老規矩先來了解下什麼是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