深刻玩轉K8S之如何實現外掛配置管理—ConfigMap

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

相關文章
相關標籤/搜索