Skip to content

필사 모드: Ingress TLS の自動化 — cert-manager と ACME による証明書の完全自動化

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

はじめに

本番クラスタで TLS 証明書を手作業で管理していた頃を思い出してみましょう。90 日間の Let’s Encrypt 証明書を毎回更新するためにカレンダーにリマインダーを設定し、有効期限の直前に慌てて更新スクリプトを実行していたものです。証明書をひとつ忘れただけで、深夜に「サイトが開かない」という呼び出しを受けることもしばしばでした。

cert-manager はこの問題を根本から解決します。Kubernetes ネイティブのコントローラーとして、証明書の発行、更新、失効というライフサイクル全体を宣言的に管理します。Ingress にアノテーションを 1 行付けるだけで、残りは cert-manager が ACME プロトコルで Let’s Encrypt と通信して証明書を取得し、有効期限前に自動で更新してくれます。

2026 年現在の状況にも触れておきます。Ingress API は事実上 frozen の状態で、これ以上新しい機能は追加されません。後継の標準は Gateway API であり、cert-manager も Gateway API の TLS 自動化をサポートしています。ingress-nginx はメンテナンスモードに移行し、主にセキュリティパッチのみが管理される流れなので、新規構築であれば Gateway API も併せて検討するのがよいでしょう。本記事では Ingress を中心に説明しつつ、Gateway API との連携も最後に扱います。

本記事の目標は次のとおりです。

- cert-manager の CRD 構造とコントロールフローを正確に理解する

- HTTP-01 と DNS-01 チャレンジの違いと選択基準を確立する

- ワイルドカード証明書を安全に発行する

- アノテーションベースの統合(ingress-shim)の動作原理を把握する

- 更新と有効期限を Prometheus で監視する

- 社内 CA と HashiCorp Vault Issuer を連携する

- チャレンジ失敗を体系的に診断する

cert-manager のアーキテクチャ

cert-manager は複数の CRD(Custom Resource Definition)と、それを調整するコントローラーで構成されています。まず中心となるリソースの関係を図で理解すると、全体の流れが明確になります。

┌──────────────────────────────────────────────────────────┐

│ Issuer / ClusterIssuer (証明書の発行主体を定義) │

│ - ACME(Let's Encrypt), CA, Vault, SelfSigned ... │

└───────────────────────────┬──────────────────────────────┘

│ 参照

┌──────────────────────────────────────────────────────────┐

│ Certificate (望ましい証明書の宣言的な仕様) │

│ - dnsNames, secretName, issuerRef, duration ... │

└───────────────────────────┬──────────────────────────────┘

│ 発行要求を生成

┌──────────────────────────────────────────────────────────┐

│ CertificateRequest (単一の発行試行、CSR を含む) │

└───────────────────────────┬──────────────────────────────┘

│ ACME の場合

┌──────────────────────────────────────────────────────────┐

│ Order (ACME の注文 = ひとつの発行処理)│

└───────────────────────────┬──────────────────────────────┘

│ ドメイン所有の検証

┌──────────────────────────────────────────────────────────┐

│ Challenge (HTTP-01 または DNS-01 の検証) │

└───────────────────────────┬──────────────────────────────┘

│ 成功時

┌──────────────────────────────────────────────────────────┐

│ Secret (kubernetes.io/tls) tls.crt + tls.key を保存 │

└──────────────────────────────────────────────────────────┘

各リソースの役割を整理すると次のとおりです。

| リソース | スコープ | 役割 |

|---|---|---|

| Issuer | ネームスペース | そのネームスペース内でのみ証明書を発行 |

| ClusterIssuer | クラスタ全体 | すべてのネームスペースで共有する発行主体 |

| Certificate | ネームスペース | 望ましい証明書の最終状態を宣言 |

| CertificateRequest | ネームスペース | 1 回の CSR 発行試行を表現 |

| Order | ネームスペース | ACME 発行処理(複数ドメインのまとまり) |

| Challenge | ネームスペース | ドメイン所有証明の単位(HTTP-01/DNS-01) |

ここで重要なメンタルモデルは、Certificate は望ましい状態(desired state)であり、残りの子リソースはその状態を達成するために cert-manager が自動的に生成・消滅させる中間生成物だという点です。運用者は通常、Issuer/ClusterIssuer と Certificate(あるいは Ingress アノテーション)だけを直接扱い、CertificateRequest/Order/Challenge はデバッグ時だけ見ることになります。

インストール

cert-manager は Helm または静的マニフェストでインストールします。本番では CRD を明示的に管理することを推奨します。

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.17.0 \

--set crds.enabled=true

インストール確認

kubectl get pods -n cert-manager

kubectl get crd | grep cert-manager.io

インストールが完了すると、3 つの中心的な Pod が起動します。`cert-manager`(コントローラー)、`cert-manager-webhook`(検証/変換 Webhook)、`cert-manager-cainjector`(CA バンドル注入器)です。Webhook が正常に動作していないと CRD の適用自体が拒否されるため、インストール直後に Webhook Pod の状態を必ず確認します。

ACME チャレンジ: ドメイン所有の証明

Let’s Encrypt のような ACME CA が証明書を発行するには、要求者が当該ドメインを実際に管理していることを証明する必要があります。ACME プロトコル(RFC 8555)はこれをチャレンジ(challenge)として定義しており、cert-manager は HTTP-01 と DNS-01 の 2 種類をサポートしています。

HTTP-01 チャレンジの流れ

ユーザードメイン: app.example.com

1. cert-manager -> ACME サーバー: app.example.com の証明書を注文

2. ACME サーバー -> cert-manager: トークン発行 + 検証パスの案内

3. cert-manager: 一時的な Pod/Service/Ingress を作成

パス /.well-known/acme-challenge/<token> の応答を準備

4. ACME サーバー -> http://app.example.com/.well-known/acme-challenge/<token>

(80 番ポートへの HTTP リクエスト)

5. 応答が期待するキー認可値と一致すれば検証成功

6. ACME サーバー -> cert-manager: 証明書を発行

7. cert-manager: 一時リソースを整理 + Secret を保存

HTTP-01 は 80 番ポートに入ってくる外部インターネットトラフィックがクラスタの Ingress まで到達する必要があります。つまり、ドメインの A レコードが Ingress のパブリック IP を指していること、そしてファイアウォールで 80 番ポートが開いていることが必要です。

DNS-01 チャレンジの流れ

ユーザードメイン: app.example.com (または *.example.com)

1. cert-manager -> ACME サーバー: 証明書を注文

2. ACME サーバー -> cert-manager: トークンを発行

3. cert-manager -> DNS プロバイダ API:

_acme-challenge.example.com の TXT レコードに検証値を登録

4. ACME サーバー -> DNS ルックアップ: _acme-challenge.example.com の TXT を確認

5. TXT 値が一致すれば検証成功

6. ACME サーバー -> cert-manager: 証明書を発行

7. cert-manager: TXT レコードを整理 + Secret を保存

DNS-01 はインバウンドトラフィックがまったく不要です。代わりに cert-manager が DNS プロバイダ(Route53、Cloud DNS、Cloudflare など)の API 認証情報を持ち、TXT レコードを動的に作成・削除できる必要があります。

HTTP-01 と DNS-01 の比較

| 項目 | HTTP-01 | DNS-01 |

|---|---|---|

| 検証方式 | 80 番ポートの HTTP 応答 | DNS TXT レコード |

| インバウンドトラフィック | 必要(パブリック IP + 80 番ポート) | 不要 |

| ワイルドカード証明書 | 不可 | 可能(必須) |

| DNS API 認証情報 | 不要 | 必要 |

| 内部網/プライベートクラスタ | 困難 | 適合 |

| 検証の遅延 | 速い(秒単位) | DNS 伝播待ちが必要 |

| マルチドメイン SAN | ドメインごとの HTTP 検証 | TXT のまとめ検証 |

| 主な失敗原因 | ルーティング/ファイアウォール/リダイレクト | DNS 権限/伝播の遅延 |

選択基準を単純化すると次のようになります。公開された単一ドメインでインバウンドの 80 番ポートを開けるなら HTTP-01 が最も簡単です。ワイルドカード証明書が必要、インバウンドを開けないプライベートクラスタ、あるいは多数のドメインを一度に処理したい場合は DNS-01 を選びます。

ClusterIssuer の構成

ほとんどの環境では、クラスタ全体で共有できる ClusterIssuer を使います。まず Let’s Encrypt のステージングと本番の 2 つを作ることを推奨します。ステージングはレート制限が緩くテストに適しており、本番は信頼される証明書を発行しますが発行回数の制限が厳しいです。

HTTP-01 方式の ClusterIssuer

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

name: letsencrypt-staging

spec:

acme:

server: https://acme-staging-v02.api.letsencrypt.org/directory

email: platform@example.com

privateKeySecretRef:

name: letsencrypt-staging-account-key

solvers:

- http01:

ingress:

ingressClassName: nginx

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

name: letsencrypt-prod

spec:

acme:

server: https://acme-v02.api.letsencrypt.org/directory

email: platform@example.com

privateKeySecretRef:

name: letsencrypt-prod-account-key

solvers:

- http01:

ingress:

ingressClassName: nginx

`privateKeySecretRef` は ACME アカウントキーを保存する Secret の名前です。初めて ClusterIssuer を適用すると、cert-manager が自動的に ACME アカウントを登録し、この Secret にアカウントキーを保管します。この Secret を削除するとアカウントの再登録が発生するため注意します。

DNS-01 方式の ClusterIssuer(Route53 の例)

DNS-01 を使うには DNS プロバイダの API 認証情報が必要です。AWS Route53 を例にすると、IAM 認証情報または IRSA(IAM Roles for Service Accounts)を使います。

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

name: letsencrypt-dns

spec:

acme:

server: https://acme-v02.api.letsencrypt.org/directory

email: platform@example.com

privateKeySecretRef:

name: letsencrypt-dns-account-key

solvers:

- dns01:

route53:

region: ap-northeast-2

hostedZoneID: Z0123456789ABCDEFGHIJ

IRSA を使う場合 accessKeyID/secretAccessKey は省略可能

selector:

dnsZones:

- example.com

複数のソルバーを selector で分岐させることもできます。たとえば `*.example.com` は DNS-01、それ以外の公開ドメインは HTTP-01 で処理するように、ひとつの ClusterIssuer に 2 つのソルバーを定義できます。

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

name: letsencrypt-mixed

spec:

acme:

server: https://acme-v02.api.letsencrypt.org/directory

email: platform@example.com

privateKeySecretRef:

name: letsencrypt-mixed-account-key

solvers:

- dns01:

route53:

region: ap-northeast-2

hostedZoneID: Z0123456789ABCDEFGHIJ

selector:

dnsZones:

- example.com

- http01:

ingress:

ingressClassName: nginx

cert-manager は要求されたドメインが selector の dnsZones と最も具体的にマッチするソルバーを優先して選択します。

Certificate リソースを直接記述する

Ingress アノテーションを使うと Certificate が自動生成されますが、明示的に Certificate を記述すると発行ポリシーをより細かく制御できます。

apiVersion: cert-manager.io/v1

kind: Certificate

metadata:

name: app-tls

namespace: production

spec:

secretName: app-tls

duration: 2160h # 90 日

renewBefore: 720h # 有効期限の 30 日前に更新

privateKey:

algorithm: ECDSA

size: 256

rotationPolicy: Always

dnsNames:

- app.example.com

- www.app.example.com

issuerRef:

name: letsencrypt-prod

kind: ClusterIssuer

group: cert-manager.io

主なフィールドを説明します。

- `secretName`: 発行された証明書が保存される Secret です。タイプは `kubernetes.io/tls` で、`tls.crt`、`tls.key` のキーを持ちます。

- `renewBefore`: 有効期限の何日前に更新するかを指定します。デフォルトは証明書寿命の 3 分の 1 の時点です。

- `privateKey.rotationPolicy: Always` は更新のたびに新しいキーを生成します。セキュリティ上推奨されます。

- `issuerRef`: どの Issuer/ClusterIssuer を使うかを指定します。

ワイルドカード証明書

ワイルドカード証明書(`*.example.com`)は必ず DNS-01 チャレンジでのみ発行できます。HTTP-01 はワイルドカードをサポートしません。ACME 仕様上、ワイルドカードドメインの所有証明は DNS レコードでのみ可能だからです。

apiVersion: cert-manager.io/v1

kind: Certificate

metadata:

name: wildcard-example-tls

namespace: production

spec:

secretName: wildcard-example-tls

dnsNames:

- "*.example.com"

- "example.com"

issuerRef:

name: letsencrypt-dns

kind: ClusterIssuer

group: cert-manager.io

上の例のように、ワイルドカードと apex ドメインを一緒に SAN に入れるのが一般的です。ワイルドカード `*.example.com` は `example.com` 自体をカバーしないため、両方が必要です。

Ingress 統合(ingress-shim)

cert-manager の最も便利な機能は、Ingress アノテーションベースの自動化です。これを担うコンポーネントが ingress-shim です。Ingress リソースに特定のアノテーションを付けると、ingress-shim がその Ingress の TLS 仕様を読み取り、Certificate リソースを自動的に作成・管理します。

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

name: app-ingress

namespace: production

annotations:

cert-manager.io/cluster-issuer: letsencrypt-prod

spec:

ingressClassName: nginx

tls:

- hosts:

- app.example.com

secretName: app-tls

rules:

- host: app.example.com

http:

paths:

- path: /

pathType: Prefix

backend:

service:

name: app-svc

port:

number: 8080

このマニフェストを適用すると、次の順序で動作します。

1. Ingress を作成(cert-manager.io/cluster-issuer アノテーションを含む)

2. ingress-shim が tls[].secretName と hosts を読み取る

3. ingress-shim が Certificate リソースを自動作成

- dnsNames = tls[].hosts

- secretName = tls[].secretName

- issuerRef = アノテーションの cluster-issuer

4. cert-manager 本体のコントローラーが Certificate を処理

-> CertificateRequest -> Order -> Challenge -> Secret 発行

5. Ingress Controller が発行された Secret を TLS 終端に使用

主なアノテーションは次のとおりです。

| アノテーション | 意味 |

|---|---|

| cert-manager.io/cluster-issuer | 使用する ClusterIssuer 名 |

| cert-manager.io/issuer | 使用するネームスペース Issuer 名 |

| cert-manager.io/common-name | 証明書の CN を明示 |

| cert-manager.io/duration | 証明書の寿命 |

| cert-manager.io/renew-before | 更新タイミング |

注意点は、ingress-shim が自動生成した Certificate を直接編集してはいけないということです。次の調整周期で ingress-shim が Ingress の仕様を基準に上書きするためです。細かい制御が必要な場合は、アノテーションを外して Certificate を直接管理するほうがよいでしょう。

運用: 更新と有効期限の監視

cert-manager は更新を自動で処理しますが、「自動だから気にしなくてよい」という態度は危険です。DNS API 認証情報の失効、レート制限の到達、ソルバー設定の誤りなどで更新が静かに失敗すると、結局証明書が期限切れになります。したがって監視は必須です。

証明書の状態確認

すべての Certificate の状態を一目で確認

kubectl get certificate -A

特定の証明書の詳細(Ready 条件、有効期限の確認)

kubectl describe certificate app-tls -n production

cert-manager が追跡している発行の進行状況

kubectl get certificaterequest,order,challenge -A

`kubectl get certificate` の出力で READY 列が True であれば正常です。False の場合は describe で Events と Conditions を確認します。

Prometheus メトリクス

cert-manager はデフォルトで 9402 番ポートに Prometheus メトリクスを公開します。最も重要なメトリクスは証明書の有効期限時刻です。

証明書の有効期限時刻(Unix epoch 秒)

certmanager_certificate_expiration_timestamp_seconds

証明書の更新時刻

certmanager_certificate_renewal_timestamp_seconds

Ready 状態ゲージ(1=Ready, 0=NotReady)

certmanager_certificate_ready_status

ACME クライアントのリクエスト数(ステータスコード別)

certmanager_http_acme_client_request_count

コントローラーのキュー処理遅延

certmanager_controller_sync_call_count

期限間近のアラートは PromQL で次のように構成します。式そのものはコードブロック内に置く必要があります。

7 日(604800 秒)以内に期限切れ予定の証明書を警告

certmanager_certificate_expiration_timestamp_seconds - time() < 604800

Ready 状態でない証明書を警告

certmanager_certificate_ready_status == 0

Alertmanager ルールの例は次のとおりです。

groups:

- name: cert-manager

rules:

- alert: CertificateExpiringSoon

expr: certmanager_certificate_expiration_timestamp_seconds - time() < 604800

for: 1h

labels:

severity: warning

annotations:

summary: "証明書が 7 日以内に期限切れ予定"

description: "namespace/name ラベルを確認してください"

- alert: CertificateNotReady

expr: certmanager_certificate_ready_status == 0

for: 30m

labels:

severity: critical

annotations:

summary: "証明書が Ready 状態ではありません"

ServiceMonitor を通じて Prometheus Operator が cert-manager メトリクスを収集するように設定します。

apiVersion: monitoring.coreos.com/v1

kind: ServiceMonitor

metadata:

name: cert-manager

namespace: cert-manager

labels:

release: kube-prometheus-stack

spec:

selector:

matchLabels:

app.kubernetes.io/name: cert-manager

endpoints:

- port: http-metrics

interval: 60s

レート制限の管理

Let’s Encrypt の本番エンドポイントは厳格なレート制限を適用します。代表的には、登録ドメインあたり週に 50 個の証明書制限があります。テストは必ずステージングエンドポイントで行い、本番発行は実際に必要な場合のみにします。CI パイプラインでクラスタを繰り返し作成・削除すると、すぐに制限に達するため注意します。

社内 CA と Vault Issuer

すべての証明書が公開 CA から来る必要はありません。内部サービス間の mTLS や社内ドメインは、社内 CA で発行するのが一般的です。

自己 CA Issuer

まずルートまたは中間 CA のキーペアを Secret として保管し、その後 CA Issuer を作成します。

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

name: internal-ca

spec:

ca:

secretName: internal-ca-key-pair

apiVersion: cert-manager.io/v1

kind: Certificate

metadata:

name: internal-svc-tls

namespace: backend

spec:

secretName: internal-svc-tls

dnsNames:

- payments.svc.cluster.local

issuerRef:

name: internal-ca

kind: ClusterIssuer

この方式は ACME チャレンジが不要なため、インバウンド/DNS の要件なしに即座に発行されます。ただし、クライアントが社内 CA を信頼するように CA バンドルを配布する必要があります。

HashiCorp Vault Issuer

Vault の PKI シークレットエンジンをバックエンドとして使うと、集中型の証明書発行ポリシーと監査ログを活用できます。

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

name: vault-issuer

spec:

vault:

server: https://vault.internal.example.com:8200

path: pki_int/sign/example-dot-com

auth:

kubernetes:

role: cert-manager

mountPath: /v1/auth/kubernetes

serviceAccountRef:

name: cert-manager-vault

Vault Issuer は Vault の Kubernetes 認証方式を通じて ServiceAccount トークンで認証します。`path` は Vault PKI エンジンの署名パスであり、Vault 側でその role に許可ドメインと寿命ポリシーを定義します。この構造は証明書発行権限を Vault ポリシーで一元化できるため、規制環境で有利です。

Gateway API との関係

前述のとおり、Ingress API は frozen の状態であり Gateway API が後継の標準です。cert-manager は Gateway API に対しても自動証明書発行をサポートしています。ingress-shim が Ingress のアノテーションを見て Certificate を作るように、Gateway リソースのアノテーションを見て Certificate を作る方式です。

apiVersion: gateway.networking.k8s.io/v1

kind: Gateway

metadata:

name: app-gateway

namespace: production

annotations:

cert-manager.io/cluster-issuer: letsencrypt-prod

spec:

gatewayClassName: nginx

listeners:

- name: https

protocol: HTTPS

port: 443

hostname: app.example.com

tls:

mode: Terminate

certificateRefs:

- name: app-tls

kind: Secret

この機能は、かつては実験的(experimental)な機能ゲートを通じて有効化する必要があった時期がありましたが、最新バージョンでは Gateway API サポートが正式な機能として定着する流れです。cert-manager コントローラーのフラグで Gateway API サポートを有効にでき、listener の hostname を dnsNames、certificateRefs の最初の Secret を secretName として使い Certificate を自動生成します。新規クラスタを構築するなら、Ingress の代わりに Gateway API ベースの TLS 自動化を最初から採用することを推奨します。

トラブルシューティング: チャレンジ失敗の診断

チャレンジの失敗は cert-manager 運用で最も多い問題です。次の診断フローをたどれば、ほとんどの原因を絞り込めます。

証明書が Ready=False

kubectl describe certificate を確認

Events にどんなメッセージ?

┌─────────┴──────────┐

│ │

Order 作成済み Order なし/エラー

│ │

▼ ▼

kubectl describe issuerRef のタイプミス?

order ... ClusterIssuer は Ready?

│ ACME アカウント登録失敗?

Challenge 状態を確認

kubectl describe challenge ...

┌────┴─────┐

│ │

HTTP-01 DNS-01

│ │

▼ ▼

1. DNS A レコードが 1. DNS API 認証情報は有効?

Ingress IP? 2. TXT レコードが実際に作成された?

2. 80 番ポートに 3. DNS 伝播は完了?

外部からアクセス可? 4. CNAME 委任の設定?

3. チャレンジパスが 5. zone selector がマッチ?

200 を返す?

4. 強制 HTTPS

リダイレクトが

80 番検証を妨害?

HTTP-01 失敗のよくある原因

最も頻繁な失敗は、80 番ポートに入ってきた ACME 検証リクエストが強制 HTTPS リダイレクトに阻まれるケースです。ingress-nginx の `ssl-redirect` が有効だと、検証パスまで HTTPS に転送して検証が壊れることがあります。cert-manager が作成する一時的な検証 Ingress はこれを回避するよう設計されていますが、グローバル設定が強く効いていると問題になります。

次のコマンドで検証パスが実際に応答するか確認します。URL のトークン部分は実際の challenge リソースで確認します。

進行中の challenge を確認

kubectl get challenge -A

challenge 詳細でトークンと URL を確認

kubectl describe challenge <challenge-name> -n production

外部から検証パスを直接呼び出す(TOKEN は上で確認した値)

curl -v http://app.example.com/.well-known/acme-challenge/TOKEN

応答が 200 でない、または 301/302 で HTTPS にリダイレクトされる場合は、ルーティングとリダイレクト設定を点検します。

DNS-01 失敗のよくある原因

DNS-01 では、TXT レコードが実際に作成されたか、そして伝播したかを直接確認することが核心です。

cert-manager が登録した TXT レコードを直接照会

dig +short TXT _acme-challenge.example.com

権威ネームサーバーに直接問い合わせ

dig @ns-1.example-dns.com TXT _acme-challenge.example.com

challenge イベントで DNS プロバイダのエラーを確認

kubectl describe challenge <challenge-name> -n production

DNS API 認証情報が失効していたり権限が不足していると、TXT レコードの作成自体が失敗します。また CNAME 委任を使う場合は、委任先ゾーンにレコードが作られたかを確認する必要があります。伝播が遅いプロバイダでは propagation のタイムアウトを増やす必要があるかもしれません。

cmctl で素早く診断する

cert-manager は `cmctl` という診断 CLI を提供します。

証明書の状態を要約

cmctl status certificate app-tls -n production

強制更新をトリガー

cmctl renew app-tls -n production

発行の進行状況を追跡

cmctl inspect secret app-tls -n production

運用チェックリスト

本番導入の前後で次の項目を点検すると、障害を大きく減らせます。

- ステージング ClusterIssuer で先に検証してから本番へ切り替えたか

- ClusterIssuer が Ready 状態で ACME アカウントが正常に登録されているか

- ワイルドカード証明書は DNS-01 ソルバーを使っているか

- DNS-01 API 認証情報に失効/ローテーションのポリシーがあるか

- `certmanager_certificate_expiration_timestamp_seconds` に基づく期限アラートがあるか

- `certmanager_certificate_ready_status == 0` のアラートが設定されているか

- renewBefore の値が運用対応時間を考慮して十分に余裕があるか

- 証明書 Secret をバックアップ、または GitOps で再現可能か

- cert-manager Webhook Pod の高可用性(レプリカ 2 個以上)を確保したか

- Let’s Encrypt のレート制限を CI 環境で使い切らないよう隔離したか

- 社内 CA を使う場合、クライアントに CA バンドルが配布されているか

- 新規構築なら、Gateway API ベースの TLS 自動化を検討したか

おわりに

cert-manager は TLS 証明書管理を「定期的に気を配るべき運用負担」から「宣言すれば勝手に回るインフラ」へと変えてくれます。要点は、CRD 構造を正確に理解し、環境に合ったチャレンジ方式を選び、自動更新を盲信せず監視も併せて構築することです。

HTTP-01 は公開された単一ドメインに簡単で、DNS-01 はワイルドカードとプライベート環境に必須です。アノテーションベースの ingress-shim はほとんどのユースケースを 1 行で解決しますが、細かい制御が必要なら Certificate を直接扱えばよいでしょう。社内 CA と Vault Issuer で内部証明書まで一元化すれば、クラスタ全体の TLS をひとつの一貫した流れで管理できます。

最後に 2026 年の方向性をもう一度強調すると、Ingress API は frozen であり Gateway API が後継です。今から新たに構築するなら、Gateway API ベースの TLS 自動化を最初から考慮することが将来のための選択です。

参考資料

- cert-manager 公式ドキュメント: https://cert-manager.io/docs/

- cert-manager Ingress の使い方: https://cert-manager.io/docs/usage/ingress/

- cert-manager ACME 設定: https://cert-manager.io/docs/configuration/acme/

- cert-manager Gateway API サポート: https://cert-manager.io/docs/usage/gateway/

- Kubernetes Ingress の概念: https://kubernetes.io/docs/concepts/services-networking/ingress/

- ingress-nginx 公式ドキュメント: https://kubernetes.github.io/ingress-nginx/

- Let’s Encrypt ドキュメントとレート制限: https://letsencrypt.org/docs/

- Gateway API: https://gateway-api.sigs.k8s.io/

- RFC 8555 (ACME プロトコル): https://datatracker.ietf.org/doc/html/rfc8555

- HashiCorp Vault PKI シークレットエンジン: https://developer.hashicorp.com/vault/docs/secrets/pki

- cert-manager Vault Issuer: https://cert-manager.io/docs/configuration/vault/

현재 단락 (1/438)

本番クラスタで TLS 証明書を手作業で管理していた頃を思い出してみましょう。90 日間の Let’s Encrypt 証明書を毎回更新するためにカレンダーにリマインダーを設定し、有効期限の直前に慌て...

작성 글자: 0원문 글자: 16,471작성 단락: 0/438