新:获取项目更新信息,请访问推特Mastodon

带注释的 Gateway 资源

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

功能状态: cert-manager 1.15 [beta]

📌 此页面重点介绍如何通过注释 Kubernetes Gateway 资源自动创建 Certificate 资源。如果您正在寻找使用 ACME Issuer 以及 Kubernetes Gateway API 的 HTTP-01 挑战,请查看 ACME HTTP-01.

🚧 cert-manager 1.14+ 已通过 v1 Kubernetes Gateway API 测试。由于资源转换,它也应该适用于 v1beta1 和 v1alpha2,但尚未对其进行测试。

cert-manager 可以为 Gateway 资源生成 TLS 证书。这可以通过向 Gateway 添加注释来配置,类似于为 保护 Ingress 资源 的过程。

网关资源是 网关 API 的一部分,网关 API 是一组 CRD,您可以在 Kubernetes 集群中安装它,并提供比 Ingress API 更多的改进。

网关资源包含 TLS 配置,如下面的图表所示(来源:https://gateway-api.kubernetes.ac.cn)。

Gateway vs. HTTPRoute

📌 此功能需要安装 网关 API 包 并向 cert-manager 控制器传递额外的标志。

要安装 v1.5.1 网关 API 包(网关 CRD 和 webhook),请运行以下命令

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

从 cert-manager 1.15 开始,网关 API 支持不再受功能标志限制,但您仍然需要启用网关 API 支持。

要启用网关 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

网关 API CRD 应该在 cert-manager 启动之前安装,或者 cert-manager 部署应该在安装网关 API CRD 后重新启动。这很重要,因为 cert-manager 的某些组件只在启动时执行网关 API 检查。您可以使用以下命令重新启动 cert-manager

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

注释 cert-manager.io/issuercert-manager.io/cluster-issuer 告诉 cert-manager 为网关创建证书。例如,以下网关将触发创建名为 example-com-tls 的证书。

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 将创建一个证书。证书以 Secret 名称 example-com-tls 命名。 dnsNames 字段设置为网关规范中的 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.mode必须设置为 TerminatePassthrough 不受支持。
tls.certificateRef.name不能留空。
tls.certificateRef.kind如果指定,必须设置为 Secret
tls.certificateRef.group如果指定,必须设置为 core
tls.certificateRef.namespace如果指定,必须与 Gateway 相同。

在以下示例中,前四个侦听器块将不会用于生成证书资源

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 跳过了前四个侦听器块,并为最后一个侦听器块创建了一个名为 example-com-tls 的证书。

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 名称的侦听器

相同的 Secret 名称可以在多个 TLS 块中重复使用,无论主机名如何。假设您有两个这样的侦听器

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 将创建两个证书,因为使用了两个 Secret 名称:example-com-tlssite-org-tls。请注意,证书的 dnsNames 包含 *.example.com 的单个出现,适用于侦听器 2 和 3(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 # 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 资源迁移到网关资源,请注意 Ingress 资源的注释 与网关资源的注释之间存在一些差异。

网关资源支持以下注释来生成证书资源

  • cert-manager.io/issuer:获取此网关所需证书的颁发者名称。颁发者 *必须* 位于与网关资源相同的命名空间中。

  • cert-manager.io/cluster-issuer:获取此网关所需证书的集群颁发者名称。网关位于哪个命名空间并不重要,因为 ClusterIssuers 是无命名空间的资源。

  • cert-manager.io/issuer-kind:外部颁发者资源的类型,例如 AWSPCACIssuer。这仅适用于树外颁发者。

  • cert-manager.io/issuer-group:外部颁发者控制器的 API 组,例如 awspca.cert-manager.io。这仅适用于树外颁发者。

  • cert-manager.io/common-name:(可选)此注释允许您配置要生成的证书的 spec.commonName

  • cert-manager.io/email-sans:(可选)此注释允许您配置要生成的证书的 spec.emailAddresses 字段。支持以逗号分隔的值,例如 "me@example.com,you@example.com"

  • cert-manager.io/subject-organizations:(可选)此注释允许您配置要生成的证书的 spec.subject.organizations 字段。支持以逗号分隔的值,例如“公司 1,公司 2”。

  • cert-manager.io/subject-organizationalunits:(可选)此注释允许您配置要生成的证书的 spec.subject.organizationalUnits 字段。支持以逗号分隔的值,例如“IT 服务,云服务”。

  • cert-manager.io/subject-countries:(可选)此注释允许您配置要生成的证书的 spec.subject.countries 字段。支持以逗号分隔的值,例如“国家 1,国家 2”。

  • cert-manager.io/subject-provinces:(可选)此注释允许您配置要生成的证书的 spec.subject.provinces 字段。支持以逗号分隔的值,例如“省份 1,省份 2”。

  • cert-manager.io/subject-localities:(可选)此注释允许您配置要生成的证书的 spec.subject.localities 字段。支持以逗号分隔的值,例如“城市 1,城市 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: (可选) 此注释允许您配置 spec.revisionHistoryLimit 字段,以限制为证书保留的证书请求数量。最小值为 1。如果未设置,将保留所有证书请求。

  • 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.k8s.ac.cn/docs/usage/certificate