Kubernetes利用Volume掛載ConfigMap與Secret

人艰不拆_zmc發表於2024-09-01

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

  Kubernetes允許你將ConfigMap和Secret作為Volume掛載到Pod中,這樣容器就可以直接訪問到這些配置資訊或敏感資料了。這種方式的好處是,支援動態更新。ConfigMap和Secret更新後,容器中的資料也會更新。
  下面以nginx容器映象為例演示,利用Volume掛載ConfigMap與Secret。

2.1 不掛載任何儲存卷

(1)使用Nginx容器映象的工作負載示例如下,沒有掛載任何型別儲存卷。
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掛載在容器中,則不會覆蓋掉原目錄下的其他檔案。

相關文章