Kubernetes Certificate Manager (cert-manager) is a native Kubernetes controller helping you to issue certificates from a variety of sources, such as Let's Encrypt, HashiCorp Valut, a signing keypair and self-signed. The Certificate Manager ensures certificates are valid and up-to-date, and attempt to renew certificates at a configured time before expiry.
The Kubernetes Certificate Manager is installed on the Kubernetes cluster using the Helm Chart. The Helm Chart is the recommended approach to install the Certificate Manager on Kubernetes.
Helm
"Helm is a tool for managing Kubernetes charts. Charts are packages of pre-configured Kubernetes resources." and "Helm is a tool that streamlines installing and managing Kubernetes applications. Think of it like apt/yum/homebrew for Kubernetes." - Source: https://github.com/helm/helm
Helm is the client-side component and is required to install Helm on a Kubernetes cluster. Tiller is the server-side component which is installed using Helm.
Install Helm
- Go to the Helm releases page and download the latest binary file: https://github.com/helm/helm/releases
$ curl https://storage.googleapis.com/kubernetes-helm/helm-v2.11.0-linux-amd64.tar.gz -o ~/helm.tar.gz
- Extract the gzipped tar archive file to /usr/local/bin
$ sudo tar -xzf ~/helm.tar.gz -C /usr/local/bin --strip-components=1
-
Check if Helm is installed correctly by checking the version.
$ helm version Client: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"} Error: could not find tiller
The error is there because we didn't install Tiller yet on our Kubernetes platform.
When you've installed the Helm client correctly, we need to install the server component on the Kubernetes platform. The server component is named "Tiller" and is controlled using the "Helm" client.
- Create a service account for the Tiller component that has cluster-admin privileges on the platform
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: name: tiller namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: tiller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: tiller namespace: kube-system EOF
- Install the server component "Tiller" on your Kubernetes platform
$ helm init --service-account tiller # Or upgrade tiller $ helm init --upgrade --service-account tiller
- Check if Helm is installed correctly by checking the version
$ helm version Client: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"}
Certificate Manager
-
Install the Certificate Manager in the kube-system namespace using Helm
$ helm install \ --name cert-manager \ --namespace kube-system \ stable/cert-manager
-
Create a (Cluster)Issues (more docs @ https://cert-manager.readthedocs.io/en/latest/tutorials/acme/http-validation.html)
Staging environmentapiVersion: certmanager.k8s.io/v1alpha1 kind: ClusterIssuer metadata: name: letsencrypt-staging namespace: default spec: acme: # The ACME server URL server: https://acme-staging-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: support@hotflo.net # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-staging # Enable the HTTP-01 challenge provider http01: {}
Production environment
apiVersion: certmanager.k8s.io/v1alpha1 kind: ClusterIssuer metadata: name: letsencrypt-prod namespace: default spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: support@hotflo.net # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod # Enable the HTTP-01 challenge provider http01: {}
-
Create a service in Kubernetes which needs a ingress
-
Create an ingress for this service and add the
certmanager.k8s.io/cluster-issuer
annotation
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: # add an annotation indicating the issuer to use. certmanager.k8s.io/cluster-issuer: letsencrypt-prod name: myIngress namespace: myIngress spec: rules: - host: myingress.com http: paths: - backend: serviceName: myservice servicePort: 80 path: / tls: # < placing a host in the TLS config will indicate a cert should be created - hosts: - myingress.com secretName: myingress-cert # < cert-manager will store the created certificate in this secret
-
That's it ! Check if the certificate is requested using kubectl
$ kubectl get certificate $ kubectl describe certificate $certificate-name
You are now capable to secure all ingress endpoints without any more hassle!