密文

密文是一個物件,其中包含少量敏感資料,例如密碼、權杖或金鑰。這類資訊否則可能會放在 Pod 規格或 容器映像檔中。使用密文表示您不需要在應用程式程式碼中包含機密資料。

由於密文可以獨立於使用它們的 Pod 建立,因此在建立、檢視與編輯 Pod 的工作流程期間,密文 (及其資料) 暴露的風險較低。Kubernetes 與在叢集中執行的應用程式也可以對密文採取額外的預防措施,例如避免將敏感資料寫入非揮發性儲存裝置。

密文與 ConfigMaps 類似,但專門用於保存機密資料。

如需更多詳細資訊,請參閱密文的資訊安全

密文的用途

您可以將密文用於以下用途,例如

Kubernetes 控制平面也使用 Secret;例如,啟動引導權杖 Secret 是一種有助於自動化節點註冊的機制。

使用案例:Secret Volume 中的點檔案

你可以透過定義一個以點開頭的鍵,使你的資料成為「隱藏」。這個鍵代表一個點檔案或「隱藏」檔案。例如,當以下 Secret 掛載到一個 Volume,secret-volume 時,該 Volume 將包含一個名為 .secret-file 的單一檔案,而 dotfile-test-container 將在路徑 /etc/secret-volume/.secret-file 中找到此檔案。

apiVersion: v1
kind: Secret
metadata:
  name: dotfile-secret
data:
  .secret-file: dmFsdWUtMg0KDQo=
---
apiVersion: v1
kind: Pod
metadata:
  name: secret-dotfiles-pod
spec:
  volumes:
    - name: secret-volume
      secret:
        secretName: dotfile-secret
  containers:
    - name: dotfile-test-container
      image: registry.k8s.io/busybox
      command:
        - ls
        - "-l"
        - "/etc/secret-volume"
      volumeMounts:
        - name: secret-volume
          readOnly: true
          mountPath: "/etc/secret-volume"

使用案例:Secret 對 Pod 中的一個容器可見

考慮一個需要處理 HTTP 請求、執行一些複雜的業務邏輯,然後用 HMAC 簽署一些訊息的程式。由於它具有複雜的應用程式邏輯,伺服器中可能存在未被注意到的遠端檔案讀取漏洞,這可能會將私密金鑰暴露給攻擊者。

這可以分為兩個容器中的兩個程序:一個前端容器,它處理使用者互動和業務邏輯,但看不到私密金鑰;以及一個簽署者容器,它可以看見私密金鑰,並回應來自前端的簡單簽署請求(例如,透過 localhost 網路)。

透過這種分割方法,攻擊者現在必須誘騙應用程式伺服器執行一些相當隨意的事情,這可能比讓它讀取檔案更困難。

Secret 的替代方案

除了使用 Secret 來保護機密資料外,你可以從替代方案中選擇。

以下是一些選項

  • 如果你的雲原生組件需要向另一個你知道在同一個 Kubernetes 叢集中執行的應用程式進行身份驗證,你可以使用 ServiceAccount 及其權杖來識別你的用戶端。
  • 有一些第三方工具可以執行,無論是在叢集內部還是外部,用於管理敏感資料。例如,一個 Pod 可以透過 HTTPS 存取的服務,如果用戶端正確地進行身份驗證(例如,使用 ServiceAccount 權杖),則會揭露 Secret。
  • 對於身份驗證,你可以為 X.509 憑證實作一個自訂簽署者,並使用 CertificateSigningRequests 讓該自訂簽署者向需要憑證的 Pod 發放憑證。
  • 你可以使用 裝置外掛程式 將節點本地加密硬體暴露給特定的 Pod。例如,你可以將受信任的 Pod 排程到提供可信賴平台模組(Trusted Platform Module,TPM)的節點上,並進行頻外組態。

你也可以結合其中兩個或多個選項,包括使用 Secret 物件本身的選項。

例如:實作(或部署)一個 Operator,它從外部服務提取短效期會話權杖,然後基於這些短效期會話權杖建立 Secret。在你叢集中執行的 Pod 可以使用會話權杖,而 Operator 確保它們有效。這種分離意味著你可以執行不知道發放和刷新這些會話權杖的確切機制的 Pod。

Secret 的類型

建立 Secret 時,你可以使用 Secret 資源的 type 欄位,或某些等效的 kubectl 命令列標記(如果可用),來指定其類型。Secret 類型用於促進對 Secret 資料的程式化處理。

Kubernetes 為一些常見的使用情境提供了幾種內建類型。這些類型在執行的驗證和 Kubernetes 對它們施加的約束方面有所不同。

內建類型用途
不透明 (Opaque)任意使用者定義的資料
kubernetes.io/service-account-tokenServiceAccount 權杖
kubernetes.io/dockercfg序列化的 ~/.dockercfg 檔案
kubernetes.io/dockerconfigjson序列化的 ~/.docker/config.json 檔案
kubernetes.io/basic-auth基本身份驗證的憑證
kubernetes.io/ssh-authSSH 身份驗證的憑證
kubernetes.io/tlsTLS 用戶端或伺服器的資料
bootstrap.kubernetes.io/token啟動引導權杖資料

你可以透過為 Secret 物件指定一個非空字串作為 type 值(空字串被視為 Opaque 類型)來定義和使用你自己的 Secret 類型。

Kubernetes 不對類型名稱施加任何約束。但是,如果你正在使用其中一種內建類型,你必須滿足為該類型定義的所有要求。

如果你正在定義一種用於公開用途的 Secret 類型,請遵循慣例並建構 Secret 類型,使其類型名稱在名稱之前加上你的網域名稱,並以 / 分隔。例如:cloud-hosting.example.net/cloud-api-credentials

不透明 (Opaque) Secret

如果你未在 Secret 清單中明確指定類型,則 Opaque 是預設的 Secret 類型。當你使用 kubectl 建立 Secret 時,你必須使用 generic 子命令來指示 Opaque Secret 類型。例如,以下命令建立一個 Opaque 類型的空 Secret

kubectl create secret generic empty-secret
kubectl get secret empty-secret

輸出看起來像這樣

NAME           TYPE     DATA   AGE
empty-secret   Opaque   0      2m6s

DATA 欄顯示儲存在 Secret 中的資料項目數量。在這種情況下,0 表示你已建立一個空的 Secret。

ServiceAccount 權杖 Secret

kubernetes.io/service-account-token 類型的 Secret 用於儲存權杖憑證,該權杖憑證識別 ServiceAccount。這是一種傳統機制,它為 Pod 提供長期有效的 ServiceAccount 憑證。

在 Kubernetes v1.22 及更高版本中,建議的方法是改用 TokenRequest API 來取得短效期、自動輪換的 ServiceAccount 權杖。你可以使用以下方法取得這些短效期權杖

  • 直接呼叫 TokenRequest API 或使用像 kubectl 這樣的 API 用戶端。例如,你可以使用 kubectl create token 命令。
  • 在你的 Pod 清單中的 投射 Volume 中請求掛載的權杖。Kubernetes 建立權杖並將其掛載在 Pod 中。當掛載權杖的 Pod 被刪除時,權杖會自動失效。有關詳細資訊,請參閱 使用 Service Account 權杖投射啟動 Pod

當使用此 Secret 類型時,你需要確保 kubernetes.io/service-account.name 註解設定為現有的 ServiceAccount 名稱。如果你要同時建立 ServiceAccount 和 Secret 物件,你應該先建立 ServiceAccount 物件。

在 Secret 建立後,Kubernetes 控制器 會填寫一些其他欄位,例如 kubernetes.io/service-account.uid 註解,以及 data 欄位中的 token 鍵,該鍵會填入身份驗證權杖。

以下範例組態宣告了一個 ServiceAccount 權杖 Secret

apiVersion: v1
kind: Secret
metadata:
  name: secret-sa-sample
  annotations:
    kubernetes.io/service-account.name: "sa-name"
type: kubernetes.io/service-account-token
data:
  extra: YmFyCg==

建立 Secret 後,請等待 Kubernetes 在 data 欄位中填入 token 鍵。

有關 ServiceAccount 如何運作的更多資訊,請參閱 ServiceAccount 文件。你也可以查看 PodautomountServiceAccountToken 欄位和 serviceAccountName 欄位,以取得有關從 Pod 內部參照 ServiceAccount 憑證的資訊。

Docker 組態 Secret

如果你正在建立 Secret 以儲存用於存取容器映像檔儲存庫的憑證,你必須為該 Secret 使用以下 type 值之一

  • kubernetes.io/dockercfg:儲存序列化的 ~/.dockercfg,這是組態 Docker 命令列的舊格式。Secret 的 data 欄位包含一個 .dockercfg 鍵,其值是以 base64 編碼的 ~/.dockercfg 檔案的內容。
  • kubernetes.io/dockerconfigjson:儲存序列化的 JSON,其格式規則與 ~/.docker/config.json 檔案相同,這是 ~/.dockercfg 的新格式。Secret 的 data 欄位必須包含一個 .dockerconfigjson 鍵,其值是以 base64 編碼的 ~/.docker/config.json 檔案的內容。

以下是 kubernetes.io/dockercfg 類型 Secret 的範例

apiVersion: v1
kind: Secret
metadata:
  name: secret-dockercfg
type: kubernetes.io/dockercfg
data:
  .dockercfg: |
    eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUvdjEvIjp7ImF1dGgiOiJvcGVuc2VzYW1lIn19fQo=    

當你使用清單建立 Docker 組態 Secret 時,API 伺服器會檢查預期的鍵是否存在於 data 欄位中,並驗證所提供的值是否可以解析為有效的 JSON。API 伺服器不會驗證 JSON 實際上是否為 Docker 組態檔案。

你也可以使用 kubectl 建立用於存取容器儲存庫的 Secret,例如當你沒有 Docker 組態檔案時

kubectl create secret docker-registry secret-tiger-docker \
  --docker-email=tiger@acme.example \
  --docker-username=tiger \
  --docker-password=pass1234 \
  --docker-server=my-registry.example:5000

此命令建立一個 kubernetes.io/dockerconfigjson 類型的 Secret。

從該新 Secret 中檢索 .data.dockerconfigjson 欄位並解碼資料

kubectl get secret secret-tiger-docker -o jsonpath='{.data.*}' | base64 -d

輸出等效於以下 JSON 文件(這也是一個有效的 Docker 組態檔案)

{
  "auths": {
    "my-registry.example:5000": {
      "username": "tiger",
      "password": "pass1234",
      "email": "tiger@acme.example",
      "auth": "dGlnZXI6cGFzczEyMzQ="
    }
  }
}

基本身份驗證 Secret

提供 kubernetes.io/basic-auth 類型是為了儲存基本身份驗證所需的憑證。當使用此 Secret 類型時,Secret 的 data 欄位必須包含以下兩個鍵之一

  • username:用於身份驗證的使用者名稱
  • password:用於身份驗證的密碼或權杖

上述兩個鍵的值都是 base64 編碼的字串。你也可以選擇在 Secret 清單中使用 stringData 欄位來提供明文內容。

以下清單是基本身份驗證 Secret 的範例

apiVersion: v1
kind: Secret
metadata:
  name: secret-basic-auth
type: kubernetes.io/basic-auth
stringData:
  username: admin # required field for kubernetes.io/basic-auth
  password: t0p-Secret # required field for kubernetes.io/basic-auth

提供基本身份驗證 Secret 類型僅是為了方便。你可以為用於基本身份驗證的憑證建立 Opaque 類型。但是,使用已定義且公開的 Secret 類型 (kubernetes.io/basic-auth) 有助於其他人了解你的 Secret 的用途,並為預期的鍵名稱建立慣例。

SSH 身份驗證 Secret

提供內建類型 kubernetes.io/ssh-auth 是為了儲存用於 SSH 身份驗證的資料。當使用此 Secret 類型時,你必須在 data(或 stringData)欄位中指定一個 ssh-privatekey 鍵值對,作為要使用的 SSH 憑證。

以下清單是用於 SSH 公開/私密金鑰身份驗證的 Secret 範例

apiVersion: v1
kind: Secret
metadata:
  name: secret-ssh-auth
type: kubernetes.io/ssh-auth
data:
  # the data is abbreviated in this example
  ssh-privatekey: |
    UG91cmluZzYlRW1vdGljb24lU2N1YmE=    

提供 SSH 身份驗證 Secret 類型僅是為了方便。你可以為用於 SSH 身份驗證的憑證建立 Opaque 類型。但是,使用已定義且公開的 Secret 類型 (kubernetes.io/ssh-auth) 有助於其他人了解你的 Secret 的用途,並為預期的鍵名稱建立慣例。Kubernetes API 會驗證是否為此類型的 Secret 設定了必要的鍵。

TLS Secret

kubernetes.io/tls Secret 類型用於儲存憑證及其相關聯的金鑰,這些金鑰通常用於 TLS。

TLS Secret 的一個常見用途是為 Ingress 組態傳輸中加密,但你也可以將其與其他資源一起使用,或直接在你的工作負載中使用。當使用此類型的 Secret 時,必須在 Secret 組態的 data(或 stringData)欄位中提供 tls.keytls.crt 鍵,儘管 API 伺服器實際上並未驗證每個鍵的值。

作為使用 stringData 的替代方案,你可以使用 data 欄位來提供 base64 編碼的憑證和私密金鑰。有關詳細資訊,請參閱 Secret 名稱和資料的約束

以下 YAML 包含 TLS Secret 的範例組態

apiVersion: v1
kind: Secret
metadata:
  name: secret-tls
type: kubernetes.io/tls
data:
  # values are base64 encoded, which obscures them but does NOT provide
  # any useful level of confidentiality
  tls.crt: |
    LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVakNDQWJzQ0FnMytNQTBHQ1NxR1NJYjNE
    UUVCQlFVQU1JR2JNUXN3Q1FZRFZRUUdFd0pLVURFT01Bd0cKQTFVRUNCTUZWRzlyZVc4eEVEQU9C
    Z05WQkFjVEIwTm9kVzh0YTNVeEVUQVBCZ05WQkFvVENFWnlZVzVyTkVSRQpNUmd3RmdZRFZRUUxF
    dzlYWldKRFpYSjBJRk4xY0hCdmNuUXhHREFXQmdOVkJBTVREMFp5WVc1ck5FUkVJRmRsCllpQkRR
    VEVqTUNFR0NTcUdTSWIzRFFFSkFSWVVjM1Z3Y0c5eWRFQm1jbUZ1YXpSa1pDNWpiMjB3SGhjTk1U
    TXcKTVRFeE1EUTFNVE01V2hjTk1UZ3dNVEV3TURRMU1UTTVXakJMTVFzd0NRWURWUVFHREFKS1VE
    RVBNQTBHQTFVRQpDQXdHWEZSdmEzbHZNUkV3RHdZRFZRUUtEQWhHY21GdWF6UkVSREVZTUJZR0Ex
    VUVBd3dQZDNkM0xtVjRZVzF3CmJHVXVZMjl0TUlHYU1BMEdDU3FHU0liM0RRRUJBUVVBQTRHSUFE
    Q0JoQUo5WThFaUhmeHhNL25PbjJTbkkxWHgKRHdPdEJEVDFKRjBReTliMVlKanV2YjdjaTEwZjVN
    Vm1UQllqMUZTVWZNOU1vejJDVVFZdW4yRFljV29IcFA4ZQpqSG1BUFVrNVd5cDJRN1ArMjh1bklI
    QkphVGZlQ09PekZSUFY2MEdTWWUzNmFScG04L3dVVm16eGFLOGtCOWVaCmhPN3F1TjdtSWQxL2pW
    cTNKODhDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUVVGQUFPQmdRQU1meTQzeE15OHh3QTUKVjF2T2NS
    OEtyNWNaSXdtbFhCUU8xeFEzazlxSGtyNFlUY1JxTVQ5WjVKTm1rWHYxK2VSaGcwTi9WMW5NUTRZ
    RgpnWXcxbnlESnBnOTduZUV4VzQyeXVlMFlHSDYyV1hYUUhyOVNVREgrRlowVnQvRGZsdklVTWRj
    UUFEZjM4aU9zCjlQbG1kb3YrcE0vNCs5a1h5aDhSUEkzZXZ6OS9NQT09Ci0tLS0tRU5EIENFUlRJ
    RklDQVRFLS0tLS0K    
  # In this example, the key data is not a real PEM-encoded private key
  tls.key: |
    RXhhbXBsZSBkYXRhIGZvciB0aGUgVExTIGNydCBmaWVsZA==    

提供 TLS Secret 類型僅是為了方便。你可以為用於 TLS 身份驗證的憑證建立 Opaque 類型。但是,使用已定義且公開的 Secret 類型 (kubernetes.io/tls) 有助於確保你的專案中 Secret 格式的一致性。API 伺服器會驗證是否為此類型的 Secret 設定了必要的鍵。

若要使用 kubectl 建立 TLS Secret,請使用 tls 子命令

kubectl create secret tls my-tls-secret \
  --cert=path/to/cert/file \
  --key=path/to/key/file

公開/私密金鑰對必須事先存在。--cert 的公開金鑰憑證必須是 .PEM 編碼的,並且必須與給定的 --key 私密金鑰匹配。

啟動引導權杖 Secret

bootstrap.kubernetes.io/token Secret 類型用於節點啟動引導過程中使用的權杖。它儲存用於簽署廣為人知的 ConfigMap 的權杖。

啟動引導權杖 Secret 通常在 kube-system 命名空間中建立,並以 bootstrap-token-<token-id> 的形式命名,其中 <token-id> 是權杖 ID 的 6 個字元的字串。

作為 Kubernetes 清單,啟動引導權杖 Secret 可能看起來像以下這樣

apiVersion: v1
kind: Secret
metadata:
  name: bootstrap-token-5emitj
  namespace: kube-system
type: bootstrap.kubernetes.io/token
data:
  auth-extra-groups: c3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG9rZW4=
  expiration: MjAyMC0wOS0xM1QwNDozOToxMFo=
  token-id: NWVtaXRq
  token-secret: a3E0Z2lodnN6emduMXAwcg==
  usage-bootstrap-authentication: dHJ1ZQ==
  usage-bootstrap-signing: dHJ1ZQ==

啟動引導權杖 Secret 在 data 下指定了以下鍵

  • token-id:作為權杖識別符的隨機 6 個字元的字串。必要。
  • token-secret:作為實際權杖 Secret 的隨機 16 個字元的字串。必要。
  • description:描述權杖用途的人類可讀字串。選用。
  • expiration:使用 RFC3339 的絕對 UTC 時間,指定權杖應何時過期。選用。
  • usage-bootstrap-<usage>:一個布林標記,指示啟動引導權杖的其他用途。
  • auth-extra-groups:除了 system:bootstrappers 群組之外,還將驗證為身份驗證的群組名稱的逗號分隔清單。

你也可以選擇在 Secret 的 stringData 欄位中提供值,而無需對其進行 base64 編碼

apiVersion: v1
kind: Secret
metadata:
  # Note how the Secret is named
  name: bootstrap-token-5emitj
  # A bootstrap token Secret usually resides in the kube-system namespace
  namespace: kube-system
type: bootstrap.kubernetes.io/token
stringData:
  auth-extra-groups: "system:bootstrappers:kubeadm:default-node-token"
  expiration: "2020-09-13T04:39:10Z"
  # This token ID is used in the name
  token-id: "5emitj"
  token-secret: "kq4gihvszzgn1p0r"
  # This token can be used for authentication
  usage-bootstrap-authentication: "true"
  # and it can be used for signing
  usage-bootstrap-signing: "true"

使用 Secret

建立 Secret

有幾種建立 Secret 的選項

Secret 名稱和資料的約束

Secret 物件的名稱必須是有效的 DNS 子網域名稱

當為 Secret 建立組態檔時,你可以指定 data 和/或 stringData 欄位。datastringData 欄位是選用的。data 欄位中所有鍵的值都必須是 base64 編碼的字串。如果不需要轉換為 base64 字串,你可以選擇改為指定 stringData 欄位,該欄位接受任意字串作為值。

datastringData 的鍵必須由字母數字字元、-_. 組成。stringData 欄位中的所有鍵值對都會在內部合併到 data 欄位中。如果一個鍵同時出現在 datastringData 欄位中,則 stringData 欄位中指定的值優先。

大小限制

個別 Secret 的大小限制為 1MiB。這是為了避免建立非常大的 Secret,這些 Secret 可能會耗盡 API 伺服器和 kubelet 記憶體。但是,建立許多較小的 Secret 也可能耗盡記憶體。你可以使用 資源配額 來限制命名空間中 Secret(或其他資源)的數量。

編輯 Secret

你可以編輯現有的 Secret,除非它是 不可變的。若要編輯 Secret,請使用以下方法之一

你也可以使用 Kustomize 工具 編輯 Secret 中的資料。但是,此方法會建立一個包含已編輯資料的新 Secret 物件。

根據你建立 Secret 的方式,以及 Secret 在你的 Pod 中的使用方式,對現有 Secret 物件的更新會自動傳播到使用資料的 Pod。有關更多資訊,請參閱 從 Pod 中將 Secret 用作檔案 章節。

使用 Secret

Secret 可以掛載為資料 Volume 或公開為 環境變數,以供 Pod 中的容器使用。Secret 也可以由系統的其他部分使用,而無需直接暴露給 Pod。例如,Secret 可以保存系統其他部分應代表你與外部系統互動時使用的憑證。

Secret Volume 來源會經過驗證,以確保指定的物件參照實際上指向 Secret 類型的物件。因此,需要在任何依賴它的 Pod 之前建立 Secret。

如果無法提取 Secret(可能是因為它不存在,或由於暫時無法連線到 API 伺服器),則 kubelet 會定期重試執行該 Pod。kubelet 也會為該 Pod 報告一個事件,其中包括提取 Secret 問題的詳細資訊。

選用 Secret

當你在 Pod 中參照 Secret 時,你可以將 Secret 標記為選用,如下列範例所示。如果選用的 Secret 不存在,Kubernetes 會忽略它。

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      optional: true

預設情況下,Secret 是必要的。在所有非選用的 Secret 都可用之前,Pod 的容器都不會啟動。

如果 Pod 在非選用的 Secret 中參照了特定的鍵,並且該 Secret 確實存在,但缺少指定的鍵,則 Pod 在啟動期間會失敗。

從 Pod 中將 Secret 用作檔案

如果你想在 Pod 中存取 Secret 中的資料,一種方法是讓 Kubernetes 將該 Secret 的值作為檔案在一個或多個 Pod 容器的檔案系統中可用。

有關說明,請參閱 建立可透過 Volume 存取 Secret 資料的 Pod

當 Volume 包含來自 Secret 的資料,並且該 Secret 已更新時,Kubernetes 會追蹤此情況並更新 Volume 中的資料,並使用最終一致性的方法。

kubelet 會保留用於該節點上 Pod 的 Volume 中的 Secret 的目前鍵和值的快取。你可以組態 kubelet 從快取值偵測變更的方式。kubelet 組態 中的 configMapAndSecretChangeDetectionStrategy 欄位控制 kubelet 使用的策略。預設策略為 Watch

對 Secret 的更新可以透過 API 監看機制(預設)、基於具有定義存活時間的快取來傳播,或在每個 kubelet 同步迴圈中從叢集 API 伺服器輪詢。

因此,從 Secret 更新到新鍵投射到 Pod 的總延遲可能長達 kubelet 同步週期 + 快取傳播延遲,其中快取傳播延遲取決於選擇的快取類型(按照上一段中列出的相同順序,這些類型是:監看傳播延遲、組態的快取 TTL 或直接輪詢的零延遲)。

將 Secret 用作環境變數

若要在 Pod 的 環境變數 中使用 Secret

  1. 對於 Pod 規格中的每個容器,為你要使用的每個 Secret 鍵新增一個環境變數到 env[].valueFrom.secretKeyRef 欄位。
  2. 修改你的映像檔和/或命令列,以便程式在指定的環境變數中尋找值。

有關說明,請參閱 使用 Secret 資料定義容器環境變數

重要的是要注意,Pod 中允許用於環境變數名稱的字元範圍是 受限制的。如果任何鍵不符合規則,則這些鍵將無法提供給你的容器,儘管允許 Pod 啟動。

容器映像檔提取 Secret

如果你想從私有儲存庫提取容器映像檔,你需要一種方法讓每個節點上的 kubelet 向該儲存庫進行身份驗證。你可以組態映像檔提取 Secret 來實現此目的。這些 Secret 是在 Pod 層級組態的。

使用 imagePullSecrets

imagePullSecrets 欄位是同一命名空間中 Secret 的參照清單。你可以使用 imagePullSecrets 將包含 Docker(或其他)映像檔儲存庫密碼的 Secret 傳遞給 kubelet。kubelet 使用此資訊代表你的 Pod 提取私有映像檔。有關 imagePullSecrets 欄位的更多資訊,請參閱 PodSpec API

手動指定 imagePullSecret

你可以從 容器映像檔 文件中了解如何指定 imagePullSecrets

安排自動附加 imagePullSecrets

你可以手動建立 imagePullSecrets,並從 ServiceAccount 參照這些 Secret。使用該 ServiceAccount 建立的任何 Pod 或預設使用該 ServiceAccount 建立的 Pod,其 imagePullSecrets 欄位將設定為 Service Account 的欄位。有關該過程的詳細說明,請參閱 將 ImagePullSecrets 新增到 Service Account

將 Secret 與靜態 Pod 搭配使用

你無法將 ConfigMap 或 Secret 與 靜態 Pod 搭配使用。

不可變的 Secret

功能狀態: Kubernetes v1.21 [穩定]

Kubernetes 允許你將特定的 Secret(和 ConfigMap)標記為不可變的。防止變更現有 Secret 的資料具有以下優點

  • 保護你免於意外(或不必要的)更新,這些更新可能會導致應用程式中斷
  • (對於廣泛使用 Secret 的叢集 - 至少有數萬個獨特的 Secret 到 Pod 掛載),切換到不可變的 Secret 可以透過顯著減少 kube-apiserver 上的負載來提高叢集的效能。kubelet 不需要維護對任何標記為不可變的 Secret 的 [監看]。

將 Secret 標記為不可變的

你可以透過將 immutable 欄位設定為 true 來建立不可變的 Secret。例如,

apiVersion: v1
kind: Secret
metadata: ...
data: ...
immutable: true

你也可以更新任何現有的可變 Secret 以使其成為不可變的。

Secret 的資訊安全

儘管 ConfigMap 和 Secret 的工作方式類似,但 Kubernetes 為 Secret 物件應用了一些額外的保護。

Secret 通常保存重要性範圍廣泛的值,其中許多值可能會導致 Kubernetes 內部(例如,Service Account 權杖)和外部系統的權限提升。即使個別應用程式可以推理它預期互動的 Secret 的權力,同一命名空間中的其他應用程式也可能使這些假設無效。

僅當節點上的 Pod 需要 Secret 時,才會將 Secret 發送到該節點。為了將 Secret 掛載到 Pod 中,kubelet 將資料副本儲存在 tmpfs 中,以便機密資料不會寫入持久儲存空間。一旦依賴 Secret 的 Pod 被刪除,kubelet 就會從 Secret 中刪除其機密資料的本機副本。

一個 Pod 中可能有多個容器。預設情況下,你定義的容器只能存取預設的 ServiceAccount 及其相關的 Secret。你必須明確定義環境變數或將 Volume 對應到容器中,才能提供對任何其他 Secret 的存取權。

同一節點上可能有多個 Pod 的 Secret。但是,只有 Pod 請求的 Secret 才可能在其容器中可見。因此,一個 Pod 無法存取另一個 Pod 的 Secret。

組態 Secret 的最小權限存取

為了加強圍繞 Secret 的安全措施,請使用單獨的命名空間來隔離對掛載的 Secret 的存取。

接下來

最後修改時間:2024 年 11 月 19 日晚上 10:53 PST:Address comments (3b8c927a3b)