新着: プロジェクトの最新情報についてはTwitterMastodonでご確認ください。

アノテーション付き Gateway リソース

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway

機能状態 (FEATURE STATE): cert-manager 1.15 [ベータ版]

📌 このページでは、Kubernetes Gateway リソースにアノテーションを付けることで、Certificate リソースを自動的に作成することに焦点を当てています。Kubernetes Gateway API を使用した HTTP-01 チャレンジと共に ACME Issuer を使用する方法については、ACME HTTP-01 を参照してください。

🚧 cert-manager 1.14 以降は、v1 Kubernetes Gateway API でテストされています。リソース変換のため、v1beta1 および v1alpha2 でも機能するはずです。ただし、これらについてはテストされていません。

cert-manager は、Gateway リソースの TLS 証明書を生成できます。これは、Gateway にアノテーションを追加することで設定され、Ingress リソースの保護 のプロセスと同様です。

Gateway リソースは、Gateway API の一部です。Gateway API は、Kubernetes クラスタにインストールする CRD のセットであり、Ingress API よりも様々な改善が提供されています。

次の図に示すように、Gateway リソースには TLS 設定が含まれています(出典:https://gateway-api.sigs.k8s.io

Gateway vs. HTTPRoute

📌 この機能には、Gateway API バンドル のインストールと、cert-manager コントローラーへの追加フラグの渡しが必須です。

v1.5.1 Gateway API バンドル(Gateway CRD と webhook)をインストールするには、次のコマンドを実行します。

kubectl apply -f "https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml"

cert-manager 1.15 以降では、Gateway API のサポートは機能フラグの背後に隠されることはなくなりましたが、Gateway API のサポートを有効にする必要があります。

Gateway API のサポートを有効にするには、次のconfig Helm 値を使用して、ファイルベースの設定 を使用します。

config:
apiVersion: controller.config.cert-manager.io/v1alpha1
kind: ControllerConfiguration
enableGatewayAPI: true

対応する Helm コマンドは次のとおりです。

helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager \
--set config.apiVersion="controller.config.cert-manager.io/v1alpha1" \
--set config.kind="ControllerConfiguration" \
--set config.enableGatewayAPI=true

Gateway API CRD は、cert-manager の起動前にインストールするか、Gateway API CRD のインストール後に cert-manager Deployment を再起動する必要があります。これは、cert-manager の一部のコンポーネントが起動時にのみ Gateway API チェックを実行するため重要です。次のコマンドを使用して cert-manager を再起動できます。

kubectl rollout restart deployment cert-manager -n cert-manager

アノテーション cert-manager.io/issuer または cert-manager.io/cluster-issuer は、cert-manager に Gateway の Certificate を作成するように指示します。たとえば、次の Gateway は、example-com-tls という名前の Certificate の作成をトリガーします。

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example
annotations:
cert-manager.io/issuer: foo
spec:
gatewayClassName: foo
listeners:
- name: http
hostname: example.com
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- name: example-com-tls

しばらくすると、cert-manager は Certificate を作成します。Certificate は、Secret 名 example-com-tls を元に命名されます。dnsNames フィールドは、Gateway spec の hostname フィールドを使用して設定されます。

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com-tls
spec:
issuerRef:
name: my-issuer
kind: Issuer
group: cert-manager.io
dnsNames:
- example.com # ✅ Copied from the `hostname` field.
secretName: example-com-tls

🚧 このメカニズムは、Gateway と同じ名前空間で Secret を作成する場合にのみ使用できます。cert-manager#5610 を参照してください。

ユースケース

選択した TLS ブロックの TLS 証明書の生成

cert-manager は、証明書の生成に使用できないリスナーブロックをスキップします。証明書の作成に使用されるリスナーブロックは、次の要件を満たしている必要があります。

フィールド要件
tls.hostname空であってはいけません。
tls.modeTerminate に設定する必要があります。Passthrough はサポートされていません。
tls.certificateRef.name空のままにしておくことはできません。
tls.certificateRef.kind指定されている場合、Secret に設定する必要があります。
tls.certificateRef.group指定されている場合、core に設定する必要があります。
tls.certificateRef.namespace指定されている場合、Gateway と同じである必要があります。

次の例では、最初の 4 つのリスナーブロックは Certificate リソースの生成に使用されません。

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: default
annotations:
cert-manager.io/issuer: my-issuer
spec:
gatewayClassName: foo
listeners:
# ❌ Missing "tls" block, the following listener is skipped.
- name: example-1
port: 80
protocol: HTTP
hostname: example.com
# ❌ Missing "hostname", the following listener is skipped.
- name: example-2
port: 443
protocol: HTTPS
tls:
certificateRefs:
- name: example-com-tls
kind: Secret
group: ""
# ❌ "mode: Passthrough" is not supported, the following listener is skipped.
- name: example-3
hostname: example.com
port: 8443
protocol: HTTPS
tls:
mode: Passthrough
certificateRefs:
- name: example-com-tls
kind: Secret
group: ""
# ❌ Cross-namespace secret references are not supported, the following listener is skipped.
- name: example-4
hostname: foo.example.com
port: 8443
protocol: HTTPS
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- name: example-com-tls
kind: Secret
group: ""
namespace: other-namespace
# ✅ The following listener is valid.
- name: example-5
hostname: bar.example.com # ✅ Required.
port: 8443
protocol: HTTPS
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate # ✅ Required. "Terminate" is the only supported mode.
certificateRefs:
- name: example-com-tls # ✅ Required.
kind: Secret # ✅ Optional. "Secret" is the only valid value.
group: "" # ✅ Optional. "" is the only valid value.

cert-manager は最初の 4 つのリスナーブロックをスキップし、最後のリスナーブロックに対して example-com-tls という名前の単一の Certificate を作成しました。

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com-tls
spec:
issuerRef:
name: my-issuer
kind: Issuer
group: cert-manager.io
dnsNames:
- foo.example.com
secretName: example-com-tls

同じ Secret 名を持つ 2 つのリスナー

ホスト名に関係なく、同じ Secret 名を複数の TLS ブロックで再利用できます。次の 2 つのリスナーがあるとします。

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example
annotations:
cert-manager.io/issuer: my-issuer
spec:
gatewayClassName: foo
listeners:
# Listener 1.
- name: example-1
hostname: example.com
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: example-com-tls
# Listener 2: Same Secret name as Listener 1, with a different hostname.
- name: example-2
hostname: "*.example.com"
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: example-com-tls
# Listener 3: also same Secret name, except the hostname is also the same.
- name: example-3
hostname: "*.example.com"
port: 8443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: example-com-tls
# Listener 4: different Secret name.
- name: example-4
hostname: site.org
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: site-org-tls

cert-manager は、2 つの Secret 名が使用されているため、2 つの Certificate を作成します。example-com-tlssite-org-tls です。Certificate の dnsNames には、リスナー 2 と 3 の両方に対して *.example.com が 1 回だけ含まれています(hostname の値は重複除去されます)。

2 つの Certificate は次のようになります。

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com-tls
spec:
issuerRef:
name: my-issuer
kind: Issuer
group: cert-manager.io
dnsNames:
- example.com # From listener 1.
- *.example.com # From listener 2 and 3.
secretName: example-com-tls
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: site-org-tls
spec:
issuerRef:
name: my-issuer
kind: Issuer
group: cert-manager.io
dnsNames:
- site.org # From listener 4.
secretName: site-org-tls

サポートされているアノテーション

Ingress リソースから Gateway リソースに移行する場合は、Ingress リソースのアノテーション と Gateway リソースのアノテーションとの違いに注意してください。

Gateway リソースは、Certificate リソースの生成のために次のアノテーションをサポートしています。

  • cert-manager.io/issuer: この Gateway に必要な証明書を取得するための Issuer の名前。Issuer は、Gateway リソースと同じ名前空間にある *必要* があります。

  • cert-manager.io/cluster-issuer: この Gateway に必要な Certificate を取得するための ClusterIssuer の名前。Gateway がどの名前空間に存在するかは関係ありません。ClusterIssuers は名前空間を持たないリソースです。

  • cert-manager.io/issuer-kind: 外部発行者リソースの種類(例:AWSPCACIssuer)。これは、ツリー外の発行者に対してのみ必要です。

  • cert-manager.io/issuer-group: 外部発行者コントローラーの API グループ(例:awspca.cert-manager.io)。これは、ツリー外の発行者に対してのみ必要です。

  • cert-manager.io/common-name: (オプション)このアノテーションを使用すると、生成される Certificate の spec.commonName を設定できます。

  • cert-manager.io/email-sans: (オプション)このアノテーションを使用すると、生成される Certificate の spec.emailAddresses フィールドを設定できます。コンマ区切りの値をサポートします(例:「me@example.com,you@example.com」)。

  • cert-manager.io/subject-organizations: (オプション)このアノテーションを使用すると、生成される Certificate の spec.subject.organizations フィールドを設定できます。コンマ区切りの値をサポートします(例:「Company 1,Company 2」)。

  • cert-manager.io/subject-organizationalunits: (オプション)このアノテーションを使用すると、生成される Certificate の spec.subject.organizationalUnits フィールドを設定できます。コンマ区切りの値をサポートします(例:「IT Services,Cloud Services」)。

  • cert-manager.io/subject-countries: (オプション)このアノテーションを使用すると、生成される Certificate の spec.subject.countries フィールドを設定できます。コンマ区切りの値をサポートします(例:「Country 1,Country 2」)。

  • cert-manager.io/subject-provinces: (オプション)このアノテーションを使用すると、生成される Certificate の spec.subject.provinces フィールドを設定できます。コンマ区切りの値をサポートします(例:「Province 1,Province 2」)。

  • cert-manager.io/subject-localities:(オプション)このアノテーションを使用すると、生成される証明書のspec.subject.localitiesフィールドを設定できます。カンマ区切りの値をサポートします(例:「City 1,City 2」)。

  • cert-manager.io/subject-postalcodes:(オプション)このアノテーションを使用すると、生成される証明書のspec.subject.postalCodesフィールドを設定できます。カンマ区切りの値をサポートします(例:「123ABC,456DEF」)。

  • cert-manager.io/subject-streetaddresses:(オプション)このアノテーションを使用すると、生成される証明書のspec.subject.streetAddressesフィールドを設定できます。カンマ区切りの値をサポートします(例:「123 Example St,456 Other Blvd」)。

  • cert-manager.io/subject-serialnumber:(オプション)このアノテーションを使用すると、生成される証明書のspec.subject.serialNumberフィールドを設定できます。カンマ区切りの値をサポートします(例:「10978342379280287615,1111144445555522228888」)。

  • cert-manager.io/duration:(オプション)このアノテーションを使用すると、生成される証明書のspec.durationフィールドを設定できます。

  • cert-manager.io/renew-before:(オプション)このアノテーションを使用すると、生成される証明書のspec.renewBeforeフィールドを設定できます。

  • cert-manager.io/usages:(オプション)このアノテーションを使用すると、生成される証明書のspec.usagesフィールドを設定できます。カンマ区切りの値を持つ文字列を渡します(例:「key agreement,digital signature, server auth」)。

  • cert-manager.io/revision-history-limit:(オプション)このアノテーションを使用すると、証明書に対して保持されるCertificateRequestの数を制限するspec.revisionHistoryLimitフィールドを設定できます。最小値は1です。設定されていない場合、すべてのCertificateRequestが保持されます。

  • cert-manager.io/private-key-algorithm:(オプション)このアノテーションを使用すると、証明書の秘密鍵生成のアルゴリズムを設定するspec.privateKey.algorithmフィールドを設定できます。有効な値はRSAECDSAEd25519です。設定されていない場合、アルゴリズムRSAが使用されます。

  • cert-manager.io/private-key-encoding:(オプション)このアノテーションを使用すると、証明書の秘密鍵生成のエンコーディングを設定するspec.privateKey.encodingフィールドを設定できます。有効な値はPKCS1PKCS8です。設定されていない場合、アルゴリズムPKCS1が使用されます。

  • cert-manager.io/private-key-size:(オプション)このアノテーションを使用すると、証明書の秘密鍵のサイズを設定するspec.privateKey.sizeフィールドを設定できます。アルゴリズムがRSAに設定されている場合、有効な値は204840968192であり、指定されていない場合は2048がデフォルトになります。アルゴリズムがECDSAに設定されている場合、有効な値は256384521であり、指定されていない場合は256がデフォルトになります。アルゴリズムがEd25519に設定されている場合、サイズは無視されます。

  • cert-manager.io/private-key-rotation-policy:(オプション)このアノテーションを使用すると、証明書の秘密鍵のローテーションポリシーを設定するspec.privateKey.rotationPolicyフィールドを設定できます。有効な値はNeverAlwaysです。設定されていない場合、ローテーションポリシーNeverが使用されます。

開発者向け内部動作図

[1] https://cert-manager.dokyumento.jp/docs/usage/certificate