cert‐manager: Let's Encryptを使ったSSL certificateの取得 - oomichi/try-kubernetes GitHub Wiki
cert-managerはKubernetesクラスタ上にデプロイされるSSL certificateを管理するコンポーネントである。
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