密文
密文是一個物件,其中包含少量敏感資料,例如密碼、權杖或金鑰。這類資訊否則可能會放在 Pod 規格或 容器映像檔中。使用密文表示您不需要在應用程式程式碼中包含機密資料。
由於密文可以獨立於使用它們的 Pod 建立,因此在建立、檢視與編輯 Pod 的工作流程期間,密文 (及其資料) 暴露的風險較低。Kubernetes 與在叢集中執行的應用程式也可以對密文採取額外的預防措施,例如避免將敏感資料寫入非揮發性儲存裝置。
密文與 ConfigMaps 類似,但專門用於保存機密資料。
注意
依預設,Kubernetes 密文以未加密形式儲存在 API 伺服器的底層資料儲存區 (etcd) 中。任何具有 API 存取權限的人都可以檢索或修改密文,任何具有 etcd 存取權限的人也可以。此外,任何經授權在命名空間中建立 Pod 的人都可以使用該存取權限讀取該命名空間中的任何密文;這包括間接存取,例如建立部署的能力。
為了安全地使用密文,請至少採取以下步驟
- 為密文啟用靜態加密。
- 啟用或設定 RBAC 規則,以最小權限存取密文。
- 將密文存取限制為特定容器。
- 考慮使用外部密文儲存提供者.
如需管理與改善密文安全性的更多指南,請參閱Kubernetes 密文的最佳實務。
如需更多詳細資訊,請參閱密文的資訊安全。
密文的用途
您可以將密文用於以下用途,例如
Kubernetes 控制平面也使用 Secret;例如,啟動引導權杖 Secret 是一種有助於自動化節點註冊的機制。
使用案例:Secret Volume 中的點檔案
你可以透過定義一個以點開頭的鍵,使你的資料成為「隱藏」。這個鍵代表一個點檔案或「隱藏」檔案。例如,當以下 Secret 掛載到一個 Volume,secret-volume
時,該 Volume 將包含一個名為 .secret-file
的單一檔案,而 dotfile-test-container
將在路徑 /etc/secret-volume/.secret-file
中找到此檔案。
註記
以點字元開頭的檔案會從ls -l
的輸出中隱藏;當列出目錄內容時,你必須使用 ls -la
才能看到它們。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-token | ServiceAccount 權杖 |
kubernetes.io/dockercfg | 序列化的 ~/.dockercfg 檔案 |
kubernetes.io/dockerconfigjson | 序列化的 ~/.docker/config.json 檔案 |
kubernetes.io/basic-auth | 基本身份驗證的憑證 |
kubernetes.io/ssh-auth | SSH 身份驗證的憑證 |
kubernetes.io/tls | TLS 用戶端或伺服器的資料 |
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。
註記
只有在你無法使用TokenRequest
API 取得權杖,並且在可讀取的 API 物件中持久化一個永不過期的權杖憑證的安全性風險對你來說是可以接受的情況下,你才應該建立 ServiceAccount 權杖 Secret。有關說明,請參閱 為 ServiceAccount 手動建立長期有效的 API 權杖。當使用此 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 文件。你也可以查看 Pod
的 automountServiceAccountToken
欄位和 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=
註記
如果你不想執行 base64 編碼,你可以選擇改用stringData
欄位。當你使用清單建立 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="
}
}
}
注意
其中的 auth
值是 base64 編碼的;它是模糊的,但不是秘密。任何可以讀取該 Secret 的人都可能得知儲存庫存取持有者權杖。
建議使用 憑證提供者 來動態且安全地按需提供提取 Secret。
基本身份驗證 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 的stringData
欄位不適用於伺服器端套用。提供基本身份驗證 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 設定了必要的鍵。
注意
SSH 私密金鑰本身並不能在 SSH 用戶端和主機伺服器之間建立信任的通訊。需要輔助的信任建立方式來緩解「中間人」攻擊,例如將known_hosts
檔案新增到 ConfigMap。TLS Secret
kubernetes.io/tls
Secret 類型用於儲存憑證及其相關聯的金鑰,這些金鑰通常用於 TLS。
TLS Secret 的一個常見用途是為 Ingress 組態傳輸中加密,但你也可以將其與其他資源一起使用,或直接在你的工作負載中使用。當使用此類型的 Secret 時,必須在 Secret 組態的 data
(或 stringData
)欄位中提供 tls.key
和 tls.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 的stringData
欄位不適用於伺服器端套用。使用 Secret
建立 Secret
有幾種建立 Secret 的選項
Secret 名稱和資料的約束
Secret 物件的名稱必須是有效的 DNS 子網域名稱。
當為 Secret 建立組態檔時,你可以指定 data
和/或 stringData
欄位。data
和 stringData
欄位是選用的。data
欄位中所有鍵的值都必須是 base64 編碼的字串。如果不需要轉換為 base64 字串,你可以選擇改為指定 stringData
欄位,該欄位接受任意字串作為值。
data
和 stringData
的鍵必須由字母數字字元、-
、_
或 .
組成。stringData
欄位中的所有鍵值對都會在內部合併到 data
欄位中。如果一個鍵同時出現在 data
和 stringData
欄位中,則 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 中的資料,並使用最終一致性的方法。
註記
使用 Secret 作為 subPath Volume 掛載的容器不會收到自動 Secret 更新。kubelet 會保留用於該節點上 Pod 的 Volume 中的 Secret 的目前鍵和值的快取。你可以組態 kubelet 從快取值偵測變更的方式。kubelet 組態 中的 configMapAndSecretChangeDetectionStrategy
欄位控制 kubelet 使用的策略。預設策略為 Watch
。
對 Secret 的更新可以透過 API 監看機制(預設)、基於具有定義存活時間的快取來傳播,或在每個 kubelet 同步迴圈中從叢集 API 伺服器輪詢。
因此,從 Secret 更新到新鍵投射到 Pod 的總延遲可能長達 kubelet 同步週期 + 快取傳播延遲,其中快取傳播延遲取決於選擇的快取類型(按照上一段中列出的相同順序,這些類型是:監看傳播延遲、組態的快取 TTL 或直接輪詢的零延遲)。
將 Secret 用作環境變數
若要在 Pod 的 環境變數 中使用 Secret
- 對於 Pod 規格中的每個容器,為你要使用的每個 Secret 鍵新增一個環境變數到
env[].valueFrom.secretKeyRef
欄位。 - 修改你的映像檔和/或命令列,以便程式在指定的環境變數中尋找值。
有關說明,請參閱 使用 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 被標記為不可變的,就無法還原此變更,也無法變更data
欄位的內容。你只能刪除並重新建立 Secret。現有的 Pod 維護到已刪除 Secret 的掛載點 - 建議重新建立這些 Pod。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 的存取。
警告
在節點上以privileged: true
執行的任何容器都可以存取該節點上使用的所有 Secret。接下來
- 有關管理和改進 Secret 安全性的指南,請參閱 Kubernetes Secret 的良好實務。
- 了解如何使用
kubectl
管理 Secret - 了解如何使用 組態檔管理 Secret
- 了解如何使用 kustomize 管理 Secret
- 閱讀
Secret
的 API 參考