Kubernetes進階實戰讀書筆記:配置容器應用(configmap)


一、向POD環境變量傳遞configmap對象鍵值數據

1、資源清單

[root@master chapter8]# cat cat configmap-env.yaml 
cat: cat: No such file or directory
apiVersion: v1
kind: ConfigMap
metadata:
  name: busybox-httpd-config
  namespace: default
data:
  httpd_port: "8080"
  verbose_level: "-vv"
---
apiVersion: v1
kind: Pod
metadata:
  name: configmap-env-demo
  namespace: default
spec:
  containers:
  - image: busybox
    name: busybox-httpd
    command: ["/bin/httpd"]
    args: ["-f","-p","$(HTTPD_PORT)","$(HTTPD_LOG_VERBOSE)"]
    env:
    - name: HTTPD_PORT
      valueFrom:
        configMapKeyRef:
          name: busybox-httpd-config
          key: httpd_port
    - name: HTTPD_LOG_VERBOSE
      valueFrom:
        configMapKeyRef:
          name: busybox-httpd-config
          key: verbose_level
          optional: true

2、創建及驗證

[root@master chapter8]# kubectl apply -f configmap-env.yaml 
configmap/busybox-httpd-config created
pod/configmap-env-demo created
[root@master chapter8]# kubectl get pod|grep configmap configmap-env-demo 1/1 Running 0 40s
[root@master chapter8]# kubectl exec configmap-env-demo ps aus kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead. PID USER TIME COMMAND 1 root 0:00 /bin/httpd -f -p 8080 -vv 6 root 0:00 ps aus

3、pod.spec.containers.env.valueFrom字段詳解

[root@master chapter8]# kubectl explain pod.spec.containers.env.valueFrom
KIND:     Pod
VERSION:  v1

RESOURCE: valueFrom <Object>

DESCRIPTION:
     Source for the environment variable's value. Cannot be used if value is not
     empty.

     EnvVarSource represents a source for the value of an EnvVar.

FIELDS:
   configMapKeyRef	<Object>
   #configMap對象中的特定key
     Selects a key of a ConfigMap.

   fieldRef	<Object>   #當前pod資源的指定字段、目前支持使用的字段包括metadata.name、metadata.name、metadata.namespace、metadata.labels、sepc.nodeName、spec.serviceAccount、sepc.nodeName、status.podIP、status.hostIP
     Selects a field of the pod: supports metadata.name, metadata.namespace,
     metadata.labels, metadata.annotations, spec.nodeName,
     spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.

   resourceFieldRef	<Object>  #當前容器的特定系統資源的最小值(配額)或最大值(限額)、目前支持的引用包括limits.cpu、limits.memory、limits.ephemeral-storage、requests.cpu、requests.memory、requests.ephemeral-storage
     Selects a resource of the container: only resources limits and requests
     (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu,
     requests.memory and requests.ephemeral-storage) are currently supported.

   secretKeyRef	<Object>
   #secret對象中的特定key
     Selects a key of a secret in the pod's namespace

如果鍵名中使用了連接線"-"、那么在轉換為變量名時、連接線將被自動替換為下划線"_"  

3、envfrom:直接將configmap資源中的所有鍵值一次性地完成導入

1、資源清單

[root@master chapter8]# cat configmap-envfrom-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: configmap-envfrom-demo
  namespace: default
spec:
  containers:
  - image: busybox
    name: busybox-httpd
    command: ["/bin/httpd"]
    args: ["-f","-p","$(HTCFG_httpd_port)","$(HTCFG_verbose_level)"]
    envFrom:
    - prefix: HTCFG_
      configMapRef:
        name: busybox-httpd-config
        optional: false

2、創建驗證

[root@master chapter8]# kubectl apply -f configmap-envfrom-pod.yaml 
pod/configmap-envfrom-demo created
[root@master chapter8]# kubectl get pod|grep configmap
configmap-env-demo       1/1     Running             0          3m46s
configmap-envfrom-demo   1/1     Running             0          30s
[root@master chapter8]# kubectl exec configmap-envfrom-demo printenv
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=configmap-envfrom-demo
HTCFG_verbose_level=-vv
HTCFG_httpd_port=8080
......

二、configmap存儲卷

1、掛載整個存儲卷  

資源清單

[root@master chapter8]# cat configmap-volume-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-demo
  namespace: default
spec:
  containers:
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: ngxconfig
      mountPath: /etc/nginx/conf.d/
      readOnly: true
  volumes:
  - name: ngxconfig
    configMap:
      name: nginx-config-files

創建

[root@master chapter8]# kubectl apply -f configmap-volume-pod.yaml 
pod/configmap-volume-demo created

[root@master chapter8]# kubectl get cm
NAME                   DATA   AGE
busybox-httpd-config   2      19h
nginx-config-files     3      7s
special-config         2      23h

[root@master chapter8]# kubectl get pod|grep configmap-volume-demo
configmap-volume-demo    1/1     Running            0          11m

2、驗證掛載整個存儲卷

[root@master chapter8]# POD_IP=$(kubectl get pods configmap-volume-demo  -o go-template={{.status.podIP}})
[root@master chapter8]# curl http://${POD_IP}:8080/nginx-status
Active connections: 1
server accepts handled requests
 8 8 8 
Reading: 0 Writing: 1 Waiting: 0 
[root@master chapter8]# kubectl exec configmap-volume-demo ls /etc/nginx/conf.d/ kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead. myserver-gzip.cfg myserver-status.cfg myserver.conf [root@master chapter8]# kubectl exec configmap-volume-demo -- nginx -T 2020/09/02 02:09:44 [warn] 28#28: duplicate MIME type "text/html" in /etc/nginx/conf.d/myserver-gzip.cfg:4 nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/conf.d/myserver-gzip.cfg:4 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok # configuration file /etc/nginx/nginx.conf: user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; } # configuration file /etc/nginx/mime.types: types { text/html html htm shtml; text/css css; ...... } # configuration file /etc/nginx/conf.d/myserver.conf: server { listen 8080; server_name www.ikubernetes.io; include /etc/nginx/conf.d/myserver-*.cfg; location / { root /usr/share/nginx/html; } } # configuration file /etc/nginx/conf.d/myserver-gzip.cfg: gzip on; gzip_comp_level 5; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/html text/css application/xml text/javascript; # configuration file /etc/nginx/conf.d/myserver-status.cfg: location /nginx-status { stub_status on; access_log off; } nginx: configuration file /etc/nginx/nginx.conf test is successful

 由上面兩個命令的結果可見、nginx-config-files中的三個文件都被添加到了容器中、並且實現了由容器應用nginx加載並生效

3、掛在存儲卷重的部分鍵值

資源清單

[root@master chapter8]# cat configmap-volume-pod-2.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-demo-2
  namespace: default
spec:
  containers:
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: ngxconfig
      mountPath: /etc/nginx/conf.d/
      readOnly: true
  volumes:
  - name: ngxconfig
    configMap:
      name: nginx-config-files
      items:
      - key: myserver.conf
        path: myserver.conf
        mode: 0644
      - key: myserver-gzip.cfg
        path: myserver-compression.cfg

4、pod.spec.volumes.configMap.items字段詳解

[root@master chapter8]# kubectl explain pod.spec.volumes.configMap.items
KIND:     Pod
VERSION:  v1

RESOURCE: items <[]Object>

DESCRIPTION:
     If unspecified, each key-value pair in the Data field of the referenced
     ConfigMap will be projected into the volume as a file whose name is the key
     and content is the value. If specified, the listed keys will be projected
     into the specified paths, and unlisted keys will not be present. If a key
     is specified which is not present in the ConfigMap, the volume setup will
     error unless it is marked optional. Paths must be relative and may not
     contain the '..' path or start with '..'.

     Maps a string key to a path within a volume.

FIELDS:
   key	<string> -required-
   #要引用的鍵名稱、必選字段
     The key to project.

   mode	<integer>
   #文件的權限模型、可用范圍為0到0777
     Optional: mode bits to use on this file, must be a value between 0 and
     0777. If not specified, the volume defaultMode will be used. This might be
     in conflict with other options that affect the file mode, like fsGroup, and
     the result can be other mode bits set.

   path	<string> -required-
   #對應的鍵於掛載點目錄中生成的文件的相對路徑、可以不同與鍵名稱、必選字段
     The relative path of the file to map the key to. May not be an absolute
     path. May not contain the path element '..'. May not start with the string
     '..'.

上面的配置示例中myserver-gzip.cfg映射成了myserver-compression.cfg文件、而myserver.conf則保持了與鍵名同名、並明確指定使用0644的權限從而達成了僅裝載部分文件至容器之目的

5、獨立掛在存儲卷重中的鍵值

1、資源清單

[root@master chapter8]# cat configmap-volume-pod-3.yaml
apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-demo-3
  namespace: default
spec:
  containers:
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: ngxconfig
      mountPath: /etc/nginx/conf.d/myserver.conf
      subPath: myserver.conf
      readOnly: true
    - name: ngxconfig
      mountPath: /etc/nginx/conf.d/myserver-status.cfg
      subPath: myserver-status.cfg
      readOnly: true
  volumes:
  - name: ngxconfig
    configMap:
      name: nginx-config-files

2、創建驗證

[root@master chapter8]# kubectl apply -f configmap-volume-pod-3.yaml 
pod/configmap-volume-demo-3 created
[root@master chapter8]# kubectl exec configmap-volume-demo-3  ls /etc/nginx/conf.d
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
default.conf
myserver-status.cfg
myserver.conf

三、容器應用重載新配置

1、使用configmap的優勢

相較於環境變量來說、使用configmap資源為容器應用提供配置的優勢之一在於其支持容器應用動態更新其配置:用戶直接更新configmap對象、然后由容器應用重載其配置文件即可

[root@master chapter8]# kubectl exec -it configmap-volume-demo -- ls -lA /etc/nginx/conf.d
total 0
drwxr-xr-x 2 root root 79 Sep 2 02:00 ..2020_09_02_02_00_39.612704422
lrwxrwxrwx 1 root root 31 Sep 2 02:00 ..data -> ..2020_09_02_02_00_39.612704422
lrwxrwxrwx 1 root root 24 Sep 2 02:00 myserver-gzip.cfg -> ..data/myserver-gzip.cfg
lrwxrwxrwx 1 root root 26 Sep 2 02:00 myserver-status.cfg -> ..data/myserver-status.cfg
lrwxrwxrwx 1 root root 20 Sep 2 01:59 myserver.conf -> ..data/myserver.conf

細心的讀者或許已經發現、掛在configmap存儲卷的掛載點目錄中的文件是符號鏈接,它們指向了當前目錄中"..data"而"..data" 也是符號鏈接、它只指向了名字形如"..2020_09_02_02_00_39.612704422"的目錄、這個目錄才是存儲卷的真正掛載點

2、兩級符號鏈接設定的好處

在引用的configmap對象中的數據發生改變時、它將被被重新掛在至一個新的數據臨時目錄下,而后"..data"將指向此新的掛載點、便達到了同時更新存儲卷上下文件數據之目的例如用:kubectl edit cm nginx-config-files編輯如下內容:

[root@master chapter8]# kubectl edit cm nginx-config-files
configmap/nginx-config-files edited

修改后查看

[root@master chapter8]# kubectl exec -it configmap-volume-demo -- ls -lA /etc/nginx/conf.d
total 0
drwxr-xr-x    2 root     root            79 Sep  2 03:35 ..2020_09_02_03_35_24.756696013
lrwxrwxrwx    1 root     root            31 Sep  2 03:35 ..data -> ..2020_09_02_03_35_24.756696013
lrwxrwxrwx    1 root     root            24 Sep  2 02:00 myserver-gzip.cfg -> ..data/myserver-gzip.cfg
lrwxrwxrwx    1 root     root            26 Sep  2 02:00 myserver-status.cfg -> ..data/myserver-status.cfg
lrwxrwxrwx    1 root     root            20 Sep  2 01:59 myserver.conf -> ..data/myserver.conf

重載nginx服務

[root@master chapter8]# kubectl exec configmap-volume-demo -- nginx -s reload
2020/09/02 03:36:35 [warn] 77#77: duplicate MIME type "text/html" in /etc/nginx/conf.d/myserver-gzip.cfg:4
nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/conf.d/myserver-gzip.cfg:4
2020/09/02 03:36:35 [notice] 77#77: signal process started

此時、如果於容器之外的位置訪問/nginx-status頁面的請求時被拒絕的、則表明新配置已然生效,如下面的命令及其結果所示

[root@master chapter8]# curl http://${POD_IP}:8080/nginx-status
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.19.2</center>
</body>
</html>

然而、需要注意的是、對於不支持配置文件重載操作的容器應用來說、只有那些在configmap對象更新后創建的POD資源中的容器會應用到新配置、此時如果不重啟舊有的容器、則會導致配置不一致的問題,即使對於支持重載操作的應用來說,由於新的配置信息並非同步推送進所有的容器中、而且各容器的重載操作也未必能同時進行、因此在更新時、短時間內仍然存在配置不一致的現象

另外使用獨立掛在存儲卷重的文件的容器、其掛在配置文件的方式並非以兩級鏈接的方式、因此存儲卷無法確保所有的掛載的文件可以被同事更新至容器中
因此為了確保配置信息的一致性、目前這種類型的掛在不支持文件更新操作

四、使用configmap資源的注意事項

在POD資源中調用configmap兌現更需要注意以下幾個問題:

1、以存儲卷方式引用的configmap必須事先於pod存在、除非在pod中將他們全部標記為"optional"否則將會導致pod無法正常啟動的錯誤;同樣、即使存在configmap、在引用的鍵不存在時,也會導致一樣的錯誤

2、當以環境變量方式注入的configmap中的鍵不存在時會被忽略、pod可以正常啟動、但錯誤引用的信息會以"lnvalidVariableNames"事件記錄與日志中

3、configmap是名稱空間級的資源、因此、引用它的pod必須處於同一名稱空間中

4、kubectl不支持引用kubernetes API server 上存在的configmap、這些包括那些通過kubectl的"--manifest-url"或"--config"選項、以及kubectl REST API創建的pod


免責聲明!

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



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