証明書リソース
apiVersion: cert-manager.io/v1
kind: Certificate
cert-managerでは、Certificate
リソースは、証明書要求の人間が読める定義を表します。cert-managerは、この入力を使用して秘密鍵とCertificateRequest
リソースを生成し、Issuer
または ClusterIssuer
から署名付き証明書を取得します。署名付き証明書と秘密鍵は、指定されたSecret
リソースに格納されます。cert-managerは、証明書が期限切れになる前に自動更新されること、および要求された場合に再発行されることを保証します。
証明書を発行するには、まずIssuer
または ClusterIssuer
リソースを構成する必要があります。
証明書リソースの作成
Certificate
リソースは、証明書署名要求の生成に使用されるフィールドを指定します。この要求は、参照している発行者タイプによって処理されます。Certificates
は、certificate.spec.issuerRef
フィールドを指定することで、どの発行者から証明書を取得するかを指定します。
example.com
と www.example.com
のDNS名、spiffe://cluster.local/ns/sandbox/sa/example
URI サブジェクト代替名を持つ、90日間有効で期限切れの15日前に更新されるCertificate
リソースの例を以下に示します。Certificate
リソースが持つ可能性のあるすべてのオプションの網羅的なリストが含まれていますが、ラベル付きのフィールドのサブセットのみが必要です。
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-comnamespace: sandboxspec:# Secret names are always required.secretName: example-com-tls# secretTemplate is optional. If set, these annotations and labels will be# copied to the Secret named example-com-tls. These labels and annotations will# be re-reconciled if the Certificate's secretTemplate changes. secretTemplate# is also enforced, so relevant label and annotation changes on the Secret by a# third party will be overwriten by cert-manager to match the secretTemplate.secretTemplate:annotations:my-secret-annotation-1: "foo"my-secret-annotation-2: "bar"labels:my-secret-label: fooprivateKey:algorithm: RSAencoding: PKCS1size: 2048# keystores allows adding additional output formats. This is an example for reference only.keystores:pkcs12:create: truepasswordSecretRef:name: example-com-tls-keystorekey: passwordprofile: Modern2023duration: 2160h # 90drenewBefore: 360h # 15disCA: falseusages:- server auth- client authsubject:organizations:- cert-manager# Avoid using commonName for DNS names in end-entity (leaf) certificates. Unless you have a specific# need for it in your environment, use dnsNames exclusively to avoid issues with commonName.# Usually, commonName is used to give human-readable names to CA certificates and can be avoided for# other certificates.commonName: example.com# The literalSubject field is exclusive with subject and commonName. It allows# specifying the subject directly as a string. This is useful for when the order# of the subject fields is important or when the subject contains special types# which can be specified by their OID.## literalSubject: "O=jetstack, CN=example.com, 2.5.4.42=John, 2.5.4.4=Doe"# At least one of commonName (possibly through literalSubject), dnsNames, uris, emailAddresses, ipAddresses or otherNames is required.dnsNames:- example.com- www.example.comuris:- spiffe://cluster.local/ns/sandbox/sa/exampleemailAddresses:- john.doe@cert-manager.ioipAddresses:- 192.168.0.5# Needs cert-manager 1.14+ and "OtherNames" feature flagotherNames:# Should only supply oid of ut8 valued types- oid: 1.3.6.1.4.1.311.20.2.3 # User Principal Name "OID"utf8Value: upn@example.local# Issuer references are always required.issuerRef:name: ca-issuer# We can reference ClusterIssuers by changing the kind here.# The default value is Issuer (i.e. a locally namespaced Issuer)kind: Issuer# This is optional since cert-manager will default to this value however# if you are using an external issuer, change this to that issuer group.group: cert-manager.io
署名付き証明書は、発行者が要求された証明書を正常に発行すると、Certificate
と同じ名前空間にある example-com-tls
という名前のSecret
リソースに格納されます。
secretTemplate
が存在する場合、このプロパティに設定されたアノテーションとラベルはexample-com-tls
シークレットにコピーされます。両方のプロパティはオプションです。
Certificate
は、sandbox
名前空間(Certificate
リソースと同じ名前空間)にある ca-issuer
という名前の発行者を使用して発行されます。
注:すべての名前空間で
Certificate
リソースから参照できるIssuer
を作成する場合は、ClusterIssuer
リソースを作成し、certificate.spec.issuerRef.kind
フィールドをClusterIssuer
に設定する必要があります。
注:
renewBefore
とduration
フィールドは、Gotime.Duration
文字列形式を使用して指定する必要があります。この形式では、d
(日)サフィックスは使用できません。webhookコンポーネント
をインストールせずにこれを行うと、cert-managerが正しく機能しなくなる可能性があります#1269
。
注:
renewBefore
フィールドをduration
に非常に近い値に設定すると、Certificate
が常に更新期間内にある更新ループが発生する可能性があります。一部のIssuers
は、クロックスキューの問題を修正するために、発行時刻の前に発行されたX.509証明書にnotBefore
フィールドを設定し、これにより、証明書の有効期間が証明書の全期間よりも短くなります。たとえば、Let's Encryptは発行時刻の1時間前に設定するため、証明書の実際の*有効期間*は89日23時間になります(*全期間*は90日のままです)。
Certificate リソースでサポートされているフィールドの完全なリストは、APIリファレンスドキュメントにあります。
ターゲットシークレット
証明書が中間CAによって発行され、Issuer
が発行された証明書のチェーンを提供できる場合、tls.crt
の内容は、要求された証明書とその後の証明書チェーンになります。
さらに、認証局が既知の場合、対応するCA証明書はca.crt
キーを使用してシークレットに格納されます。たとえば、ACME発行者ではCAは不明であり、ca.crt
はシークレットに存在しません。発行時のca.crt
の値は、証明書を使用しているアプリケーションの信頼ストアにコピーできます。ただし、ca.crt
の値をアプリケーションの信頼ストアに直接マウントしないでください。証明書が更新されると更新されるためです(詳細については証明書の信頼を参照してください)。
cert-managerは、TLSが安全に実行されている状況では役に立たないため、意図的にルート証明書をtls.crt
に追加していません。詳細については、次の説明が含まれているRFC 5246セクション7.4.2を参照してください。
証明書検証にはルートキーを個別に配布する必要があるため、ルート証明機関を指定する自己署名証明書は、リモート側が検証のために既にルートキーを保有していることを前提として、チェーンから省略しても構いません。
X.509キー使用法と拡張キー使用法
cert-managerは、いくつかのカスタムキー使用法と拡張キー使用法を持つ証明書の要求をサポートしています。cert-managerはこの要求を尊重しようとしますが、一部の発行者は、要求を削除したり、デフォルトを追加したり、完全に無視したりすることがあります。CA
とSelfSigned
Issuer
は、常に要求された使用法に一致する証明書を返します。
使用法が設定されていない場合、cert-managerはデジタル署名
、キー暗号化
、サーバー認証
というデフォルトの要求済み使用法を設定します。現在の証明書が現在のキー使用法セットと一致しない場合、cert-managerは新しい証明書の要求を試みません。
サポートされているキー使用法の完全なリストは、APIリファレンスドキュメントにあります。
追加の証明書出力形式
additionalOutputFormats
は、Certificate spec
のフィールドで、発行された証明書とその秘密鍵の追加の補足形式を指定できます。現在、サポートされている追加の出力形式はCombinedPEM
とDER
の2つです。両方の出力形式を同じCertificateで指定できます。
apiVersion: cert-manager.io/v1kind: Certificatespec:...secretName: my-cert-tlsadditionalOutputFormats:- type: CombinedPEM- type: DER# Results in:apiVersion: v1kind: Secretmetadata:name: my-cert-tlstype: kubernetes.io/tlsdata:ca.crt: <PEM CA certificate>tls.key: <PEM private key>tls.crt: <PEM signed certificate chain>tls-combined.pem: <PEM private key + "\n" + PEM signed certificate chain>key.der: <DER binary format of private key>
CombinedPEM
CombinedPEM
タイプは、結果のCertificateのSecret tls-combined.pem
に新しいキーエントリを作成します。このエントリには、PEMエンコードされた秘密鍵、それに続く少なくとも1つの改行文字、それに続くPEMエンコードされた署名済み証明書チェーンが含まれます。
<private key> + "\n" + <signed certificate chain>
apiVersion: v1kind: Secretmetadata:name: my-cert-tlstype: kubernetes.io/tlsdata:tls-combined.pem: <PEM private key + "\n" + PEM signed certificate chain>...
DER
DER
タイプは、結果のCertificateのSecret key.der
に新しいキーエントリを作成します。このエントリには、秘密鍵のDERバイナリ形式が含まれます。
apiVersion: v1kind: Secretmetadata:name: my-cert-tlstype: kubernetes.io/tlsdata:key.der: <DER binary format of private key>...
名前制約付き証明書の作成
ルートまたは中間CA証明書には名前制約を設定できます。名前制約は、証明パス内の後続の証明書のすべてのサブジェクト名が配置される必要がある名前空間を示します。詳細については、https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10を参照してください。
⛔️ この機能は、cert-managerコントローラーとWebhookコンポーネントの--feature-gates
フラグに追加することでのみ有効になります。
--feature-gates=NameConstraints=true
名前制約を持つCA証明書を作成するには、次の構成を使用します。
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: ca-cert-examplespec:secretName: example-ca-key-pairisCA: trueissuerRef:name: selfsignedkind: ClusterIssuercommonName: "example1.com"dnsNames:- example1.comnameConstraints:critical: truepermitted:dnsDomains: ["example1.com", "example2.com"]ipRanges: ["10.10.0.0/16"]emailAddress: ["example@example.org"]excluded:ipRanges: ["10.10.0.0/24"]
cert-managerの組み込みCAおよびSelfSigned Issuerと共に使用する場合、SAN(DNS名、IPアドレス、URI、およびメールアドレス)は証明書自身の名前制約と、証明書が属する証明書チェーンに含まれる名前制約のいずれともチェックされません。
証明書は正常に発行される可能性がありますが、TLSハンドシェイク中にクライアントによって拒否される可能性があります。
発行トリガー
有効期限による再発行(更新)
cert-managerはCertificate
を自動的に更新します。発行されたX.509証明書の期間と、「renewBefore」値(証明書の有効期限の何時間前に更新するかを指定する)に基づいて、Certificate
をいつ更新するかを計算します。
spec.duration
とspec.renewBefore
/spec.renewBeforePercentage
フィールドは、Certificate
のX.509証明書の期間と「renewBefore」値を指定するために使用できます。spec.duration
のデフォルト値は90日です。一部の発行者は、設定された期間の証明書のみを発行するように構成されている可能性があるため、実際の期間は異なる場合があります。spec.renewBefore
は絶対的な期間を指定し、spec.renewBeforePercentage
は発行された証明書の実際の期間を使用して有効な「renewBefore」を計算します。spec.renewBeforePercentage
の使用をお勧めします。実際の期間が予想よりも短い場合に、更新ループを防ぐことができます。spec.duration
の最小値は1時間、有効なspec.renewBefore
の最小値は5分です。spec.duration
> spec.renewBefore
とする必要があります。
X.509証明書が発行されると、cert-managerはCertificate
の更新時間を計算します。デフォルトでは、X.509証明書の期間の2/3になります。spec.renewBefore
またはspec.renewBeforePercentage
が設定されている場合、有効なspec.renewBefore
時間分、有効期限前に設定されます。cert-managerはCertificate
のstatus.RenewalTime
を更新が試行される時間に設定します。
ユーザー操作による再発行
証明書オブジェクトは、次の状況で再発行されます。
- 証明書の仕様書の以下のフィールドのいずれかが変更された場合:
commonName
、dnsNames
、ipAddresses
、uris
、emailAddresses
、subject
、isCA
、usages
、duration
、またはissuerRef
;より詳細な説明は、FAQページにあります。 - 再発行が以下の方法で手動でトリガーされた場合
上記の命令にはcmctlが必要です。cmctl renew cert-1
❌証明書リソースに関連付けられたシークレットリソースを削除することは、秘密鍵を手動でローテーションするための推奨される解決策ではありません。秘密鍵を手動でローテーションする推奨される方法は、以下のコマンドを使用して証明書リソースの再発行をトリガーすることです(cmctl
が必要です)。
cmctl renew cert-1
発行動作:発行中の仮証明書
イングレスシムを使用して証明書を要求する場合イングレスシムの使用、使用されている場合、コンポーネントingress-gce
は、サービスを提供する際に、署名済み証明書の発行を待っている間、仮証明書が存在することを必要とします。これを容易にするために、以下のアノテーションが
cert-manager.io/issue-temporary-certificate: "true"
証明書に存在する場合、署名済み証明書が発行されるまで、自己署名された仮証明書がSecret
に存在します。
イングレスに以下のアノテーションを追加すると、「issue-temporary-certificate」が証明書に自動的に設定されます。
acme.cert-manager.io/http01-edit-in-place: "true"
発行動作:秘密鍵のローテーション
デフォルトでは、秘密鍵は自動的にローテーションされません。rotationPolicy: Always
の設定を使用すると、証明書オブジェクトに関連付けられた秘密鍵シークレットは、証明書が再発行されるとすぐにローテーションされるように構成できます(発行トリガーを参照)。
rotationPolicy: Always
を使用すると、cert-managerは、証明書オブジェクトが正しく署名されるまで待ってから、シークレット内のtls.key
ファイルを上書きします。
この設定を使用すると、アプリケーションがマウントされたtls.crt
とtls.key
の変更を検出してそれらを正常にリロードするか、自動的に再起動できる場合、ダウンタイムはありません。
アプリケーションが起動時に一度だけ秘密鍵と署名済み証明書を読み込む場合、新しい証明書はアプリケーションによってすぐに提供されません。そのため、kubectl rollout restart
でポッドを手動で再起動するか、waveを実行することで自動化します。Waveは、マウントされたシークレットが変更されるたびにデプロイメントの再起動を確実に実行するシークレットコントローラーです。
秘密鍵の再利用
組み込みのVenafiイシューアーなどの一部のイシューアーは、秘密鍵の再利用を許可しない場合があります。この場合、各証明書オブジェクトに対してrotationPolicy: Always
設定を明示的に構成する必要があります。
次の例では、証明書にrotationPolicy: Always
が設定されています。
apiVersion: cert-manager.io/v1kind: Certificatespec:secretName: my-cert-tlsprivateKey:rotationPolicy: Always # 🔰 Here.
rotationPolicy
設定
rotationPolicy
の可能な値は次のとおりです。
値 | 説明 |
---|---|
Never (デフォルト) | cert-managerは、各発行で既存の秘密鍵を再利用します。 |
Always (推奨) | cert-managerは、各発行で新しい秘密鍵を生成します。 |
rotationPolicy: Never
を使用すると、ターゲットシークレットリソースにまだ存在しない場合にのみ秘密鍵が生成されます(tls.key
キーを使用)。それ以降のすべての発行では、この秘密鍵が再利用されます。これは、以前のリリースとの互換性を維持するためにデフォルトです。
rotationPolicy: Always
を使用すると、アクションが証明書オブジェクトの再発行をトリガーするたびに新しい秘密鍵が生成されます(上記の秘密鍵のローテーションをトリガーするアクションを参照)。証明書オブジェクトの作成時に秘密鍵シークレットが既に存在する場合、ローテーションメカニズムには最初の発行も含まれるため、既存の秘密鍵は使用されません。
👉 証明書リソースにrotationPolicy: Always
を構成することをお勧めします。証明書と秘密鍵の両方を同時にローテーションすることで、公開された秘密鍵を使用して証明書を発行するリスクを防ぎます。秘密鍵を定期的に更新するもう1つの利点は、緊急時に秘密鍵のローテーションを実行できるという確信を持つことができることです。一般的に、キーをできるだけ頻繁にローテーションして、キーの侵害に関連するリスクを軽減することは良い習慣です。
証明書が削除されたときのシークレットのクリーンアップ
デフォルトでは、cert-managerは、対応するCertificate
リソースが削除されたときに、署名済み証明書を含むSecret
リソースを削除しません。これは、Certificate
を削除しても、現在その証明書に依存しているサービスは停止しませんが、証明書は更新されなくなります。Secret
はもう必要ない場合は、手動で削除する必要があります。
Certificate
が削除されたときにSecret
を自動的に削除する方が良い場合は、コントローラーに--enable-certificate-owner-ref
フラグを渡すようにインストールを構成する必要があります。
開発者向けの内部動作図
[1] https://cert-manager.dokyumento.jp/docs/usage/certificaterequest