cert-manager 導入&設定ガイド(FujiSSL ACME)
2025年10月20日
対象:Kubernetes(1.22+ 目安)。Helm or kubectl(CRDs)で導入。HTTP-01(Ingress) / DNS-01(Cloudflare/Route53)/ EAB(外部アカウントバインディング)対応。
外部公開における重要な注意
管理ツール「契約一覧」に表示される EAB KID / EAB HMAC Key は機密情報です。GitHub 等の公開リポジトリやブログ、資料に絶対に記載しないでください。Kubernetes Secret は namespaced に作成し、RBAC/バックアップの取り扱いに注意してください。
管理ツール「契約一覧」に表示される EAB KID / EAB HMAC Key は機密情報です。GitHub 等の公開リポジトリやブログ、資料に絶対に記載しないでください。Kubernetes Secret は namespaced に作成し、RBAC/バックアップの取り扱いに注意してください。
Contents
0. 前提とゴール
- FujiSSL 管理ツールで ACME 契約(OV) を作成済み、以下4点を控える:
ACMEサーバURL(例:https://ユーザによって異なります)/ドメイン(FQDN)/EAB KID/EAB HMAC Key - ゴール:Ingress の注釈だけで自動発行・自動更新(Let’s Encryptでは不可なOV + ACMEを FujiSSL で実現)。
1. cert-manager のインストール
方法A:Helm(推奨)
kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm upgrade --install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--set crds.enabled=true
# バージョン固定したい場合は --version v1.xx.x を付与
方法B:kubectl(CRDs マニフェスト)
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.crds.yaml
kubectl create namespace cert-manager
kubectl apply -n cert-manager -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
導入確認
kubectl -n cert-manager get pods で cert-manager/cainjector/webhook がすべて Running を確認。
2. EAB シークレットの作成
# 例:cert-manager 名前空間に保存(ClusterIssuer を使う想定)
kubectl -n cert-manager create secret generic fujissl-eab-secret \
--from-literal=hmac-key='<EAB_HMAC_KEY>'
- 名称は後続の Issuer/ClusterIssuer の
externalAccountBinding.keySecretRefと一致させます。 - KID は Secret ではなく、Issuer 定義内の
keyIDにそのまま記載します(リポジトリ公開は避けること)。
3. Issuer / ClusterIssuer の作成(FujiSSL ACME + EAB)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: fujissl-ov-issuer
spec:
acme:
server: 管理画面で取得したACMEサーバURL
email: admin@example.com
privateKeySecretRef:
name: fujissl-ov-account-key
externalAccountBinding:
keyID: <EAB_KID> # ← 管理ツール表示の KID
keySecretRef:
name: fujissl-eab-secret # ← 先ほど作成した Secret
key: hmac-key
solvers:
- http01:
ingress:
class: nginx # or "alb", "traefik" など
- namespaced 運用にしたい場合は
Issuerを使い、同一 namespace に Secret も配置。 - HTTP-01 を使う場合は上記そのままでOK。DNS-01 を使う場合は後述の solver を追記します。
4. HTTP-01(Ingress)での発行
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-https
annotations:
cert-manager.io/cluster-issuer: fujissl-ov-issuer
acme.cert-manager.io/http01-edit-in-place: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
- www.example.com
secretName: tls-example-com # ← 証明書が保存される Secret
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
- 80/TCP が到達可能であること(CDN を使う場合
/.well-known/acme-challenge/を素通しに)。 - 作成後、cert-manager が Order/Challenge を生成し、成功すれば
tls-example-comSecret に証明書が入ります。
5. DNS-01(Cloudflare / Route53)での発行
5-1) Cloudflare(API Token)
# API Token を Secret 化(最小権限:Zone.DNS:Edit)
kubectl -n cert-manager create secret generic cloudflare-api-token \
--from-literal=api-token='<CF_API_TOKEN>'
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: fujissl-ov-issuer
spec:
acme:
server: 管理画面で取得したACMEサーバURL
email: admin@example.com
privateKeySecretRef:
name: fujissl-ov-account-key
externalAccountBinding:
keyID: <EAB_KID>
keySecretRef:
name: fujissl-eab-secret
key: hmac-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
- 以後、Ingress 側は
tls.hostsに*.example.comなどを指定するとワイルドカードも自動発行されます。
5-2) AWS Route53(IRSA or Profile)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: fujissl-ov-issuer
spec:
acme:
server: 管理画面で取得したACMEサーバURL
email: admin@example.com
privateKeySecretRef:
name: fujissl-ov-account-key
externalAccountBinding:
keyID: <EAB_KID>
keySecretRef:
name: fujissl-eab-secret
key: hmac-key
solvers:
- dns01:
route53:
region: ap-northeast-1 # 変更
hostedZoneID: ZXXXXXXXXXXXX # 省略も可(自動検出に頼る運用も可)
role: arn:aws:iam::123456789012:role/cert-manager-dns # IRSA/RAM
- 必要権限:
route53:ChangeResourceRecordSets等。IRSA(ServiceAccount にロール付与)がおすすめ。 - アクセスキー直書きは避け、どうしても必要なら Secret で渡して RBAC・監査を徹底。
6. 動作確認とローテーション
# リソースの状態
kubectl get issuer,clusterissuer,certificate,order,challenge -A
# 失敗時の詳細
kubectl describe order <name> -n <ns>
kubectl describe challenge <name> -n <ns>
kubectl logs -n cert-manager deploy/cert-manager --tail=200
# 秘密鍵/証明書の中身確認(開発環境のみで)
kubectl get secret tls-example-com -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | less
- cert-manager は期限が近い証明書を自動で更新し、
secretNameを上書きします(Ingress 側の再起動は不要)。 - 周辺プロキシ/ゲートウェイが Secret をマウントしている場合は、サイドカーやリロード設定で追随させます。
7. DNS/ネットワークの実務メモ
- HTTP-01:対象 FQDN が Ingress へ到達(80/TCP)。
/.well-known/acme-challenge/はリライト/リダイレクト/キャッシュしない。 - DNS-01:TXT は
_acme-challenge.<FQDN>。ワイルドカードは_acme-challenge.example.comに集約。TTL は 60–300 秒。 - CDN:発行/更新時はチャレンジをバイパス(Cloudflare は灰色雲、または該当パスのキャッシュ無効)。
- CAA:独自運用している場合のみ、使用 CA を許可。誤設定は発行失敗の主要因。
8. セキュリティ(EAB/DNSトークン)
- EAB KID/HMAC・DNS API トークンは Kubernetes Secret に限定保存。GitOps 運用時は SealedSecrets/ExternalSecrets 等の仕組みで暗号化。
- RBAC:
get/list/watchのみ最小限付与。Secret の範囲は namespace 単位に分離。 - バックアップ:Secret を含む etcd バックアップの暗号化・持ち出し防止に注意。
9. トラブルシュート(定型)
- Order が失敗:
kubectl describe orderで理由を確認。CAA/到達性/権限の順で点検。 - HTTP-01 失敗:80/TCP 未開放/リダイレクトで別FQDNへ/WAF がブロック。
/.well-known/acme-challenge/を素通しに。 - DNS-01 失敗:TXT 値が反映前/委任ゾーンの編集漏れ。
dig +short TXT _acme-challenge.example.com @1.1.1.1で確認。 - Rate limit:検証は SAN を絞って回数を節約。問題が解消したら本番SANで再実行。
- Webhook 失敗:cert-manager の Pod/イベントログを確認。CRD のバージョン不整合に注意。
10. 追加例:Namespace ごとの Issuer、複数ドメイン
A) Namespace ローカル Issuer(隔離運用)
apiVersion: v1
kind: Secret
metadata:
name: fujissl-eab-secret
namespace: app
type: Opaque
data:
hmac-key: <base64-encoded EAB_HMAC_KEY>
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: fujissl-ov-issuer
namespace: app
spec:
acme:
server: 管理画面で取得したACMEサーバURL
email: app-admin@example.com
privateKeySecretRef:
name: fujissl-ov-account-key
externalAccountBinding:
keyID: <EAB_KID>
keySecretRef:
name: fujissl-eab-secret
key: hmac-key
solvers:
- http01:
ingress:
class: nginx
B) 1つの Ingress で複数FQDN
spec:
tls:
- hosts: [example.com, www.example.com, api.example.com]
secretName: tls-example-com
HTTP-01 の場合はすべての FQDN がこの Ingress に到達する必要あり。到達しない FQDN は DNS-01 を使う。
よく読まれている質問
- OV証明書 自動化手順(ACME対応)
- クロスサインが必要なのはどんな時ですか?また、利用者は何をすればよいのでしょうか?...
- DV証明書 自動化手順(ACME対応)
- Certbot インストール&設定ガイド(FujiSSL ACME)
- cert-manager 導入&設定ガイド(FujiSSL ACME)
- acme.sh インストール&設定ガイド(FujiSSL ACME)
- win-acme(Windows IIS)
- DNS 設定ガイド(HTTP-01 / DNS-01 共通)
- lego インストール&設定ガイド(FujiSSL ACME)
- 審査状況の確認
- 申請から発行までの間、どのようなメールが届きますか
- テスト証明書は発行していますか
- ファイル認証のクローラーのIPアドレスを教えてください
- FujiSSLは世界的CA「Sectigo」の中間認証局です
- FujiSSLのクーポンの有効期限はありますか?
- FujiSSLではどのACMEクライアントが使えますか?
- 身に覚えのない11円の請求がありました。なぜですか?
- 複数年プランについて
- キャンセルしたいのですが、返金はどのようにされますか。
- クライアント証明書発行までの流れ






