Welcome to new things

[Technical] [Electronic work] [Gadget] [Game] memo writing

How to automatically update Let's Encrypt on Kubernetes (GKE)

PS

Since the procedure had changed, we have rewritten it in a separate article, along with how to obtain a wildcard certificate.

www.ekwbtblog.com

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

  1. Download and unzip from https://github.com/kubernetes/helm/releases
  2. 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

  1. Create any account by [GCP]-[IAM and Administration]-[Service Account]-[Create Service Account
  2. Add the account created in [GCP]-[IAM and Administration]-[IAM]-[Add] (with the role [DNS]-[DNS Admin])
  3. [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

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com

www.ekwbtblog.com