Creating certificates
IBM® Cloud Private cert-manager is the Kubernetes certificate manager controller shared service that is used to generate and manage certificates based on the jetstack/cert-manager project .
- About cert-manager
- Adding a certificate to a Kubernetes workload
- Adding a certificate to a Kubernetes Ingress
About cert-manager
You can use the IBM Cloud Private cert-manager to create and mount a certificate to a Kubernetes Deployment, StatefulSet, or DaemonSet. You can also create and add a certificate to a Kubernetes Ingress.
Issuer, ClusterIssuer, and Certificate are Kubernetes resource types that were introduced to support certificate generation and lifecycle management.
IBM Cloud Private has one ClusterIssuer, icp-ca-issuer
, that holds an IBM Cloud Private self-signed CA certificate and key pair. The certificate and key pair are stored as a Secret, cluster-ca-cert
, within the kube-system namespace and are generated when you install IBM Cloud Private. You can create your own issuers for your own workloads after installation.
See the following list to learn how IBM Cloud Private cert-manager works:
- The Issuer signs new certificates and key pairs.
- The certificate represents an X.509 certificate and key pair for TLS or authentication.
- The certificate is stored as a Kubernetes Secret.
- The certificate is renewed automatically.
Adding a certificate to a Kubernetes workload
An icp-ca-issuer
is automatically created as a ClusterIssuer for each IBM Cloud Private installation. This Issuer contains the self-signed IBM Cloud Private cluster CA and is accessible from all namespaces. More Issuers (namespace-scoped) or ClusterIssuers (cluster-scoped) can be defined.
-
Define the Issuer.
See the following example of a Secret that contains a CA certificate and key pair:
apiVersion: v1 data: # base64 encoded PEM tls.crt: LS0tLS...tLS0tCg== tls.key: LS0tLS...tLS0tLQo= kind: Secret metadata: name: hello-deployment-tls-ca-key-pair namespace: default type: kubernetes.io/tls
See the following example of an Issuer that references the previous Secret:
apiVersion: certmanager.k8s.io/v1alpha1 kind: Issuer metadata: name: hello-deployment-tls namespace: foobar spec: ca: secretName: hello-deployment-tls-ca-key-pair
-
Define the certificate.
The following example defines a certificate that uses the Issuer, which is referenced in the previous step:
apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: hello-deployment-tls-1 namespace: foobar spec: # name of the tls secret to store # the generated certificate/key pair secretName: hello-deployment-tls-1 issuerRef: # issuer created in step 1 name: hello-deployment-tls # ClusterIssuers can be referenced # by changing the kind here. # the default value is Issuer (i.e. # a locally namespaced Issuer) kind: Issuer commonName: "foo1.bar1" dnsNames: # one more fully-qualified domain name # can be defined here - foo1.bar1
The following code example defines a certificate that uses the icp-ca-issuer that was created during installation.
apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: hello-deployment-tls-1 namespace: foobar spec: # name of the tls secret to store # the generated certificate/key pair secretName: hello-deployment-tls-1 issuerRef: # issuer created in step 1 name: icp-ca-issuer # ClusterIssuers can be referenced # by changing the kind here. # the default value is Issuer (i.e. # a locally namespaced Issuer) kind: ClusterIssuer commonName: "foo1.bar1" dnsNames: # one more fully-qualified domain name # can be defined here - foo1.bar1
-
Mount the Secret to the Deployment, DaemonSet, or StatefulSet.
The Kubernetes Secret that contains the certificate is mounted to the file system in the same manner as any other secret. For more information, see the Kubernetes documentation .
Adding a certificate to Kubernetes Ingress
The Ingress Kubernetes resource type is used to expose services to an external network. Cert-manager generated certificates can be added to Ingress resources. IBM Cloud Private provides a NGINX Kubernetes Ingress point out-of-the-box.
Handling Multiple Domain Names
Requests to multiple virtual hosts can be handled by the same Ingress. Each virtual host can be terminated with its own certificates. In this case, the fully-qualified domain name in the TLS/HTTPS request is used to identify the requested virtual host. The TLS-SNI protocol extension defines this process.
Complete the following procedure to secure the Kubernetes Ingress:
-
Define the Issuer.
An
icp-ca-issuer
is automatically created as a ClusterIssuer for each IBM Cloud Private installation. This issuer contains the self-signed IBM Cloud Private cluster CA and is accessible from all namespaces.More Issuers (namespace-scoped) or ClusterIssuers (cluster-scoped) can be defined with the following examples.
For the CA certificate and key pair, see the following example:
apiVersion: v1 data: # base64 encoded PEM tls.crt: LS0tLS...tLS0tCg== tls.key: LS0tLS...tLS0tLQo= kind: Secret metadata: name: hello-deployment-tls-ca-key-pair namespace: default type: kubernetes.io/tls
For the Issuer, see the following example:
apiVersion: certmanager.k8s.io/v1alpha1 kind: Issuer metadata: name: hello-deployment-tls namespace: foobar spec: ca: secretName: hello-deployment-tls-ca-key-pair
-
Define the certificate.
The following example defines a certificate that uses the Issuer in the previous step:
apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: hello-deployment-tls-1 namespace: foobar spec: # name of the tls secret to store # the generated certificate/key pair secretName: hello-deployment-tls-1 issuerRef: # issuer created in step 1 name: hello-deployment-tls # ClusterIssuers can be referenced # by changing the kind here. # the default value is Issuer (i.e. # a locally namespaced Issuer) kind: Issuer commonName: "foo1.bar1" dnsNames: # one more fully-qualified domain name # can be defined here - foo1.bar1
Cert-manager creates the certificate based on the certificate resource definition and stores it as a Kubernetes secret.
The following example defines a certificate that uses the
icp-ca-issuer
that was created during installation:apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: hello-deployment-tls-1 namespace: foobar spec: # name of the tls secret to store # the generated certificate/key pair secretName: hello-deployment-tls-1 issuerRef: # issuer created in step 1 name: icp-ca-issuer # ClusterIssuers can be referenced # by changing the kind here. # the default value is Issuer (i.e. # a locally namespaced Issuer) kind: ClusterIssuer commonName: "foo1.bar1" dnsNames: # one more fully-qualified domain name # can be defined here - foo1.bar1
-
Add the secret to the Kubernetes Ingress.
The following example defines a TLS-enabled Kubernetes Ingress that is integrated with cert-manager:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: hello-k8s-ingress-tls annotations: kubernetes.io/ingress.class: "nginx" ingress.kubernetes.io/rewrite-target: "/" spec: tls: # k8s ingress defines different tls certificates # for each nginx server blocks. # k8s ingress default cert is used if # no host-specific secret specified - hosts: # this is the fully-qualified domain name # of the first server block - foo1.bar1 # certificate hello-k8s-ingress-tls-1 # is only used by foo1.bar1 secretName: hello-k8s-ingress-tls-1 - hosts: # this is the fully-qualified domain name # of the second server block - foo2.bar2 # certificate hello-k8s-ingress-tls-2 # is only used by foo2.bar2 secretName: hello-k8s-ingress-tls-2 rules: # each server block redirects request # to its own backend service - host: foo1.bar1 http: paths: - backend: serviceName: hello-world-svc servicePort: 80 path: /fb - host: foo2.bar2 http: paths: - backend: serviceName: hello-world-svc servicePort: 80 path: /fb
Note: Certificates that are created by cert-manager are automatically renewed before expiration. Workloads must pick up the new certificates.