@@ -25,6 +25,7 @@ Currently, the following types of volume sources can be projected:
2525* [ ` configMap ` ] ( /docs/concepts/storage/volumes/#configmap )
2626* [ ` serviceAccountToken ` ] ( #serviceaccounttoken )
2727* [ ` clusterTrustBundle ` ] ( #clustertrustbundle )
28+ * [ ` podCertificate ` ] ( #podcertificate )
2829
2930All sources are required to be in the same namespace as the Pod. For more details,
3031see the [ all-in-one volume] ( https://git.k8s.io/design-proposals-archive/node/all-in-one-volume.md ) design document.
@@ -96,6 +97,108 @@ By default, the kubelet will prevent the pod from starting if the named ClusterT
9697
9798{{% code_sample file="pods/storage/projected-clustertrustbundle.yaml" %}}
9899
100+ ## podCertificate projected volumes {#podcertificate}
101+
102+ {{< feature-state feature_gate_name="PodCertificateRequest" >}}
103+
104+ {{< note >}}
105+ In Kubernetes {{< skew currentVersion >}}, you must enable the
106+ ` PodCertificateRequest ` [ feature
107+ gate] ( /docs/reference/command-line-tools-reference/feature-gates/ ) _ and_ the
108+ ` certificates.k8s.io/v1alpha1 ` {{< glossary_tooltip text="API group"
109+ term_id="api-group" >}} in order to use this API.
110+ {{< /note >}}
111+
112+ The ` podCertificate ` projected volumes source securely provisions a private key
113+ and X.509 certificate chain for pod to use as client or server credentials.
114+ Kubelet will then handle refreshing the private key and certificate chain when
115+ they get close to expiration. The application just has to make sure that it
116+ reloads the file promptly when it changes, with a mechanism like ` inotify ` or
117+ polling.
118+
119+ Each container within a pod can mount more than one podCertificate projection,
120+ and the same projection can safely be shared between multiple containers as
121+ well.
122+
123+ Each ` podCertificate ` projection supports the following configuration fields:
124+ * ` signerName ` : Which
125+ [ signer] ( /docs/reference/access-authn-authz/certificate-signing-requests#ctb-signer-unlinked#signers )
126+ you want to issue the certificate. Note that signers may have their own
127+ access requirements, and may refuse to issue certificates to your pod.
128+ * ` keyType ` : The type of private key that should be generated. Valid values are
129+ ` ED25519 ` , ` ECDSAP256 ` , ` ECDSAP384 ` , ` ECDSAP521 ` , ` RSA3072 ` , and ` RSA4096 ` .
130+ * ` maxExpirationSeconds ` : What's the maximum lifetime you want for the
131+ certificate issued to the pod? If not set, will be defaulted to ` 86400 ` (24
132+ hours). Must be at least ` 3600 ` (1 hour), and at most ` 7862400 ` (91 days).
133+ * ` credentialBundlePath ` : Relative path within the projection where the
134+ credential bundle should be written. The credential bundle is a PEM-formatted
135+ file, where the first block is a "PRIVATE KEY" block that contains a
136+ PKCS #8 -serialized private key, and the remaining blocks are "CERTIFICATE"
137+ blocks that comprise the certificate chain (leaf certificate and any
138+ intermediates).
139+ * ` keyPath ` and ` certificateChainPath ` : Separate paths where Kubelet should
140+ write * just* the private key or certificate chain.
141+
142+ {{< note >}}
143+
144+ Most applications should prefer using ` credentialBundlePath ` unless they need
145+ the key and certificates in separate files for compatibility reasons. Kubelet
146+ uses an atomic writing strategy based on symlinks to make sure that when you
147+ open the files it projects, you read either the old content or the new content.
148+ However, if you read the key and certificate chain from separate files, Kubelet
149+ may rotate the credentials after your first read and before your second read,
150+ resulting in your application loading a mismatched key and certificate.
151+
152+ {{< /note >}}
153+
154+ Under the hood, Kubelet will run the following state machine for each
155+ ` podCertificate ` projection:
156+
157+ {{< mermaid >}}
158+ graph LR
159+ Initial --> Wait
160+ Wait --> Fresh
161+ Wait --> Failed
162+ Wait --> Denied
163+ Fresh --> WaitRefresh
164+ WaitRefresh --> Failed
165+ WaitRefresh --> Denied
166+ {{< /mermaid >}}
167+ ** Figure 1:** Kubelet podCertificate lifecycle
168+
169+ 1 . The projection starts out in ` Initial ` state.
170+ 2 . Kubelet generates a private key and holds it in memory.
171+ 3 . Kubelet creates a
172+ [ PodCertificateRequest] ( /docs/reference/access-authn-authz/certificate-signing-requests#ctb-signer-unlinked#pod-certificate-requests )
173+ addressed to the requested signer. Kubelet then moves the projection into
174+ the ` Wait ` state.
175+ 4 . If the PodCertificateRequest is marked "Denied", move to the ` Denied ` state. This is
176+ a permanent error state, and the container(s) that mount this projection will
177+ fail to start.
178+ 5 . If the PodCertificateRequest is marked "Failed", move to the ` Failed ` state.
179+ This is a permanent error state, and the container(s) that mount this
180+ projection will fail to start.
181+ 6 . If the PodCertificate is marked "Issued", move to the ` Fresh ` state. Kubelet
182+ holds the private key and certificate chain in memory, and will periodically
183+ write them to the filesystem at the requested location. The container that
184+ mounts this projection will start up and run (assuming nothing else blocks
185+ its execution).
186+ 7 . The signer indicated an appropriate time to begin refreshing the certificate
187+ when it issued the PodCertificateRequest. Once that time has passed Kubelet
188+ will generate a new private key, create a new PodCertificateRequest, and move
189+ the projection into ` WaitRefresh ` state.
190+ 8 . If the PodCertificateRequest is marked "Denied", move to the ` Denied ` state.
191+ This is a permanent error state, and the container(s) will begin to get
192+ Kubelet volume remount errors.
193+ 9 . If the PodCertificateRequest is marked "Failed", move to the ` Failed ` state.
194+ This is a permanent error state, and the container(s) will begin to get
195+ Kubelet volume remount errors.
196+ 10 . If the PodCertificate is marked "Issued", move back to the ` Fresh ` state. The
197+ container(s) will continue to run, with the new private key and certificate
198+ chain written to the filesystem.
199+
200+ {{% code_sample file="pods/storage/projected-podcertificate.yaml" %}}
201+
99202## SecurityContext interactions
100203
101204The [ proposal] ( https://git.k8s.io/enhancements/keps/sig-storage/2451-service-account-token-volumes#proposal ) for file permission handling in projected service account volume enhancement introduced the projected files having the correct owner permissions set.
0 commit comments