Skip to content

Commit 79b343d

Browse files
committed
Pod Certificates: User documentation
1 parent 237eb46 commit 79b343d

File tree

4 files changed

+467
-203
lines changed

4 files changed

+467
-203
lines changed

content/en/docs/concepts/storage/projected-volumes.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2930
All sources are required to be in the same namespace as the Pod. For more details,
3031
see 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

101204
The [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

Comments
 (0)