kubernetes實踐之六十二:Secret 使用

百聯達發表於2018-06-21
一: 簡介
Secret 可以作為資料卷被掛載,或作為環境變數暴露出來以供 pod 中的容器使用。它們也可以被系統的其他部分使用,而不直接暴露在 pod 內。例如,它們可以儲存憑據,系統的其他部分應該用它來代表您與外部系統進行互動。

Secret舉例:

點選(此處)摺疊或開啟

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4.   name: mysecret
  5. type: Opaque
  6. data:
  7.   username: YWRtaW4=
  8.   password: MWYyZDFlMmU2N2Rm

二:在 Pod 中使用 Secret 檔案

1.建立一個 secret 或者使用已有的 secret。多個 pod 可以引用同一個 secret。

2.修改您的 pod 的定義在 spec.volumes[] 下增加一個 volume。可以給這個 volume 隨意命名,它的 spec.volumes[].secret.secretName 必須等於 secret 物件的名字。

3.將 spec.containers[].volumeMounts[] 加到需要用到該 secret 的容器中。指定 spec.containers[].volumeMounts[].readOnly = true 和 spec.containers[].volumeMounts[].mountPath 為您想要該 secret 出現的尚未使用的目錄。

4.修改您的映象並且/或者命令列讓程式從該目錄下尋找檔案。Secret 的 data 對映中的每一個鍵都成為了 mountPath 下的一個檔名。

點選(此處)摺疊或開啟

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4.   name: mypod
  5. spec:
  6.   containers:
  7.   - name: mypod
  8.     image: redis
  9.     volumeMounts:
  10.     - name: foo
  11.       mountPath: "/etc/foo"
  12.       readOnly: true
  13.   volumes:
  14.   - name: foo
  15.     secret:
  16.       secretName: mysecret
您想要用的每個 secret 都需要在 spec.volumes 中指明。如果 pod 中有多個容器,每個容器都需要自己的 volumeMounts 配置塊,但是每個 secret 只需要一個 spec.volumes。
您可以打包多個檔案到一個 secret 中,或者使用的多個 secret,怎樣方便就怎樣來.

三:向特性路徑對映 secret 金鑰

我們還可以控制 Secret key 對映在 volume 中的路徑。您可以使用 spec.volumes[].secret.items 欄位修改每個 key 的目標路徑:

點選(此處)摺疊或開啟

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4.   name: mypod
  5. spec:
  6.   containers:
  7.   - name: mypod
  8.     image: redis
  9.     volumeMounts:
  10.     - name: foo
  11.       mountPath: "/etc/foo"
  12.       readOnly: true
  13.   volumes:
  14.   - name: foo
  15.     secret:
  16.       secretName: mysecret
  17.       items:
  18.       - key: username
  19.         path: my-group/my-username
1.username secret 儲存在 /etc/foo/my-group/my-username 檔案中而不是 /etc/foo/username 中。
2.password secret 沒有被影射

如果使用了 spec.volumes[].secret.items,只有在 items 中指定的 key 被影射。要使用 secret 中所有的 key,所有這些都必須列在 items 欄位中。所有列出的金鑰必須存在於相應的 secret 中。否則,不會建立卷。

四:Secret 檔案許可權
您還可以指定 secret 將擁有的許可權模式位檔案。如果不指定,預設使用 0644。您可以為整個保密卷指定預設模式,如果需要,可以覆蓋每個金鑰。

點選(此處)摺疊或開啟

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4.   name: mypod
  5. spec:
  6.   containers:
  7.   - name: mypod
  8.     image: redis
  9.     volumeMounts:
  10.     - name: foo
  11.       mountPath: "/etc/foo"
  12.   volumes:
  13.   - name: foo
  14.     secret:
  15.       secretName: mysecret
  16.       defaultMode: 256
然後,secret 將被掛載到 /etc/foo 目錄,所有透過該 secret volume 掛載建立的檔案的許可權都是 0400。
請注意,JSON 規範不支援八進位制符號,因此使用 256 值作為 0400 許可權。如果您使用 yaml 而不是 json 作為 pod,則可以使用八進位制符號以更自然的方式指定許可權。

五:從 Volume 中消費 secret 值
在掛載的 secret volume 的容器內,secret key 將作為檔案,並且 secret 的值使用 base-64 解碼並儲存在這些檔案中。這是在上面的示例容器內執行的命令的結果:

點選(此處)摺疊或開啟

  1. $ ls /etc/foo/
  2. username
  3. password
  4. $ cat /etc/foo/username
  5. admin
  6. $ cat /etc/foo/password
  7. 1f2d1e2e67df
六:掛載的 secret 被自動更新
當已經在 volume 中消被消費的 secret 被更新時,被對映的 key 也將被更新。Kubelet 在週期性同步時檢查被掛載的 secret 是不是最新的。但是,它正在使用其基於本地 ttl 的快取來獲取當前的 secret 值。結果是,當 secret 被更新的時刻到將新的 secret 對映到 pod 的時刻的總延遲可以與 kubelet 中的secret 快取的 kubelet sync period + ttl 一樣長。

:Secret 作為環境變數
1.建立一個 secret 或者使用一個已存在的 secret。多個 pod 可以引用同一個 secret。
2.在每個容器中修改您想要使用 secret key 的 Pod 定義,為要使用的每個 secret key 新增一個環境變數。消費secret key 的環境變數應填充 secret 的名稱,並鍵入 env[x].valueFrom.secretKeyRef。
3.修改映象或者命令列,以便程式在指定的環境變數中查詢值。

點選(此處)摺疊或開啟

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4.   name: secret-env-pod
  5. spec:
  6.   containers:
  7.   - name: mycontainer
  8.     image: redis
  9.     env:
  10.       - name: SECRET_USERNAME
  11.         valueFrom:
  12.           secretKeyRef:
  13.             name: mysecret
  14.             key: username
  15.       - name: SECRET_PASSWORD
  16.         valueFrom:
  17.           secretKeyRef:
  18.             name: mysecret
  19.             key: password
  20.   restartPolicy: Never
消費環境變數裡的 Secret 值
在一個消耗環境變數 secret 的容器中,secret key 作為包含 secret 資料的 base-64 解碼值的常規環境變數。這是從上面的示例在容器內執行的命令的結果:

點選(此處)摺疊或開啟

  1. $ echo $SECRET_USERNAME
  2. admin
  3. $ echo $SECRET_PASSWORD
  4. 1f2d1e2e67df
九:使用 imagePullSecret
imagePullSecret 是將包含 Docker(或其他)映象登錄檔密碼的 secret 傳遞給 Kubelet 的一種方式,因此可以代表您的 pod 拉取私有映象。

:使用Secret的限制
1.驗證 secret volume 來源確保指定的物件引用實際上指向一個型別為 Secret 的物件。因此,需要在依賴於它的任何 pod 之前建立一個 secret。
2.Secret API 物件駐留在名稱空間中。它們只能由同一名稱空間中的 pod 引用。
3.個 secret 的大小限制為1MB。這是為了防止建立非常大的 secret 會耗盡 apiserver 和 kubelet 的記憶體。然而,建立許多較小的 secret 也可能耗盡記憶體。更全面得限制 secret 對記憶體使用的更全面的限制是計劃中的功能。
4.Kubelet 僅支援從 API server 獲取的 Pod 使用 secret。這包括使用 kubectl 建立的任何 pod,或間接透過 replication controller 建立的 pod。它不包括透過 kubelet --manifest-url 標誌,其 --config 標誌或其 REST API 建立的pod(這些不是建立 pod 的常用方法)。
5.必須先建立 secret,除非將它們標記為可選項,否則必須在將其作為環境變數在 pod 中使用之前建立 secret。對不存在的 secret 的引用將阻止其啟動。
6.透過 secretKeyRef 對不存在於命名的 key 中的 key 進行引用將阻止該啟動。
7.用於透過 envFrom 填充環境變數的 secret,這些環境變數具有被認為是無效環境變數名稱的 key 將跳過這些鍵。該 pod 將被允許啟動。將會有一個事件,其原因是 InvalidVariableNames,該訊息將包含被跳過的無效鍵的列表。該示例顯示一個 pod,它指的是包含2個無效鍵,1badkey 和 2alsobad 的預設/mysecret ConfigMap。

十一: Secret 與 Pod 生命週期的聯絡
透過 API 建立的 Pod 時,不會檢查應用的 secret 是否存在。一旦 Pod 被排程,kubelet 就會嘗試獲取該 secret 的值。如果獲取不到該 secret,或者暫時無法與 API server 建立連線,kubelet 將會定期重試。Kubelet 將會報告關於 pod 的事件,並解釋它無法啟動的原因。一旦獲取的 secret,kubelet將建立並裝載一個包含它的卷。在安裝所有pod的卷之前,都不會啟動 pod 的容器。





來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28624388/viewspace-2156450/,如需轉載,請註明出處,否則將追究法律責任。

相關文章