cert-managerとRoute53を使ったTLS証明書の作成
概要
以前に投稿した「オンプレ環境でk8s環境の構築(v1.34)」で構築したkubernetesクラスタ上
でweb apiなどを動作させる際に、traefikやnginxなどのIngressをリバースプロキシとして使用することが多いかと思います。
上記の場合に、cert-managerとRoute53を使ってLet's Encryptで作成したワイルドカード証明書を使ったTLS通信を実現する方法を解説します。
参考にした記事
下記Qiitaの記事を参考に、環境やバージョン差異があってそのままでは動作しなかった箇所を修正させていただきました。
Kubernetes cert-managerでRoute53で作成したドメインの証明書を作成し、Ingressで利用する。
前提条件
今回の記事の内容を実施するにあたって、下記が前提条件となります。
使用するドメインについては、Route53に管理を委譲できるものであればどこで取得しても問題ないはずです。筆者はお名前.comで取得したドメインを使用しています。
- ドメインを所有している
- awsアカウントを作成していて、Route53でドメインを管理している
cert-managerのインストール
下記コマンドを実行して、helmでcert-managerをインストールします。
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.18.2 \
--set installCRDs=true \
--set 'extraArgs={--dns01-recursive-nameservers-only,--dns01-recursive-nameservers=8.8.8.8:53\,1.1.1.1:53}'
ポイントとしては、「helm install」のオプションで「--set 'extraArgs={--dns01-recursive-nameservers-only,--dns01-recursive-nameservers=8.8.8.8:53,1.1.1.1:53}'」をつけていることです。
オンプレクラスターの名前解決に使用するLAN内のDNSサーバーと、Let's Encryptから参照するRoute53の両方に同じドメインを登録することになりますが、このオプションを付けておかないと証明書発行に必要になるtxtレコードの参照でLAN内のDNSサーバーを参照してしまい、証明書の作成に失敗するためです。
issuerの作成
Route53にLet's EncryptのDNS検証で必要になるtxtレコードを作成するための準備をします。
まずは、公式ドキュメントに沿ってIAMを作成してください。
cert-manager Route53
上記手順で作成したIAMのシークレットアクセスキーをkubernetesのシークレットに登録します。
kubectl -n cert-manager create secret generic prod-route53-credentials-secret --from-literal=secret-access-key=<SECRET_ACCESS_KEY>
次に、下記のyamlを作成してClusterIssuerを作成します。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-issuer
spec:
acme:
# stagingで試して、問題なく証明書ができたらprodで再実行
# server: https://acme-v02.api.letsencrypt.org/directory
server: https://acme-staging-v02.api.letsencrypt.org/directory # staging
email: <YOUR_MAIL>
privateKeySecretRef:
name: letsencrypt-issuer
solvers:
- selector:
dnsZones:
- "example.net"
dns01:
route53:
region: ap-northeast-1
hostedZoneID: <Route53 Zone ID>
accessKeyID: <ACCESS_KEY> // アクセスキー
secretAccessKeySecretRef:
name: prod-route53-credentials-secret
key: secret-access-key
kubectl apply実行後に、ステータスに問題がなければ大丈夫です。
kubectl describe clusterissuer
・・・
Status:
Acme:
Last Private Key Hash: xxxxxxxxxxxxxxxxxxx
Last Registered Email: <YOUR_MAIL>
Conditions:
Last Transition Time: 2025-09-20T02:08:00Z
Message: The ACME account was registered with the ACME server
Observed Generation: 1
Reason: ACMEAccountRegistered
Status: True
Type: Ready
・・・
IngressでTLS証明書を使用する場合は特定のアノテーションを付けることで自動で作成出来ますが、動作確認のため、今回は手動で作成してみます。
下記yamlファイルを作成してapplyすると証明書が作成されます。
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-net # 任意の名前に変更
spec:
secretName: example-net-tls # 任意の名前に変更
duration: 2160h # 90d
renewBefore: 360h # 15d
commonName: "*.example.net" # 任意の名前に変更
isCA: false
usages:
- server auth
- client auth
dnsNames:
- example.net # 使用するドメインに変更
- "*.example.net" # commonNameに設定したものと合わせる
# Issuer references are always required.
issuerRef:
name: letsencrypt-issuer
kind: ClusterIssuer
下記コマンドで、問題なく証明書が作成されているか確認出来ます。
kubectl get certificate
NAME READY SECRET AGE
example-net True example-net-tls 10d
まとめ
今回はcert-managerとRoute53を使ってLet's Encryptの証明書を作成する方法をまとめました。
かなりざっくりとまとめた内容ですが、少しでも参考になれば幸いです。
Discussion