带注释的 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)。

📌 此功能需要安装 网关 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/v1alpha1kind: ControllerConfigurationenableGatewayAPI: 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/issuer 或 cert-manager.io/cluster-issuer 告诉 cert-manager 为网关创建证书。例如,以下网关将触发创建名为 example-com-tls 的证书。
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata:name: exampleannotations:cert-manager.io/issuer: foospec:gatewayClassName: foolisteners:- name: httphostname: example.comport: 443protocol: HTTPSallowedRoutes:namespaces:from: Alltls:mode: TerminatecertificateRefs:- name: example-com-tls
片刻之后,cert-manager 将创建一个证书。证书以 Secret 名称 example-com-tls 命名。 dnsNames 字段设置为网关规范中的 hostname 字段。
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-com-tlsspec:issuerRef:name: my-issuerkind: Issuergroup: cert-manager.iodnsNames:- example.com # ✅ Copied from the `hostname` field.secretName: example-com-tls
🚧 此机制只能用于在与 Gateway 相同的命名空间中创建 Secret,请参阅 cert-manager#5610
用例
为选定的 TLS 块生成 TLS 证书
cert-manager 会跳过任何不能用于生成证书的侦听器块。要将侦听器块用于创建证书,它必须满足以下要求
| 字段 | 要求 |
|---|---|
tls.hostname | 不能为空。 |
tls.mode | 必须设置为 Terminate。 Passthrough 不受支持。 |
tls.certificateRef.name | 不能留空。 |
tls.certificateRef.kind | 如果指定,必须设置为 Secret。 |
tls.certificateRef.group | 如果指定,必须设置为 core。 |
tls.certificateRef.namespace | 如果指定,必须与 Gateway 相同。 |
在以下示例中,前四个侦听器块将不会用于生成证书资源
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata:name: my-gatewaynamespace: defaultannotations:cert-manager.io/issuer: my-issuerspec:gatewayClassName: foolisteners:# ❌ Missing "tls" block, the following listener is skipped.- name: example-1port: 80protocol: HTTPhostname: example.com# ❌ Missing "hostname", the following listener is skipped.- name: example-2port: 443protocol: HTTPStls:certificateRefs:- name: example-com-tlskind: Secretgroup: ""# ❌ "mode: Passthrough" is not supported, the following listener is skipped.- name: example-3hostname: example.comport: 8443protocol: HTTPStls:mode: PassthroughcertificateRefs:- name: example-com-tlskind: Secretgroup: ""# ❌ Cross-namespace secret references are not supported, the following listener is skipped.- name: example-4hostname: foo.example.comport: 8443protocol: HTTPSallowedRoutes:namespaces:from: Alltls:mode: TerminatecertificateRefs:- name: example-com-tlskind: Secretgroup: ""namespace: other-namespace# ✅ The following listener is valid.- name: example-5hostname: bar.example.com # ✅ Required.port: 8443protocol: HTTPSallowedRoutes:namespaces:from: Alltls: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/v1kind: Certificatemetadata:name: example-com-tlsspec:issuerRef:name: my-issuerkind: Issuergroup: cert-manager.iodnsNames:- foo.example.comsecretName: example-com-tls
两个具有相同 Secret 名称的侦听器
相同的 Secret 名称可以在多个 TLS 块中重复使用,无论主机名如何。假设您有两个这样的侦听器
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata:name: exampleannotations:cert-manager.io/issuer: my-issuerspec:gatewayClassName: foolisteners:# Listener 1.- name: example-1hostname: example.comport: 443protocol: HTTPStls:mode: TerminatecertificateRefs:- name: example-com-tls# Listener 2: Same Secret name as Listener 1, with a different hostname.- name: example-2hostname: "*.example.com"port: 443protocol: HTTPStls:mode: TerminatecertificateRefs:- name: example-com-tls# Listener 3: also same Secret name, except the hostname is also the same.- name: example-3hostname: "*.example.com"port: 8443protocol: HTTPStls:mode: TerminatecertificateRefs:- name: example-com-tls# Listener 4: different Secret name.- name: example-4hostname: site.orgport: 443protocol: HTTPStls:mode: TerminatecertificateRefs:- name: site-org-tls
cert-manager 将创建两个证书,因为使用了两个 Secret 名称:example-com-tls 和 site-org-tls。请注意,证书的 dnsNames 包含 *.example.com 的单个出现,适用于侦听器 2 和 3(hostname 值已去重)。
这两个证书如下所示
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-com-tlsspec:issuerRef:name: my-issuerkind: Issuergroup: cert-manager.iodnsNames:- example.com # From listener 1.- *.example.com # From listener 2 and 3.secretName: example-com-tls---apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: site-org-tlsspec:issuerRef:name: my-issuerkind: Issuergroup: cert-manager.iodnsNames:- 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字段,以设置用于证书的私钥生成算法。有效值为RSA、ECDSA和Ed25519。如果未设置,将使用算法RSA。 -
cert-manager.io/private-key-encoding: (可选) 此注释允许您配置spec.privateKey.encoding字段,以设置用于证书的私钥生成的编码。有效值为PKCS1和PKCS8。如果未设置,将使用算法PKCS1。 -
cert-manager.io/private-key-size: (可选) 此注释允许您配置spec.privateKey.size字段,以设置证书的私钥大小。如果算法设置为RSA,有效值为2048、4096或8192,如果未指定,则默认为2048。如果算法设置为ECDSA,有效值为256、384或521,如果未指定,则默认为256。如果算法设置为Ed25519,则忽略大小。 -
cert-manager.io/private-key-rotation-policy: (可选) 此注释允许您配置spec.privateKey.rotationPolicy字段,以设置证书的私钥轮换策略。有效值为Never和Always。如果未设置,将使用轮换策略Never。
