Manage TLS Certificates in a Cluster [page]deterministic
Kubernetes provides a `certificates.k8s.io` API, which lets you provision TLS certificates signed by a Certificate Authority (CA) that you control. These CAs and certificates can be used by your workloads to establish trust.
The `certificates.k8s.io` API uses a protocol that is similar to the [ACME draft](https://github.com/ietf-wg-acme/acme/).
> Note: Certificates created using the `certificates.k8s.io` API are signed by a [dedicated CA](#configuring-your-cluster-to-provide-signing). It is possible to configure your cluster to use the cluster root CA for this purpose, but you should never rely on this. Do not assume that these certificates will validate against the cluster root CA.
##
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://jqlang.github.io/jq/](https://jqlang.github.io/jq/).
## Trusting TLS in a cluster
Trusting the [custom CA](#configuring-your-cluster-to-provide-signing) from an application running as a pod usually requires some extra application configuration. You will need to add the CA certificate bundle to the list of CA certificates that the TLS client or server trusts. For example, you would do this with a Golang TLS config by parsing the certificate chain and adding the parsed certificates to the `RootCAs` field in the [`tls.Config`](https://pkg.go.dev/crypto/tls#Config) struct.
> Note: Even though the custom CA certificate may be included in the filesystem (in the ConfigMap `kube-root-ca.crt`), you should not use that certificate authority for any purpose other than to verify internal Kubernetes endpoints. An example of an internal Kubernetes endpoint is the Service named `kubernetes` in the default namespace.
If you want to use a custom certificate authority for your workloads, you should generate that CA separately, and distribute its CA certificate using a [ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap) that your pods have access to read.
## Requesting a certificate
The following section demonstrates how to create a TLS certificate for a Kubernetes service accessed through DNS.
> Note: This tutorial uses CFSSL: Cloudflare's PKI and TLS toolkit See the Cloudflare blog article [Introducing CFSSL - CloudFlare's PKI toolkit](https://blog.cloudflare.com/introducing-cfssl/) for more information.
## Create a certificate signing request
Generate a private key and certificate signing request (or CSR) by running the following command:
```shell cat <<EOF | cfssl genkey - | cfssljson -bare server { "hosts": [ "my-svc.my-namespace.svc.cluster.local", "my-pod.my-namespace.pod.cluster.local", "192.0.2.24", "10.0.34.2" ], "CN": "my-pod.my-namespace.pod.cluster.local", "key": { "algo": "ecdsa", "size": 256 } } EOF ```
Where `192.0.2.24` is the service's cluster IP, `my-svc.my-namespace.svc.cluster.local` is the service's DNS name, `10.0.34.2` is the pod's IP and `my-pod.my-namespace.pod.cluster.local` is the pod's DNS name. You should see output similar to:
``` 2022/02/01 11:45:32 [INFO] generate received request 2022/02/01 11:45:32 [INFO] received CSR 2022/02/01 11:45:32 [INFO] generating key: ecdsa-256 2022/02/01 11:45:32 [INFO] encoded CSR ```
This command generates two files; it generates `server.csr` containing the PEM 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 CertificateSigningRequest object to send to the Kubernetes API
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 - apiVersion: certificates.k8s.io/ …(trimmed)