cert‐manager: Let's Encryptを使ったSSL certificateの取得 - oomichi/try-kubernetes GitHub Wiki

cert-managerはKubernetesクラスタ上にデプロイされるSSL certificateを管理するコンポーネントである。

Let's Encrypt

SSL certificateの取得元として無料で使えるLet's Encryptが利用されることが多い。 Let's Encryptは無料であるが、そのcertificateの有効期限が3か月と限られているため、3カ月毎に更新が必要となる。 Let's Encryptでcertificateを取得・更新するためには、そのDNSドメインを管理していることを証明するために、そのDNSドメインに特定のTXTレコードをLet's Encryptから指定された値を設定する必要がある。

cert-managerはこの手順を自動化してくれる。また、cert-managerが管理しているcertificateの有効期限を定期的にチェックし、有効期限が迫ると自動更新を行ってくれる。 よって、DNSドメインを変更するに必要な設定をcert-managerに渡す必要がある。以下はAWS Route53で管理しているDNSドメインを使用した際の設定である。

設定手順

cert-managerのインストール:

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm upgrade cert-manager jetstack/cert-manager \
    --install \
    --create-namespace \
    --wait \
    --namespace cert-manager \
    --set installCRDs=true

AWS Route53を変更(TXTレコードの追加)するためのAWSクレデンシャルの設定。cert-managerと同じNamespaceに設定する必要がある:

kubectl -n cert-manager create secret generic route53-credentials-secret \
  --from-literal=access-key-id=AKIAXXXXXXXXXXXXXXXXXX \
  --from-literal=secret-access-key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

cluster-issuerリソースの作成:

$ cat clusterissuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-issuer
spec:
  acme:
    # server: https://acme-staging-v02.api.letsencrypt.org/directory
    server: https://acme-v02.api.letsencrypt.org/directory
    email: <<Let's Encryptに渡すEmailアドレス>>
    privateKeySecretRef:
      name: letsencrypt-issuer
    solvers:
    - dns01:
        route53:
          hostedZoneID: <<Route53のhosted Zone ID>>
          region: <<us-west-1などのAWSリージョン>>
          accessKeyIDSecretRef:
            name: route53-credentials-secret
            key: access-key-id
          secretAccessKeySecretRef:
            name: route53-credentials-secret
            key: secret-access-key
$
$ kubectl apply -f clusterissuer.yaml

Ingressに固定のAnnotationを追加。cert-managerはこのAnnotationのついたIngressからSSL certificate取得に必要な情報(ドメイン、certificate格納先Secretなど)を取得し、処理を行う:

$ cat ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-issuer
    acme.cert-manager.io/http01-edit-in-place: "true"
  name: <<Ingress名>>
spec:
  ingressClassName: webapprouting.kubernetes.azure.com
  rules:
  - host: <<ドメイン名>>
    http:
      paths:
      - backend:
          service:
            name: <<バックエンドService名>>
            port:
              number: <<バックエンドServiceのポート番号>>
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - <<ドメイン名>>
    secretName: secret-tls
$ kubectl apply -f ingress.yaml
⚠️ **GitHub.com Fallback** ⚠️