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

参考リンク