1、概述
在Kubernetes叢集中,應用的配置管理是一個關鍵且複雜的任務。隨著應用的擴充套件和微服務架構的普及,傳統的配置檔案管理方式已經難以滿足動態、靈活的配置需求。幸運的是,Kubernetes提供了強大的配置管理能力,其中ConfigMap和Secret結合Volume掛載的方式是實現這一目標的重要手段。
1.1 ConfigMap
ConfigMap是Kubernetes中的一個API物件,用於儲存非敏感的配置資訊,如應用的配置引數、環境變數等。它允許你將配置資訊與應用的容器映象解耦,從而更容易地管理和更新配置。
1.2 Secret
與ConfigMap類似,Secret也是Kubernetes中的一個API物件,但它用於儲存敏感資訊,如資料庫密碼、OAuth令牌等。Secret透過Base64編碼儲存資料,但Kubernetes在將Secret掛載到Pod中時會自動進行解碼,以確保資料的安全性。詳細Secret資源講解請參見《Kubernetes物件——Secret 》這篇博文。
2、利用Volume掛載ConfigMap與Secret
2.1 不掛載任何儲存卷
apiVersion: apps/v1 kind: Deployment metadata: namespace: test-configmap-volume labels: app: nginx-v1 name: nginx-v1 spec: replicas: 1 selector: matchLabels: app: nginx-v1 template: metadata: labels: app: nginx-v1 spec: containers: - name: container-jzx3ih imagePullPolicy: IfNotPresent image: 'nginx' ports: - name: tcp-80 protocol: TCP containerPort: 80 serviceAccount: default affinity: {} initContainers: [] volumes: [] strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 25% maxSurge: 25%
(2)進入容器內部,可以看到使用nginx容器映象啟動nginx容器後,/etc/ssl目錄下是存在資料檔案的。
2.2 掛載ConfigMap
建立測試用的configmap。
apiVersion: v1 kind: ConfigMap metadata: namespace: test-configmap-volume labels: {} name: test-configmap-volume1 spec: template: metadata: labels: {} data: a: aa b: bb c: cc
2.2.1 將整個configmap資源物件掛載到容器內部
更新nginx-v1工作負載配置檔案,將測試用的configmap資源物件掛載到nginx容器/etc/ssl目錄下。
kind: Deployment apiVersion: apps/v1 metadata: name: nginx-v1 namespace: test-configmap-volume labels: app: nginx-v1 annotations: deployment.kubernetes.io/revision: '2' spec: replicas: 1 selector: matchLabels: app: nginx-v1 template: metadata: creationTimestamp: null labels: app: nginx-v1 spec: volumes: - name: volume-pikzy0 configMap: name: test-configmap-volume1 defaultMode: 420 containers: - name: container-jzx3ih image: 'nginx' ports: - name: tcp-80 containerPort: 80 protocol: TCP resources: {} volumeMounts: - name: volume-pikzy0 readOnly: true mountPath: /etc/ssl terminationMessagePath: /dev/termination-log terminationMessagePolicy: File imagePullPolicy: IfNotPresent restartPolicy: Always terminationGracePeriodSeconds: 30 dnsPolicy: ClusterFirst serviceAccountName: default serviceAccount: default securityContext: {} affinity: {} schedulerName: default-scheduler strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 25% maxSurge: 25% revisionHistoryLimit: 10 progressDeadlineSeconds: 600
再次進入容器/etc/ssl目錄下,結果如下。
當ConfigMap以volume的形式掛載到容器中的指定路徑時,如果目標路徑在容器中不存在,Kubernetes會在容器啟動時自動建立這個路徑。如果目標路徑已經存在於容器中,ConfigMap預設會會覆蓋原先目錄下的內容(除非使用子路徑),並且ConfigMap的每個key都會被建立為該目錄下的一個新檔案(檔名與key相同)。
2.2.2 將configmap資源物件指定key掛載到容器內部
更新nginx-v1工作負載配置檔案,將測試用的configmap資源物件指定key掛載到nginx容器/etc/ssl目錄下。(將key a、b掛載到容器/etc/ssl路徑下並且a的檔名改為haa,b的檔名改成hbb)
...... spec: volumes: - name: volume-pikzy0 configMap: name: test-configmap-volume1 items: - key: a path: haa - key: b path: hbb defaultMode: 420 containers: - name: container-jzx3ih image: 'nginx' ports: - name: tcp-80 containerPort: 80 protocol: TCP resources: {} volumeMounts: - name: volume-pikzy0 readOnly: true mountPath: /etc/ssl terminationMessagePath: /dev/termination-log terminationMessagePolicy: File imagePullPolicy: IfNotPresent restartPolicy: Always .......
結果如下:
當ConfigMap將指定key以volume的形式掛載到容器中的指定路徑時,如果目標路徑在容器中不存在,Kubernetes會在容器啟動時自動建立這個路徑。如果目標路徑已經存在於容器中,ConfigMap預設會會覆蓋原先目錄下的內容(除非使用子路徑),這些key都會被建立為該目錄下的一個新檔案(檔名與path相同)。
2.2.3 將configmap資源物件透過子路徑掛載到容器內部
不管是將整個configmap資源物件掛載到容器內部,還是將configmap資源物件指定key掛載到容器內部,如果目標路徑已經存在於容器中,ConfigMap預設會會覆蓋原先目錄下的內容。有時候我們就想覆蓋原先目錄下指定檔案,這時候就需要使用子路徑,使用subpath選定configMap的指定的key-value掛載在容器中,不會覆蓋掉原目錄下的其他檔案。
更新nginx-v1工作負載配置檔案,將測試用的configmap資源物件指定key a透過子路徑覆蓋容器/etc/ssl/openssl.cnf檔案。
....... spec: volumes: - name: volume-pikzy0 configMap: name: test-configmap-volume1 defaultMode: 420 containers: - name: container-jzx3ih image: 'nginx' ports: - name: tcp-80 containerPort: 80 protocol: TCP resources: {} volumeMounts: - name: volume-pikzy0 readOnly: true mountPath: /etc/ssl/openssl.cnf subPath: a terminationMessagePath: /dev/termination-log terminationMessagePolicy: File imagePullPolicy: IfNotPresent .......
結果如下:
透過使用subpath選定configMap的指定的key-value掛載在容器中,不會覆蓋掉原目錄下的其他檔案。
2.3 掛載Secret
詳細步驟參見《Kubernetes物件——Secret 》這篇博文,本文不再贅餘,使用方式和掛載ConfigMap一致。
3、總結
Kubernetes允許你將ConfigMap和Secret作為Volume掛載到Pod中,這樣容器就可以直接訪問到這些配置資訊或敏感資料了。這種方式的好處是,支援動態更新。ConfigMap和Secret更新後,容器中的資料也會更新。
(1)將整個ConfigMap/Secret資源物件掛載到容器內部
當ConfigMap/Secret以Volume的形式掛載到容器中的指定路徑時,如果目標路徑在容器中不存在,Kubernetes會在容器啟動時自動建立這個路徑。如果目標路徑已經存在於容器中,ConfigMap預設會會覆蓋原先目錄下的內容,並且ConfigMap的每個key都會被建立為該目錄下的一個新檔案(檔名與key相同)。
(2)將ConfigMap/Secret資源物件指定key掛載到容器內部
當ConfigMap/Secret將指定key以Volume的形式掛載到容器中的指定路徑時,如果目標路徑在容器中不存在,Kubernetes會在容器啟動時自動建立這個路徑。如果目標路徑已經存在於容器中,ConfigMap預設會會覆蓋原先目錄下的內容,這些key都會被建立為該目錄下的一個新檔案(檔名與path相同)。
(3)將ConfigMap/Secret資源物件透過子路徑掛載到容器內部
如果掛載路徑是一個已存在的目錄,則目錄下的內容不會被覆蓋。直接將ConfigMap/Secret掛載在容器的路徑,會覆蓋掉容器路徑下原有的檔案,使用subpath選定ConfigMap/Secret的指定的key-value掛載在容器中,則不會覆蓋掉原目錄下的其他檔案。