K8s configMap原理介紹


給容器內應用程序傳遞參數的實現方式:
  1. 將配置文件直接打包到鏡像中,但這種方式不推薦使用,因為修改配置不夠靈活。
  2. 通過定義Pod清單時,指定自定義命令行參數,即設定 args:["命令參數"],這種也
      可在啟動Pod時,傳參來修改Pod的應用程序的配置文件.
  3. 使用環境變量來給Pod中應用傳參修改配置
     但要使用此種方式,必須符合以下前提之一:
      1) Pod中的應用程序必須是Cloud Native的應用程序,即支持直接通過環境變量來加載配置信息。
      2) 通過定義Entrypoint腳本的預處理變量來修改Pod中應用程序的配置文件,這些Entrypoint腳本
       可以使用set,sed,grep等工具來實現修改,但也要確保容器中有這些工具。
  4.存儲卷: 我們可將配置信息直接放到存儲卷中,如PV中,Pod啟動時,自動掛載存儲卷到配置文件目錄,
      來實現給Pod中應用提供不同的配置。
  5. configMap 或 secret
    

configMap的主要作用:
  就是為了讓鏡像 和 配置文件解耦,以便實現鏡像的可移植性和可復用性,因為一個configMap其實就是一系列配置信息的集合,將來可直接注入到Pod中的容器使用,而注入方式有兩種,一種將configMap做為存儲卷,一種是將configMap通過env中configMapKeyRef注入到容器中; configMap是KeyValve形式來保存數據的,如: name=zhangsan 或 nginx.conf="http{server{...}}" 對於configMap的Value的長度是沒有限制的,所以它可以是一整個配置文件的信息。
configMap: 它是K8s中的標准組件,它通過兩種方式實現給Pod傳遞配置參數:
  A. 將環境變量直接定義在configMap中,當Pod啟動時,通過env來引用configMap中定義的環境變量。
  B. 將一個完整配置文件封裝到configMap中,然后通過共享卷的方式掛載到Pod中,實現給應用傳參。
secret: 它時一種相對安全的configMap,因為它將configMap通過base64做了編碼, 讓數據不是明文直接存儲在configMap中,起到了一定的保護作用,但對Base64進行反編碼,對專業人士來說,沒有任何難度,因此它只是相對安全。

對於configMap中第一種,讓Pod引用configMap中的環境變量的方式:
  kubectl explain pods.spec.containers.env    #env也可直接定義傳遞給Pod中容器的環境變量,這點需要記住。
    env.valueFrom
       configMapKeyRef: 可用於定義Pod啟動時引用的configMapKey是哪個。
       fieldRef: 也可引用一個字段,為Pod中容器內應用程序的每個環境變量值,如:
       metadata.name: 引用Pod的名稱
       metadata.namespace: 引用Pod所在的名稱空間名
       metadata.labels: 引用Pod的標簽
       status.hostIP: 引用Pod所在節點的IP
       status.podIP: 引用Pod的IP
       resourceFieldRef: 引用一個資源需求 或 資源限制
       secretKeyRef: 引用一個secretKey來為Pod傳參

在定義configMap時,通常僅需要定義它的data 或 binaryData(二進制數據),它倆都是map[string]類型的,
所以它們的值都是以hash列表方式存儲的,即key和value沒有直接關系,key就是hash碼。

創建configmap示例:
  #命令創建:
  kubectl create configmap nginx-config --from-literal=nginx_port=80 --from-literal=server_name=myapp.test.com

  kubectl get configmap

  kubectl describe cm nginx-config

  #使用文件內容來做key的值
  vim w3c.conf
    server {
        server_name bbs.test.com;
        listen 80;
     root /data/nginx/bbs/
   }

#注意:configmap的名稱中不支持下划線!
  #這個是定義了一個key叫www, 其值為www.conf的內容.
  kubectl create configmap nginx-www --from-file=www=./www.conf 

  #這是定義了一個key叫www.conf,其值為www.conf的內容
  kubectl create configmap nginx-www --from-file=./www.conf 

  kubectl get cm nginx-www -o yaml
  kubectl describe cm nginx-www

#給Pod中的容器傳遞configMap定義的變量的示例:
vim  pod-configmap.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm-1
  namespace: default
  labels:
     app: myapp
     tier: frontend
  annotations:
     test.com/created-by: “cluster admin”
spec:
  containers:
  -  name: myapp
     image: ikubernetes/myapp:v1
     ports:
     -   name: http
         containerPort:80
     env:
     - name: NGINX_SERVER_PORT
       valueFrom:
         configMapKeyRef:
            name: nginx-config
            key: nginx_port
     -  name:NGINX_SERVER_NAME
        valueFrom:
          configMapKeyRef:
            name: nginx-config
            key: server_name

#應用這個使用configMap的Pod

  kubectl apply -f pod-configmap.yaml

#進入Pod查看configMap傳入的變量
  kubectl exec -it pod-cm-1 -- /bin/sh
  / # printenv   #查看我們定義的變量有沒有傳遞進來.

#接着我們來修改configmap中可以的值,看能否在Pod馬上生效:
  kubectl edit cm nginx-config      #將nginx-config這個configmap中的值修改一下.
  kubectl describe cm nginx-config   #確認edit已經修改了configmap中key的值.

#接着在登陸pod-cm-1 這個Pod中,查看容器中變量的值是否改變了。
#可以看到值是不會改變的,它僅會在創建Pod時,加載一次configmap中的數據.

#通過共享卷的方式來掛載configmap:
vim  pod-configmap-2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm-2
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    test.com/created-by: “cluster admin”
spec:
 containers:
 - name: myapp
   image: ikubernetes/myapp:v1
   ports:
   - name: http
     containerPort: 80
   volumeMounts:
   - name: nginxconf
     mountPath: /etc/nginx/config.d/   #掛載點不存在,Pod會自動創建.
     readOnly: true       #不能讓容器修改配置的內容。
volumes:
-  name: nginxconf        #定義存儲卷的名字為nginxconf
   configMap:
     name: nginx-config   #要掛載nginx-config這個configMap

   #創建Pod
  kubectl apply -f pod-configmap-2.yaml

  kubectl exec -it pod-cm-2 -- /bin/sh
  / # ls -l /etc/nginx/config.d/
    total 0
    lrwxrwxrwx 1 root root 17 Jul 21 13:48 nginx_port -> ..data/nginx_port
    lrwxrwxrwx 1 root root 18 Jul 21 13:48 server_name -> ..data/server_name

注: 你將可以看到config.d下面創建了兩個連接文件,它們的內容就時nginx-config這個configMap中定義的變量值,連接文件名為key的名字, 連接文件指向的文件其實是新版本的configmap文件,即當configmap文件被修改時,它就會將改變同步到API Server,APIServer在將改變通告給所有引用者,之后引用者的內容也將變成新版本的內容,這樣就可以實現動態更新配置文件了。

#測試動態更新configmap的變量值
  kubectl edit cm nginx-config   
     #修改nginx-config的中server_port為8888 查看Pod中的變化.
      不過要有點耐心,因為APIServer通告完成是需要時間的。

通常若非敏感數據,均可使用明文存儲的configMap來做,若涉及到密碼,私鑰等數據時,一定要使用secret類型.

而secret類型有三種:

  generic: 通用類型,通常用於存儲密碼數據。
  tls:此類型僅用於存儲私鑰和證書。
  docker-registry: 若要保存docker倉庫的認證信息的話,就必須使用此種類型來創建。


#創建一個mysql-root-password的secret:
  kubectl create secret generic mysql-root-password --from-literal=password=MyP@ss.8*9
    注: 這就定義了一個generic類型的secret, 名字是mysql-root-password, key是password,值是MyP@ss.8*9

  kubectl get secret
  kubectl describe secret mysql-root-password
  kubectl get secret mysql-root-password -o yaml    #可看到password這個key的值是加密的.

#但secret的加密是一種偽加密,它僅僅是將數據做了base64的編碼.
  echo  password這個Key的值  | base64 -d    #-d:是解碼, 這樣就可以看到base64加碼后的明文密碼了。

#創建一個引用secret的Pod清單:
vim  pod-secret-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-1
  namespace: default
  labels:
     app: myapp
     tier: frontend
 annotations:
     test.com/created-by: “cluster admin”
spec:
  containers:
  -  name: myapp
     image: ikubernetes/myapp:v1
     ports:
     -  name: http
        containerPort:80
     env:
     -  name: MYSQL_ROOT_PASSWORD   #它是Pod啟動成功后,Pod中容器的環境變量名.
        valueFrom:
          secretKeyRef:
            name: mysql-root-password  #這是secret的對象名
            key: password      #它是secret中的key名

  #創建導入secret內容的Pod:
  kubectl apply -f pod-secret.yaml
  kubectl exec pod-secret-1 -- printenv |grep ‘MYSQL_ROOT_PASSWORD’    #可以看到注入到容器中的secret是明文存儲的.

擴展:
  CoreOS:
    這個組織開發了一個K8s組件,叫Operator(運維工程師),它可以讓運維工程師將一些更加復雜的處理邏輯封裝在Operator中,這樣Operator就可以幫我們完成更加復雜的任務了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM