Kubernetes 環境でサービスを公開する際、TLS 証明書の管理は避けて通れない課題です。手動での証明書発行・更新は、運用負荷の増大と期限切れによる障害リスクを招きます。CNCF Graduated プロジェクトである cert-manager は、TLS 証明書のライフサイクルを完全に自動化し、この課題を根本的に解決します。Kubo のような K3s ベースの Kubernetes プラットフォームでは、cert-manager の導入によりゼロタッチの証明書管理が実現できます。
cert-manager の基本概念とアーキテクチャ
cert-manager は、Kubernetes および OpenShift クラスタ上で TLS 証明書の発行と更新を自動化するアドオンです。GitHub リポジトリで活発に開発が続けられており、クラウドネイティブ環境における証明書管理のデファクトスタンダードとなっています。
主要コンポーネント
cert-manager は以下のコンポーネントで構成されます:
- Controller: Certificate リソースの状態を監視し、証明書の発行・更新を実行
- Webhook: CRD のバリデーションと Admission Control を担当
- CA Injector: Webhook やカスタムリソースに CA バンドルを自動注入
- ACME Solver: Let's Encrypt 等の ACME プロバイダーとのチャレンジ処理を実行
サポートする発行元(Issuer)
cert-manager のドキュメントによると、以下の認証局に対応しています:
- Let's Encrypt (ACME プロトコル): 無料の TLS 証明書を自動発行
- HashiCorp Vault: エンタープライズ PKI との連携
- CyberArk Certificate Manager: 企業向け証明書管理
- プライベート PKI: 自社認証局による証明書発行
- Self-signed: テスト環境向けの自己署名証明書
Captain.AI は Kubernetes 環境全体のセキュリティ状態を AI で監視し、証明書の期限切れリスクを事前に検知する運用支援を提供します。
インストールと初期設定
Helm によるインストール
# cert-manager の Helm リポジトリを追加
helm repo add jetstack https://charts.jetstack.io
helm repo update
# CRD を含めてインストール
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.18.1 \
--set crds.enabled=true
インストールの確認
# Pod の状態を確認
kubectl get pods -n cert-manager
# 出力例:
# cert-manager-5c6866597-zw7kh 1/1 Running 0
# cert-manager-cainjector-577f6d9fd7-b 1/1 Running 0
# cert-manager-webhook-56f8b4f8d-hsqvg 1/1 Running 0
ClusterIssuer の作成
Funky Si's Blog の実践ガイドを参考に、Let's Encrypt 用の ClusterIssuer を設定します:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: nginx
ステージング環境でのテスト用 Issuer も用意しておくことを推奨します:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-staging-key
solvers:
- http01:
ingress:
class: nginx
Kubo では K3s に標準搭載される Traefik Ingress Controller との連携も可能です。
ACME チャレンジの仕組みと選択
Let's Encrypt は ACME(Automatic Certificate Management Environment)プロトコルを使用して、ドメインの所有権を検証します。KodeKloud の解説によると、cert-manager は主に 2 つのチャレンジタイプをサポートしています。
HTTP-01 チャレンジ
solvers:
- http01:
ingress:
class: nginx
- let's encrypt がドメインの
-.well-known-acme-challenge-エンドポイントにアクセスして検証 - メリット: 設定がシンプル、追加の DNS 権限不要
- デメリット: ポート 80 が外部からアクセス可能である必要がある、ワイルドカード証明書は非対応
DNS-01 チャレンジ
solvers:
- dns01:
cloudflare:
email: admin@example.com
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
- DNS レコードにトークンを設定して検証
- メリット: ワイルドカード証明書をサポート、ポート 80 不要
- デメリット: DNS プロバイダーの API 認証情報が必要
The Dougie Chronicles が詳しく解説しているように、Cloudflare を使った DNS-01 チャレンジは、特にワイルドカード証明書が必要な場合に最も一般的な選択肢です。
サポートされる DNS プロバイダー:
Ingress との連携と自動証明書発行
cert-manager の最も強力な機能の一つが、Ingress リソースとの自動連携です。
アノテーションによる自動発行
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- app.example.com
secretName: app-tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80
cert-manager.io/cluster-issuer アノテーションを追加するだけで、cert-manager が自動的に Certificate リソースを作成し、Let's Encrypt から証明書を取得して Kubernetes Secret に保存します。
Gateway API との連携
Kubernetes Gateway API を使う場合も同様に対応しています:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-route
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
parentRefs:
- name: my-gateway
hostnames:
- "app.example.com"
rules:
- backendRefs:
- name: my-app
port: 80
自動更新の仕組み
Medium の詳細記事が解説するように、cert-manager は証明書の有効期限を常に監視し、renewBefore で指定された期間前に自動的に更新を実行します。Let's Encrypt の証明書は 90 日間有効で、デフォルトでは期限の 30 日前に更新が開始されます。
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-tls
spec:
secretName: app-tls-secret
duration: 2160h # 90 日
renewBefore: 720h # 30 日前に更新
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- app.example.com
- www.app.example.com
Captain.AI と連携すれば、証明書の更新失敗を AI が検知し、自動的に対処策を提案するワークフローの構築が可能です。
トラブルシューティングとベストプラクティス
よくある問題と解決策
oneuptime のガイドや F5 のベストプラクティスを参考に:
# Certificate のステータス確認
kubectl describe certificate app-tls -n default
# CertificateRequest の確認
kubectl get certificaterequest -n default
# Order の確認(ACME の場合)
kubectl get order -n default
# Challenge の確認
kubectl get challenge -n default
# cert-manager のログ確認
kubectl logs -n cert-manager -l app=cert-manager
よくあるエラーと対処
| エラー | 原因 | 対処 |
|---|---|---|
Waiting for HTTP-01 challenge | ポート 80 がブロック | ファイアウォール設定を確認 |
DNS record not yet propagated | DNS 伝播の遅延 | --dns01-recursive-nameservers を設定 |
rate limited | Let's Encrypt のレート制限 | ステージング環境でテスト |
account is not registered | ACME 登録の失敗 | email フィールドを確認 |
セキュリティのベストプラクティス
- ステージング Issuer でテストしてから本番 Issuer に切り替え
- RBAC で Certificate リソースへのアクセスを制限
- Apurv のテックノートが推奨するように、API トークンは Kubernetes Secret で安全に管理
- 証明書の監視アラートを設定(Prometheus メトリクス
certmanager_certificate_expiration_timestamp_seconds)
まとめ
cert-manager は Kubernetes 環境における TLS 証明書管理の労力を劇的に削減します。本記事のポイントをまとめると:
- cert-manager は証明書の発行・更新・管理を完全に自動化
- Let's Encrypt との連携で無料の TLS 証明書を自動取得
- HTTP-01 / DNS-01 チャレンジの選択で様々な環境に対応
- Ingress アノテーション で既存のワークロードに最小限の変更で導入
- 自動更新 により証明書期限切れのリスクをゼロに
Kubo は K3s ベースで CNCF エコシステムとの高い親和性を持ち、cert-manager の導入により安全なサービス公開を簡単に実現できます。Kubernetes 環境のセキュリティ強化に取り組む方は、ぜひ Kubo をご検討ください。
AI を活用した Kubernetes 運用の自動化については、Captain.AI の詳細をご確認ください。導入のご相談はお問い合わせからお気軽にどうぞ。