Skip to content

Commit ae4e63f

Browse files
author
Tim Bannister
committed
Tidy page “Manage TLS Certificates in a Cluster”
1 parent 05b03c7 commit ae4e63f

File tree

1 file changed

+56
-45
lines changed

1 file changed

+56
-45
lines changed

content/en/docs/tasks/tls/managing-tls-in-a-cluster.md

Lines changed: 56 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,18 @@ these certificates will validate against the cluster root CA.
2929
## {{% heading "prerequisites" %}}
3030

3131

32-
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
32+
{{< include "task-tutorial-prereqs.md" >}}
3333

34+
You need the `cfssl` tool. You can download `cfssl` from
35+
[https://github.com/cloudflare/cfssl/releases](https://github.com/cloudflare/cfssl/releases).
3436

37+
Some steps in this page use the `jq` tool. If you don't have `jq`, you can
38+
install it via your operating system's software sources, or fetch it from
39+
[https://stedolan.github.io/jq/](https://stedolan.github.io/jq/).
3540

3641
<!-- steps -->
3742

38-
## Trusting TLS in a Cluster
43+
## Trusting TLS in a cluster
3944

4045
Trusting the custom CA from an application running as a pod usually requires
4146
some extra application configuration. You will need to add the CA certificate
@@ -48,7 +53,7 @@ You can distribute the CA certificate as a
4853
[ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap) that your
4954
pods have access to use.
5055

51-
## Requesting a Certificate
56+
## Requesting a certificate
5257

5358
The following section demonstrates how to create a TLS certificate for a
5459
Kubernetes service accessed through DNS.
@@ -57,12 +62,7 @@ Kubernetes service accessed through DNS.
5762
This tutorial uses CFSSL: Cloudflare's PKI and TLS toolkit [click here](https://blog.cloudflare.com/introducing-cfssl/) to know more.
5863
{{< /note >}}
5964

60-
## Download and install CFSSL
61-
62-
The cfssl tools used in this example can be downloaded at
63-
[https://github.com/cloudflare/cfssl/releases](https://github.com/cloudflare/cfssl/releases).
64-
65-
## Create a Certificate Signing Request
65+
## Create a certificate signing request
6666

6767
Generate a private key and certificate signing request (or CSR) by running
6868
the following command:
@@ -98,14 +98,14 @@ is the pod's DNS name. You should see the output similar to:
9898
```
9999

100100
This command generates two files; it generates `server.csr` containing the PEM
101-
encoded [pkcs#10](https://tools.ietf.org/html/rfc2986) certification request,
101+
encoded [PKCS#10](https://tools.ietf.org/html/rfc2986) certification request,
102102
and `server-key.pem` containing the PEM encoded key to the certificate that
103103
is still to be created.
104104

105-
## Create a Certificate Signing Request object to send to the Kubernetes API
105+
## Create a CertificateSigningRequest object to send to the Kubernetes API
106106

107-
Generate a CSR yaml blob and send it to the apiserver by running the following
108-
command:
107+
Generate a CSR manifest (in YAML), and send it to the API server. You can do that by
108+
running the following command:
109109

110110
```shell
111111
cat <<EOF | kubectl apply -f -
@@ -124,7 +124,7 @@ EOF
124124
```
125125

126126
Notice that the `server.csr` file created in step 1 is base64 encoded
127-
and stashed in the `.spec.request` field. We are also requesting a
127+
and stashed in the `.spec.request` field. You are also requesting a
128128
certificate with the "digital signature", "key encipherment", and "server
129129
auth" key usages, signed by an example `example.com/serving` signer.
130130
A specific `signerName` must be requested.
@@ -157,7 +157,7 @@ Subject Alternative Names:
157157
Events: <none>
158158
```
159159

160-
## Get the Certificate Signing Request Approved
160+
## Get the CertificateSigningRequest approved {#get-the-certificate-signing-request-approved}
161161

162162
Approving the [certificate signing request](/docs/reference/access-authn-authz/certificate-signing-requests/)
163163
is either done by an automated approval process or on a one off basis by a cluster
@@ -186,16 +186,18 @@ my-svc.my-namespace 10m example.com/serving [email protected] <none>
186186
This means the certificate request has been approved and is waiting for the
187187
requested signer to sign it.
188188

189-
## Sign the Certificate Signing Request
189+
## Sign the CertificateSigningRequest {#sign-the-certificate-signing-request}
190190

191191
Next, you'll play the part of a certificate signer, issue the certificate, and upload it to the API.
192192

193-
A signer would typically watch the Certificate Signing Request API for objects with its `signerName`,
194-
check that they have been approved, sign certificates for those requests,
193+
A signer would typically watch the CertificateSigningRequest API for objects with its `signerName`,
194+
check that they have been approved, sign certificates for those requests,
195195
and update the API object status with the issued certificate.
196196

197197
### Create a Certificate Authority
198198

199+
You need an authority to provide the digital signature on the new certificate.
200+
199201
First, create a signing certificate by running the following:
200202

201203
```shell
@@ -210,7 +212,7 @@ cat <<EOF | cfssl gencert -initca - | cfssljson -bare ca
210212
EOF
211213
```
212214

213-
You should see the output similar to:
215+
You should see output similar to:
214216

215217
```none
216218
2022/02/01 11:50:39 [INFO] generating a new CA key and certificate from CSR
@@ -223,7 +225,7 @@ You should see the output similar to:
223225

224226
This produces a certificate authority key file (`ca-key.pem`) and certificate (`ca.pem`).
225227

226-
### Issue a Certificate
228+
### Issue a certificate
227229

228230
{{< codenew file="tls/server-signing-config.json" >}}
229231

@@ -245,7 +247,7 @@ You should see the output similar to:
245247

246248
This produces a signed serving certificate file, `ca-signed-server.pem`.
247249

248-
### Upload the Signed Certificate
250+
### Upload the signed certificate
249251

250252
Finally, populate the signed certificate in the API object's status:
251253

@@ -256,62 +258,76 @@ kubectl get csr my-svc.my-namespace -o json | \
256258
```
257259

258260
{{< note >}}
259-
This uses the command line tool [jq](https://stedolan.github.io/jq/) to populate the base64-encoded content in the `.status.certificate` field.
260-
If you do not have `jq`, you can also save the JSON output to a file, populate this field manually, and upload the resulting file.
261+
This uses the command line tool [`jq`](https://stedolan.github.io/jq/) to populate the base64-encoded
262+
content in the `.status.certificate` field.
263+
If you do not have `jq`, you can also save the JSON output to a file, populate this field manually, and
264+
upload the resulting file.
261265
{{< /note >}}
262266

263-
Once the CSR is approved and the signed certificate is uploaded you should see the following:
267+
Once the CSR is approved and the signed certificate is uploaded, run:
264268

265269
```shell
266270
kubectl get csr
267271
```
268272

273+
The output is similar to:
269274
```none
270275
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
271276
my-svc.my-namespace 20m example.com/serving [email protected] <none> Approved,Issued
272277
```
273278

274-
## Download the Certificate and Use It
279+
## Download the certificate and use it
275280

276-
Now, as the requesting user, you can download the issued certificate
281+
Now, as the requesting user, you can download the issued certificate
277282
and save it to a `server.crt` file by running the following:
278283

279284
```shell
280285
kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \
281286
| base64 --decode > server.crt
282287
```
283288

284-
Now you can populate `server.crt` and `server-key.pem` in a secret and mount
285-
it into a pod to use as the keypair to start your HTTPS server:
289+
Now you can populate `server.crt` and `server-key.pem` in a
290+
{{< glossary_tooltip text="Secret" term_id="secret" >}}
291+
that you could later mount into a Pod (for example, to use with a webserver
292+
that serves HTTPS).
286293

287294
```shell
288-
kubectl create secret tls server --cert server.crt --key server-key.pem
295+
kubectl create secret tls server --cert server.crt --key server-key.pem
289296
```
290297

291298
```none
292299
secret/server created
293300
```
294301

295-
Finally, you can populate `ca.pem` in a configmap and use it as the trust root
296-
to verify the serving certificate:
302+
Finally, you can populate `ca.pem` into a {< glossary_tooltip text="ConfigMap" term_id="configmap" >}}
303+
and use it as the trust root to verify the serving certificate:
297304

298305
```shell
299-
kubectl create configmap example-serving-ca --from-file ca.crt=ca.pem
306+
kubectl create configmap example-serving-ca --from-file ca.crt=ca.pem
300307
```
301308

302309
```none
303310
configmap/example-serving-ca created
304311
```
305312

306-
## Approving Certificate Signing Requests
313+
## Approving CertificateSigningRequests {#approving-certificate-signing-requests}
307314

308315
A Kubernetes administrator (with appropriate permissions) can manually approve
309-
(or deny) Certificate Signing Requests by using the `kubectl certificate
316+
(or deny) CertificateSigningRequests by using the `kubectl certificate
310317
approve` and `kubectl certificate deny` commands. However if you intend
311318
to make heavy usage of this API, you might consider writing an automated
312319
certificates controller.
313320

314-
Whether a machine or a human using kubectl as above, the role of the approver is
321+
{{< caution >}}
322+
The ability to approve CSRs decides who trusts whom within your environment. The
323+
ability to approve CSRs should not be granted broadly or lightly.
324+
325+
You should make sure that you confidently understand both the verification requirements
326+
that fall on the approver **and** the repercussions of issuing a specific certificate
327+
before you grant the `approve` permission.
328+
{{< /caution >}}
329+
330+
Whether a machine or a human using kubectl as above, the role of the _approver_ is
315331
to verify that the CSR satisfies two requirements:
316332

317333
1. The subject of the CSR controls the private key used to sign the CSR. This
@@ -326,20 +342,15 @@ to verify that the CSR satisfies two requirements:
326342
If and only if these two requirements are met, the approver should approve
327343
the CSR and otherwise should deny the CSR.
328344

329-
## A Word of Warning on the Approval Permission
345+
For more information on certificate approval and access control, read
346+
the [Certificate Signing Requests](/docs/reference/access-authn-authz/certificate-signing-requests/)
347+
reference page.
330348

331-
The ability to approve CSRs decides who trusts whom within your environment. The
332-
ability to approve CSRs should not be granted broadly or lightly. The
333-
requirements of the challenge noted in the previous section and the
334-
repercussions of issuing a specific certificate should be fully understood
335-
before granting this permission.
336-
337-
## A Note to Cluster Administrators
349+
## Configuring your cluster to provide signing
338350

339-
This tutorial assumes that a signer is setup to serve the certificates API. The
351+
This page assumes that a signer is setup to serve the certificates API. The
340352
Kubernetes controller manager provides a default implementation of a signer. To
341353
enable it, pass the `--cluster-signing-cert-file` and
342354
`--cluster-signing-key-file` parameters to the controller manager with paths to
343355
your Certificate Authority's keypair.
344356

345-

0 commit comments

Comments
 (0)