投射卷
本文件描述了 Kubernetes 中的**投射卷(projected volumes)**。建議熟悉卷(volumes)。
介紹
projected
卷將多個現有卷源對映到同一個目錄中。
目前,以下型別的卷源可以被投射:
所有源都必須與 Pod 位於相同的名稱空間中。更多詳情請參閱 all-in-one volume 設計文件。
包含 Secret、DownwardAPI 和 ConfigMap 的示例配置:
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox:1.28
command: ["sleep", "3600"]
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "cpu_limit"
resourceFieldRef:
containerName: container-test
resource: limits.cpu
- configMap:
name: myconfigmap
items:
- key: config
path: my-group/my-config
示例配置:設定了非預設許可權模式的 Secret
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox:1.28
command: ["sleep", "3600"]
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- secret:
name: mysecret2
items:
- key: password
path: my-group/my-password
mode: 511
每個投射卷源都在規範的 sources
下列出。引數幾乎相同,但有兩個例外:
- 對於 Secret,
secretName
欄位已更改為name
,以與 ConfigMap 的命名保持一致。 defaultMode
只能在投射級別指定,而不能為每個卷源指定。然而,如上所示,你可以為每個單獨的投射顯式設定mode
。
serviceAccountToken 投射卷
你可以將當前服務賬號的令牌注入到 Pod 中的指定路徑。例如:
apiVersion: v1
kind: Pod
metadata:
name: sa-token-test
spec:
containers:
- name: container-test
image: busybox:1.28
command: ["sleep", "3600"]
volumeMounts:
- name: token-vol
mountPath: "/service-account"
readOnly: true
serviceAccountName: default
volumes:
- name: token-vol
projected:
sources:
- serviceAccountToken:
audience: api
expirationSeconds: 3600
path: token
該示例 Pod 包含一個投射卷,其中注入了服務賬號令牌。此 Pod 中的容器可以使用該令牌訪問 Kubernetes API 伺服器,並以Pod 的 ServiceAccount 身份進行身份驗證。audience
欄位包含令牌的預期受眾。令牌的接收者必須使用令牌受眾中指定的識別符號來識別自己,否則應拒絕該令牌。此欄位是可選的,預設為 API 伺服器的識別符號。
expirationSeconds
是服務賬號令牌的預期有效期。它預設為 1 小時,並且必須至少為 10 分鐘(600 秒)。管理員還可以透過為 API 伺服器指定 --service-account-max-token-expiration
選項來限制其最大值。path
欄位指定投射卷掛載點的相對路徑。
注意
使用投射卷源作為subPath
卷掛載的容器將不會收到這些卷源的更新。clusterTrustBundle 投射卷
Kubernetes v1.33 [beta]
(預設停用)注意
要在 Kubernetes 1.34 中使用此特性,你必須透過ClusterTrustBundle
特性門控和 --runtime-config=certificates.k8s.io/v1beta1/clustertrustbundles=true
kube-apiserver 標誌啟用對 ClusterTrustBundle 物件的支援,然後啟用 ClusterTrustBundleProjection
特性門控。clusterTrustBundle
投射卷源將一個或多個 ClusterTrustBundle 物件的內容注入為容器檔案系統中的自動更新檔案。
ClusterTrustBundle 可以透過名稱或簽名者名稱進行選擇。
要透過名稱選擇,請使用 name
欄位指定單個 ClusterTrustBundle 物件。
要透過簽名者名稱選擇,請使用 signerName
欄位(以及可選的 labelSelector
欄位)指定一組使用給定簽名者名稱的 ClusterTrustBundle 物件。如果 labelSelector
不存在,則選擇該簽名者的所有 ClusterTrustBundle。
Kubelet 會對選定的 ClusterTrustBundle 物件中的證書進行去重,規範化 PEM 表示(丟棄註釋和頭),重新排序證書,並將它們寫入由 path
命名的檔案。當選定的 ClusterTrustBundle 集合或其內容發生變化時,kubelet 會保持檔案是最新的。
預設情況下,如果找不到命名的 ClusterTrustBundle,或者 signerName
/ labelSelector
不匹配任何 ClusterTrustBundle,kubelet 將阻止 Pod 啟動。如果這不是你想要的行為,請將 optional
欄位設定為 true
,Pod 將在 path
處啟動一個空檔案。
apiVersion: v1
kind: Pod
metadata:
name: sa-ctb-name-test
spec:
containers:
- name: container-test
image: busybox
command: ["sleep", "3600"]
volumeMounts:
- name: token-vol
mountPath: "/root-certificates"
readOnly: true
serviceAccountName: default
volumes:
- name: token-vol
projected:
sources:
- clusterTrustBundle:
name: example
path: example-roots.pem
- clusterTrustBundle:
signerName: "example.com/mysigner"
labelSelector:
matchLabels:
version: live
path: mysigner-roots.pem
optional: true
podCertificate 投射卷
Kubernetes v1.34 [alpha]
(預設停用)注意
在 Kubernetes 1.34 中,你必須使用PodCertificateRequest
特性門控和 --runtime-config=certificates.k8s.io/v1alpha1/podcertificaterequests=true
kube-apiserver 標誌啟用對 Pod 證書的支援。podCertificate
投射卷源安全地為 Pod 提供了私鑰和 X.509 證書鏈,作為客戶端或伺服器憑據使用。Kubelet 將在私鑰和證書連結近過期時處理它們的重新整理。應用程式只需確保在檔案更改時及時重新載入檔案,例如使用 inotify
或輪詢機制。
每個 podCertificate
投射支援以下配置欄位:
signerName
:你希望頒發證書的簽名者。請注意,簽名者可能有自己的訪問要求,並可能拒絕向你的 Pod 頒發證書。keyType
:應生成的私鑰型別。有效值為ED25519
、ECDSAP256
、ECDSAP384
、ECDSAP521
、RSA3072
和RSA4096
。maxExpirationSeconds
:你接受的頒發給 Pod 證書的最長有效期。如果未設定,則預設為86400
(24 小時)。必須至少為3600
(1 小時),最多為7862400
(91 天)。Kubernetes 內建簽名者限制為最長有效期86400
(1 天)。簽名者可以頒發比你指定有效期短的證書。credentialBundlePath
:憑證包應寫入的投射中的相對路徑。憑證包是一個 PEM 格式的檔案,其中第一個塊是包含 PKCS#8 序列化私鑰的“PRIVATE KEY”塊,其餘塊是構成證書鏈(葉證書和任何中間證書)的“CERTIFICATE”塊。keyPath
和certificateChainPath
:Kubelet 應該**只**寫入私鑰或證書鏈的單獨路徑。
注意
大多數應用程式應優先使用credentialBundlePath
,除非出於相容性原因需要將金鑰和證書分別存放在不同的檔案中。Kubelet 使用基於符號連結的原子寫入策略,以確保當你開啟它投射的檔案時,你讀取的是舊內容或新內容。然而,如果你從單獨的檔案中讀取金鑰和證書鏈,Kubelet 可能會在你的第一次讀取之後和第二次讀取之前輪換憑據,導致你的應用程式載入不匹配的金鑰和證書。# Sample Pod spec that uses a podCertificate projection to request an ED25519
# private key, a certificate from the `coolcert.example.com/foo` signer, and
# write the results to `/var/run/my-x509-credentials/credentialbundle.pem`.
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: podcertificate-pod
spec:
serviceAccountName: default
containers:
- image: debian
name: main
command: ["sleep", "infinity"]
volumeMounts:
- name: my-x509-credentials
mountPath: /var/run/my-x509-credentials
volumes:
- name: my-x509-credentials
projected:
defaultMode: 420
sources:
- podCertificate:
keyType: ED25519
signerName: coolcert.example.com/foo
credentialBundlePath: credentialbundle.pem
SecurityContext 互動
關於投射服務賬號卷增強中檔案許可權處理的提案引入了投射檔案設定正確所有者許可權的機制。
Linux
在具有投射卷並在 Pod SecurityContext
中設定 RunAsUser
的 Linux Pod 中,投射檔案具有正確的所有權設定,包括容器使用者所有權。
當 Pod 中的所有容器在其 PodSecurityContext
或容器 SecurityContext
中設定相同的 runAsUser
時,kubelet 確保 serviceAccountToken
卷的內容由該使用者擁有,並且令牌檔案的許可權模式設定為 0600
。
注意
在 Pod 建立後新增的 臨時容器 不會改變 Pod 建立時設定的卷許可權。
如果 Pod 的 serviceAccountToken
卷許可權由於 Pod 中所有其他容器具有相同的 runAsUser
而設定為 0600
,則臨時容器必須使用相同的 runAsUser
才能讀取令牌。
Windows
在具有投射卷並在 Pod SecurityContext
中設定 RunAsUsername
的 Windows Pod 中,由於 Windows 中使用者賬號的管理方式,所有權未被強制執行。Windows 在名為安全賬號管理器(SAM)的資料庫檔案中儲存和管理本地使用者和組賬號。每個容器都維護自己的 SAM 資料庫例項,在容器執行時主機無法檢視。Windows 容器旨在將作業系統的使用者模式部分與主機隔離執行,因此維護了一個虛擬 SAM 資料庫。因此,在主機上執行的 kubelet 沒有能力為虛擬化容器賬號動態配置主機檔案所有權。建議如果主機上的檔案要與容器共享,則應將它們放置在 C:\
之外的自己的卷掛載中。
預設情況下,投射檔案將具有以下所有權,示例如下:
PS C:\> Get-Acl C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt | Format-List
Path : Microsoft.PowerShell.Core\FileSystem::C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt
Owner : BUILTIN\Administrators
Group : NT AUTHORITY\SYSTEM
Access : NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow FullControl
BUILTIN\Users Allow ReadAndExecute, Synchronize
Audit :
Sddl : O:BAG:SYD:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU)
這意味著所有管理員使用者(如 ContainerAdministrator
)將擁有讀、寫和執行許可權,而非管理員使用者將擁有讀和執行許可權。
注意
通常,不鼓勵授予容器訪問主機的許可權,因為這可能會導致潛在的安全漏洞。
在 Windows Pod 中使用 RunAsUser
建立 Pod 將導致 Pod 永遠停留在 ContainerCreating
狀態。因此,建議不要在 Windows Pod 中使用僅適用於 Linux 的 RunAsUser
選項。