Merge pull request #31595 from sftim/20220102_revise_managing_tls_in_a_cluster_task

Tidy page “Manage TLS Certificates in a Cluster”
pull/31721/head
Kubernetes Prow Robot 2022-02-11 08:50:25 -08:00 committed by GitHub
commit 1592f3a445
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 56 additions and 45 deletions

View File

@ -29,13 +29,18 @@ these certificates will validate against the cluster root CA.
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{< include "task-tutorial-prereqs.md" >}}
You need the `cfssl` tool. You can download `cfssl` from
[https://github.com/cloudflare/cfssl/releases](https://github.com/cloudflare/cfssl/releases).
Some steps in this page use the `jq` tool. If you don't have `jq`, you can
install it via your operating system's software sources, or fetch it from
[https://stedolan.github.io/jq/](https://stedolan.github.io/jq/).
<!-- steps -->
## Trusting TLS in a Cluster
## Trusting TLS in a cluster
Trusting the custom CA from an application running as a pod usually requires
some extra application configuration. You will need to add the CA certificate
@ -48,7 +53,7 @@ You can distribute the CA certificate as a
[ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap) that your
pods have access to use.
## Requesting a Certificate
## Requesting a certificate
The following section demonstrates how to create a TLS certificate for a
Kubernetes service accessed through DNS.
@ -57,12 +62,7 @@ Kubernetes service accessed through DNS.
This tutorial uses CFSSL: Cloudflare's PKI and TLS toolkit [click here](https://blog.cloudflare.com/introducing-cfssl/) to know more.
{{< /note >}}
## Download and install CFSSL
The cfssl tools used in this example can be downloaded at
[https://github.com/cloudflare/cfssl/releases](https://github.com/cloudflare/cfssl/releases).
## Create a Certificate Signing Request
## Create a certificate signing request
Generate a private key and certificate signing request (or CSR) by running
the following command:
@ -98,14 +98,14 @@ is the pod's DNS name. You should see the output similar to:
```
This command generates two files; it generates `server.csr` containing the PEM
encoded [pkcs#10](https://tools.ietf.org/html/rfc2986) certification request,
encoded [PKCS#10](https://tools.ietf.org/html/rfc2986) certification request,
and `server-key.pem` containing the PEM encoded key to the certificate that
is still to be created.
## Create a Certificate Signing Request object to send to the Kubernetes API
## Create a CertificateSigningRequest object to send to the Kubernetes API
Generate a CSR yaml blob and send it to the apiserver by running the following
command:
Generate a CSR manifest (in YAML), and send it to the API server. You can do that by
running the following command:
```shell
cat <<EOF | kubectl apply -f -
@ -124,7 +124,7 @@ EOF
```
Notice that the `server.csr` file created in step 1 is base64 encoded
and stashed in the `.spec.request` field. We are also requesting a
and stashed in the `.spec.request` field. You are also requesting a
certificate with the "digital signature", "key encipherment", and "server
auth" key usages, signed by an example `example.com/serving` signer.
A specific `signerName` must be requested.
@ -157,7 +157,7 @@ Subject Alternative Names:
Events: <none>
```
## Get the Certificate Signing Request Approved
## Get the CertificateSigningRequest approved {#get-the-certificate-signing-request-approved}
Approving the [certificate signing request](/docs/reference/access-authn-authz/certificate-signing-requests/)
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 yourname@example.com <none>
This means the certificate request has been approved and is waiting for the
requested signer to sign it.
## Sign the Certificate Signing Request
## Sign the CertificateSigningRequest {#sign-the-certificate-signing-request}
Next, you'll play the part of a certificate signer, issue the certificate, and upload it to the API.
A signer would typically watch the Certificate Signing Request API for objects with its `signerName`,
check that they have been approved, sign certificates for those requests,
A signer would typically watch the CertificateSigningRequest API for objects with its `signerName`,
check that they have been approved, sign certificates for those requests,
and update the API object status with the issued certificate.
### Create a Certificate Authority
You need an authority to provide the digital signature on the new certificate.
First, create a signing certificate by running the following:
```shell
@ -210,7 +212,7 @@ cat <<EOF | cfssl gencert -initca - | cfssljson -bare ca
EOF
```
You should see the output similar to:
You should see output similar to:
```none
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:
This produces a certificate authority key file (`ca-key.pem`) and certificate (`ca.pem`).
### Issue a Certificate
### Issue a certificate
{{< codenew file="tls/server-signing-config.json" >}}
@ -245,7 +247,7 @@ You should see the output similar to:
This produces a signed serving certificate file, `ca-signed-server.pem`.
### Upload the Signed Certificate
### Upload the signed certificate
Finally, populate the signed certificate in the API object's status:
@ -256,24 +258,27 @@ kubectl get csr my-svc.my-namespace -o json | \
```
{{< note >}}
This uses the command line tool [jq](https://stedolan.github.io/jq/) to populate the base64-encoded content in the `.status.certificate` field.
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.
This uses the command line tool [`jq`](https://stedolan.github.io/jq/) to populate the base64-encoded
content in the `.status.certificate` field.
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.
{{< /note >}}
Once the CSR is approved and the signed certificate is uploaded you should see the following:
Once the CSR is approved and the signed certificate is uploaded, run:
```shell
kubectl get csr
```
The output is similar to:
```none
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
my-svc.my-namespace 20m example.com/serving yourname@example.com <none> Approved,Issued
```
## Download the Certificate and Use It
## Download the certificate and use it
Now, as the requesting user, you can download the issued certificate
Now, as the requesting user, you can download the issued certificate
and save it to a `server.crt` file by running the following:
```shell
@ -281,37 +286,48 @@ kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \
| base64 --decode > server.crt
```
Now you can populate `server.crt` and `server-key.pem` in a secret and mount
it into a pod to use as the keypair to start your HTTPS server:
Now you can populate `server.crt` and `server-key.pem` in a
{{< glossary_tooltip text="Secret" term_id="secret" >}}
that you could later mount into a Pod (for example, to use with a webserver
that serves HTTPS).
```shell
kubectl create secret tls server --cert server.crt --key server-key.pem
kubectl create secret tls server --cert server.crt --key server-key.pem
```
```none
secret/server created
```
Finally, you can populate `ca.pem` in a configmap and use it as the trust root
to verify the serving certificate:
Finally, you can populate `ca.pem` into a {< glossary_tooltip text="ConfigMap" term_id="configmap" >}}
and use it as the trust root to verify the serving certificate:
```shell
kubectl create configmap example-serving-ca --from-file ca.crt=ca.pem
kubectl create configmap example-serving-ca --from-file ca.crt=ca.pem
```
```none
configmap/example-serving-ca created
```
## Approving Certificate Signing Requests
## Approving CertificateSigningRequests {#approving-certificate-signing-requests}
A Kubernetes administrator (with appropriate permissions) can manually approve
(or deny) Certificate Signing Requests by using the `kubectl certificate
(or deny) CertificateSigningRequests by using the `kubectl certificate
approve` and `kubectl certificate deny` commands. However if you intend
to make heavy usage of this API, you might consider writing an automated
certificates controller.
Whether a machine or a human using kubectl as above, the role of the approver is
{{< caution >}}
The ability to approve CSRs decides who trusts whom within your environment. The
ability to approve CSRs should not be granted broadly or lightly.
You should make sure that you confidently understand both the verification requirements
that fall on the approver **and** the repercussions of issuing a specific certificate
before you grant the `approve` permission.
{{< /caution >}}
Whether a machine or a human using kubectl as above, the role of the _approver_ is
to verify that the CSR satisfies two requirements:
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:
If and only if these two requirements are met, the approver should approve
the CSR and otherwise should deny the CSR.
## A Word of Warning on the Approval Permission
For more information on certificate approval and access control, read
the [Certificate Signing Requests](/docs/reference/access-authn-authz/certificate-signing-requests/)
reference page.
The ability to approve CSRs decides who trusts whom within your environment. The
ability to approve CSRs should not be granted broadly or lightly. The
requirements of the challenge noted in the previous section and the
repercussions of issuing a specific certificate should be fully understood
before granting this permission.
## Configuring your cluster to provide signing
## A Note to Cluster Administrators
This tutorial assumes that a signer is setup to serve the certificates API. The
This page assumes that a signer is setup to serve the certificates API. The
Kubernetes controller manager provides a default implementation of a signer. To
enable it, pass the `--cluster-signing-cert-file` and
`--cluster-signing-key-file` parameters to the controller manager with paths to
your Certificate Authority's keypair.