Cert Manager
cert-managerは、Kubernetes内でTLS証明書を自動的に管理するためのツールです。Let's Encryptなどの認証局から証明書を自動取得・更新します。
cert-managerを使用すると、TLS証明書の取得と更新を完全に自動化できます。
概要
cert-managerの主な特徴:
- TLS証明書の自動取得と更新
- Let's Encrypt、Venafi、HashiCorp Vaultなど複数の認証局に対応
- ACME(HTTP-01、DNS-01)チャレンジサポート
- 証明書の自動ローテーション
- Ingressとの統合
インストール
1. cert-managerのインストール
Helmを使用してインストールします。
# Helm リポジトリの追加
helm repo add jetstack https://charts.jetstack.io
helm repo update
# cert-managerのインストール
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.13.0 \
--set installCRDs=true
2. インストールの確認
# Podの確認
kubectl get pods -n cert-manager
# CRDの確認
kubectl get crd | grep cert-manager
ClusterIssuerの設定
Let's Encrypt(Staging)
まずはステージング環境で動作確認を行います。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: nginx
Let's Encrypt(Production)
動作確認後、本番環境用のIssuerを作成します。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
DNS-01チャレンジ(Cloudflare)
ワイルドカード証明書を取得する場合はDNS-01チャレンジを使用します。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-dns
solvers:
- dns01:
cloudflare:
email: your-email@example.com
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
証明書の取得
Ingressでの自動証明書取得
Ingressにアノテーションを追加することで、自動的に証明書を取得できます。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- example.com
secretName: example-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80
Certificate リソースの直接作成
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-cert
namespace: default
spec:
secretName: example-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- example.com
- www.example.com
証明書の確認
Certificateリソースの確認
# Certificate一覧
kubectl get certificate
# 詳細確認
kubectl describe certificate example-cert
# CertificateRequestの確認
kubectl get certificaterequest
# Orderの確認
kubectl get order
# Challengeの確認
kubectl get challenge
証明書の内容確認
# Secretから証明書を取得
kubectl get secret example-tls -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout
トラブルシューティング
証明書が発行されない場合
Let's Encryptには厳しいレート制限があります。テストはステージング環境で行ってください。
# ログの確認
kubectl logs -n cert-manager deploy/cert-manager
# Challengeの詳細確認
kubectl describe challenge <challenge-name>
# Certificateの詳細確認
kubectl describe certificate <cert-name>
一般的な問題
- HTTP-01チャレンジが失敗: Ingressが正しく設定されているか確認
- DNS-01チャレンジが失敗: DNSプロバイダーのAPIトークンが正しいか確認
- レート制限エラー: ステージング環境で十分にテストしてから本番環境へ
ベストプラクティス
- ステージング環境でテスト: 本番前に必ずステージング環境で動作確認
- 証明書の有効期限監視: 自動更新が失敗した場合に備えてモニタリング
- ClusterIssuerの使用: 名前空間を跨いで使用する場合はClusterIssuer
- 適切なチャレンジ方法: ワイルドカード証明書にはDNS-01を使用
証明書の更新
cert-managerは証明書の有効期限が30日を切ると自動的に更新を試みます。
手動更新
# Certificateの削除と再作成
kubectl delete certificate example-cert
kubectl apply -f certificate.yaml
# またはSecretの削除(自動的に再発行される)
kubectl delete secret example-tls