PS
Since the procedure had changed, we have rewritten it in a separate article, along with how to obtain a wildcard certificate.
Postscript ends here (original article below)
It was convenient to use "cert-manager" + DNS authentication to automatically update Let's Encrypt on Kubernetes (GKE) without processing on the service side.
Procedure (up to cert-manager installation)
Helm Installation
To install "cert-manager" using the Kubernetes package manager "Helm", first install Helm and create a Helm account. (Details are described in https://github.com/ahmetb/gke-letsencrypt)
Install Helm Client
- Download and unzip from https://github.com/kubernetes/helm/releases
- make executable through a path
mv linux-amd64/helm /usr/local/bin/helm sudo chown root:root /usr/local/bin/helm sudo chmod 755 /usr/local/bin/helm
Create, authorize, and update Helm accounts (tiller) to Kubernetes
kubectl create serviceaccount -n kube-system tiller kubectl create clusterrolebinding tiller-binding \ --clusterrole=cluster-admin \ --serviceaccount kube-system:tiller helm init --service-account tiller helm repo update
cert-manager installation
helm install --name cert-manager --version v0.5.2 \ --namespace kube-system stable/cert-manager
If you get an error, the information may be out of date, so please get the latest information from the cert-manager installation manual of cert-manager.
Overall flow
This completes the installation of cert-manager. Before proceeding to the next step, we will briefly describe the entire process.
How cert-manager works
The cert-manager consists largely of "Issuer" and "Certificate". Certificate" mainly contains settings related to domains and certificates, while "Issuer" contains settings related to the means of acquiring certificates and accounts. The acquisition of a certificate in "Certificate" is executed in "Issuer" and stored in the secret defined in "Certificate" to make the certificate available.
Mechanism of Certificate Usage
The certificate obtained above is stored in Kubernetes as a secret. The certificate is then used by referencing the secret from Ingress. (The method of using certificates with Ingress is described in another article "How to communicate HTTPS with Kubernetes (GKE) (Ingress version)").
How Let's Encrypt DNS Authentication Works
In Let's Encrypt DNS authentication, Let's Encrypt checks if the claimant is the owner of the domain by checking if the specified value was written to the DNS record. Therefore, cert-manager allows the Issuer to edit DNS records by associating a service account with the Issuer that can edit GCP's DNS records, allowing the Issuer to pass the check from Let's Encrypt.
Procedure (remaining)
GCP Service Account Creation
Create a service account that allows you to edit DNS records
- Create any account by [GCP]-[IAM and Administration]-[Service Account]-[Create Service Account
- Add the account created in [GCP]-[IAM and Administration]-[IAM]-[Add] (with the role [DNS]-[DNS Admin])
- [GCP]-[APIs and Services]-[Authentication Information]-[Create Authentication Information]-[Service Account Key] to create a key JSON file (select service account and save key file with key type as JSON)
Register the key file in Kubernetes secret so that the contents of the key file can be referenced by cert-manager.
kubectl create secret generic <シークレット名> \ --from-file=key.json=<キーファイルパス>
Issuer made
issuer.yaml
apiVersion: certmanager.k8s.io/v1alpha1 kind: Issuer metadata: name: letsencrypt-issuer namespace: default spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: <Let's Encryptに登録するemail> privateKeySecretRef: name: letsencrypt-issuer dns01: providers: - name: clouddns clouddns: serviceAccountSecretRef: name: <DNSサービスアカウントのキーファイルのシークレット名> key: key.json project: <GCPプロジェクト名>
kubectl apply -f issuer.yaml
Certificate作成
certificate.yaml
apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: example-com-certificate namespace: default spec: secretName: example-com-certificate # Ingressから参照するシークレット名 issuerRef: name: letsencrypt-issuer # Issuer名 kind: Issuer commonName: example.com # ドメイン名 dnsNames: - example.com # ドメイン名 acme: config: - dns01: provider: clouddns # Issuerのprovider名 domains: - example.com # ドメイン名
kubectl apply -f certificate.yaml
confirmation
kubectl describe certificate,issuer,clusterissuer --all-namespaces
You can check the status at If there are no errors, the certificate has been successfully obtained. If there is an error, check the cert-manager logs to determine the cause of the error using the following method.
- [GCP]-[Kubernetes Engine]-[workload]-[filter-off]-[cert-manager]-[managed-bot]-[bot-name]-[log]-[Container Logs
Certificate Usage
A sample of Ingress is described below. By setting the secret of tls to the secret name set in Certificate, the certificate of Ingress and Certificate are linked. (How to use Certificate with Ingress is described in another article "How to communicate HTTPS with Kubernetes (GKE) (Ingress version)")
ingress.yaml
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress annotations: kubernetes.io/ingress.allow-http: "false" kubernetes.io/ingress.global-static-ip-name: "<static ip名>" spec: tls: - secretName: example-com-certificate backend: serviceName: nginx servicePort: 80
supplementary explanation
After repeated trial and error, you may get stuck on Let's Encrypt Limitations, so it is better to test it in staging instead of in production at first.
For staging, set "server" in "issuer.yaml" to "https://acme-staging-v02.api.letsencrypt.org/directory
".
The certificate obtained by staging will be a suspicious site, but it is still accessible.
You can also uninstall and reinstall "cert-manager" at
helm list # List of installed packages helm delete <cert-manager名> # <cert-manager>削除 helm install \ --replace \ # To reinstall with the same name, add "--replace". --name <cert-manager名> \ --namespace kube-system \ stable/cert-manager
reference information
- https://qiita.com/apstndb/items/3a39a1e6acacbbc30765
- https://github.com/ahmetb/gke-letsencrypt
- https://cert-manager.readthedocs.io/en/latest/
- https://medium.com/google-cloud/kubernetes-w-lets-encrypt-cloud-dns-c888b2ff8c0e
- https://github.com/jetstack/cert-manager/issues/339