使用由 Google 管理的 SSL 证书

本页面介绍如何使用 Ingress 对象和由 Google 管理的 SSL 证书创建外部负载均衡器。这些证书是 Google 为您的域名预配、续订和管理的网域验证 (DV) 证书。这些证书并不代表您的个人或组织身份。

如需了解如何使用 Google Cloud 创建 Google 管理的证书,请参阅 Google 管理的证书

GKE Google 管理的 SSL 证书支持公共集群和专用集群。

API 版本

您可以使用 ManagedCertificate 自定义资源配置 Google 管理的 SSL 证书,该资源以不同的 API 版本提供,具体取决于您的 Google Kubernetes Engine (GKE) 集群版本:

  • GKE 版本 1.15 及更高版本中提供了 ManagedCertificate v1beta2 API。
  • GKE 1.17.9-gke.6300 及更高版本中提供了 ManagedCertificate v1 API

虽然 GKE 集群目前支持 ManagedCertificate v1beta1 API,但此 API 版本已弃用,并会在未来推出的 GKE 版本中移除。建议您使用较新的 API 版本。

在 API 版本之间迁移

在支持较新 API 版本的集群中更新 ManagedCertificate 对象时,这些对象会自动升级到较新 API 版本。系统会定期更新资源,因此您无需执行任何操作来迁移资源。

使用由 Google 管理的证书创建 Ingress

要配置由 Google 管理的 SSL 证书并将其与 Ingress 关联,您需要执行以下操作:

  • 在 Ingress 所在的命名空间中创建 ManagedCertificate 对象。
  • 通过将 networking.gke.io/managed-certificates 注解添加到 Ingress,将 ManagedCertificate 对象与 Ingress 相关联。此注解一个是英文逗号分隔的 ManagedCertificate 对象列表。

限制

由 Google 管理的证书不如由您获得和管理的证书灵活。Google 管理的证书最多支持 100 个非通配符网域。与自行管理的证书不同,Google 管理的证书不支持通配符网域。

如果您需要自行管理的证书,或者您已经拥有要在 Ingress 上配置的 SSL 证书,请参阅在客户端和负载均衡器之间设置 HTTPS (TLS)

Ingress 所支持证书的数量和类型由 Google 管理的 SSL 证书的限制定义。

不支持对由 Google 管理的证书进行更新。

如需进行手动更改并将停机时间缩至最短,请参阅手动更新由 Google 管理的证书

前提条件

  • 您必须拥有域名。域名长度不得超过 63 个字符。您可以使用 Google Domains 或其他注册商。
  • 集群必须启用 HttpLoadBalancing 插件。
  • "kubernetes.io/ingress.class" 必须是 "gce"
  • 您必须在同一项目和命名空间中应用 IngressManagedCertificate 资源。
  • 创建预留的(静态)外部 IP 地址。 预留静态 IP 地址可以保证该地址始终属于您,即使您删除 Ingress 也是如此。如果您不预留 IP 地址,则 IP 地址可能会更改,这样您需要重新配置您的网域的 DNS 记录。请使用 gcloud 命令行工具或 Cloud Console 创建预留 IP 地址。

    gcloud

    如需创建预留 IP 地址,请运行以下命令:

    gcloud compute addresses create ADDRESS_NAME --global
    

    ADDRESS_NAME 替换为您要创建的预留 IP 地址的名称。

    如需查找您创建的静态 IP 地址,请运行以下命令:

    gcloud compute addresses describe ADDRESS_NAME --global
    

    输出内容类似如下:

    address: 203.0.113.32
    ...
    

    控制台

    如需创建预留的 IP 地址,请执行以下步骤:

    1. 转到 Cloud Console 中的外部 IP 地址页面。

      转到“外部 IP 地址”

    2. 为此 IP 地址指定名称(例如 example-ip-address)。

    3. 指定您需要 IPv4 还是 IPv6 地址。

    4. 选择类型对应的全球选项。

    5. 点击预留。 IP 地址在外部地址列中列出。

    Config Connector

    注意:此步骤需要使用配置连接器。按照安装说明在您的集群上安装配置连接器。

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global
    如需部署此清单,请将它以 compute-address.yaml 的形式下载到您的机器上,然后运行以下命令:

    kubectl apply -f compute-address.yaml
    

设置由 Google 管理的证书

  1. 创建一个 ManagedCertificate 对象。 此资源会指定 SSL 证书的网域。不支持通配符网域。

    以下清单描述了一个 ManagedCertificate 对象。将此清单保存为 managed-cert.yaml

    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: managed-cert
    spec:
      domains:
        - DOMAIN_NAME1
        - DOMAIN_NAME2
    

    替换以下内容:

    • DOMAIN_NAME1DOMAIN_NAME2:您拥有的域名。例如 example.comwww.example.com
  2. 将清单应用到您的集群:

    kubectl apply -f managed-cert.yaml
    
  3. 创建 NodePort 类型的 Service 以向互联网公开您的应用。

    以下清单描述了 NodePort 类型的 Service。将此清单保存为 mc-service.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: mc-service
    spec:
      selector:
        app: mc-service
      type: NodePort
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    
  4. 将清单应用到您的集群:

    kubectl apply -f mc-service.yaml
    
  5. 创建 Ingress。

    以下清单描述了一个使用您创建的 ManagedCertificate 的 Ingress。将此清单保存为 managed-cert-ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: managed-cert-ingress
      annotations:
        kubernetes.io/ingress.global-static-ip-name: ADDRESS_NAME
        networking.gke.io/managed-certificates: managed-cert
        kubernetes.io/ingress.class: "gce"
    spec:
      defaultBackend:
        service:
          name: mc-service
          port:
            number: SERVICE_PORT
    

    替换以下内容:

    • ADDRESS_NAME:预留的 IP 地址的名称。
    • SERVICE_PORT:Service 清单中 ports.port 的值。
  6. 将清单应用到您的集群:

    kubectl apply -f managed-cert-ingress.yaml
    
  7. 获取负载均衡器的 IP 地址:

    kubectl get ingress
    

    输出内容类似如下:

    NAME              HOSTS     ADDRESS         PORTS     AGE
    example-ingress   *         203.0.113.32     80       54s
    

    负载平衡器的 IP 地址在 ADDRESS 列中列出。如果您使用的是预留的静态 IP 地址,则该地址将是负载平衡器的地址。

    如果未列出地址,请等待 Ingress 完成设置。

  8. 为您的网域配置 DNS 记录,以指向负载平衡器的 IP 地址。如果您使用 Cloud DNS,请参阅管理记录以了解详情。

  9. 等待 Google 管理的证书完成预配。此过程最多可能需要 60 分钟。您可以使用以下命令检查证书的状态:

    kubectl describe managedcertificate managed-cert
    

    输出内容类似如下:

    Name:         managed-cert
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         ManagedCertificate
    (...)
    Spec:
     Domains:
       DOMAIN_NAME1
       DOMAIN_NAME2
    Status:
     CertificateStatus: Active
    (...)
    

    Status.CertificateStatus 字段的值指示证书是否已预配。如果 Status.CertificateStatus 不是 Active,则表示证书尚未预配。

  10. 使用 https:// 前缀访问您的网域,验证 SSL 是否正常工作。您的浏览器会指示连接是否安全,您可以查看证书详细信息。

从自行管理的证书迁移到由 Google 管理的证书

将 Ingress 从使用自行管理的 SSL 证书迁移到由 Google 管理的 SSL 证书时,由 Google 管理的 SSL 证书处于活跃状态之前,请不要删除任何自行管理的 SSL 证书。成功预配由 Google 管理的 SSL 证书后,它们会自动处于活跃状态。 由 Google 管理的 SSL 证书生效时,您可以删除自行管理的 SSL 证书。

使用以下说明从自行管理的 SSL 证书迁移到 Google 管理的 SSL 证书。

  1. 将由 Google 管理的新证书添加到 Ingress,如设置由 Google 管理的证书部分中所述。
  2. 等待由 Google 管理的证书资源的状态变为“有效”。 使用以下命令检查证书的状态:

    kubectl describe managedcertificate managed-cert
    
  3. 状态为 Active 时,更新 Ingress,以移除对自行管理证书的引用。

移除由 Google 管理的证书

如需从集群中移除由 Google 管理的证书,您必须删除 ManagedCertificate 对象并移除引用它的 Ingress 注解。

  1. 删除 ManagedCertificate 对象:

    kubectl delete -f managed-cert.yaml
    

    输出内容类似如下:

    managedcertificate.networking.gke.io "managed-cert" deleted
    
  2. 从 Ingress 中移除注释:

    kubectl annotate ingress managed-cert-ingress networking.gke.io/managed-certificates-
    

    请注意命令末尾的减号 -

  3. 释放您为负载均衡器预留的静态 IP 地址。

    您可以使用 gcloud 命令行工具、Cloud Console 或 Config Connector 释放预留的 IP 地址。

    gcloud

    使用以下命令释放预留的 IP 地址:

    gcloud compute addresses delete ADDRESS_NAME --global
    

    ADDRESS_NAME 替换为该 IP 地址的名称。

    控制台

    如需释放预留的 IP 地址,请执行以下步骤:

    1. 转到 Cloud Console 中的外部 IP 地址页面。

      转到“外部 IP 地址”

    2. 选中要释放的 IP 地址旁边的复选框。

    3. 点击释放 IP 地址

    Config Connector

    注意:此步骤需要使用配置连接器。按照安装说明在您的集群上安装配置连接器。

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global

    如需部署此清单,请将它以 compute-address.yaml 的形式下载到您的机器上,然后运行以下命令:

    kubectl delete -f compute-address.yaml
    

问题排查

本部分介绍了如何解决由 Google 管理的证书的相关问题。

检查 ManagedCertificate 和 Ingress 资源上的事件

如果您超出了允许的证书数量,则系统将向 ManagedCertificate 添加一个原因为 TooManyCertificates 的事件。您可以使用以下命令检查 ManagedCertificate 对象上的事件:

kubectl describe managedcertificate CERTIFICATE_NAME

CERTIFICATE_NAME 替换为 ManagedCertificate 的名称。

如果您将不存在的 ManagedCertificate v1 关联到 Ingress,则系统将向 Ingress 添加一个原因为 MissingCertificate 的事件。您可以使用以下命令检查 Ingress 资源上的事件:

kubectl describe ingress INGRESS_NAME

INGRESS_NAME 替换为您的 Ingress 名称。

网域解析为多个负载平衡器的 IP 地址时未预配托管式证书

当网域解析为多个负载均衡器(多个 Ingress 对象)的 IP 地址时,您应该创建一个 ManagedCertificate 对象并将其关联到所有 Ingress 对象。如果您改为创建多个 ManagedCertificate 对象并将每个对象关联到单独的 Ingress,则证书授权机构可能无法验证网域的所有权,并且部分证书可能无法预配。若要使验证成功,证书必须在网域解析为的所有 IP 地址下显示。

具体而言,当您的网域解析为使用不同 Ingress 对象配置的 IPv4 和 IPv6 地址时,您应该创建一个 ManagedCertificate 对象并将其关联到两个 Ingress。

由 Google 管理的证书与 Ingress 之间的通信中断

代管式证书使用 kubernetes.io/pre-shared-cert 注解与 Ingress 通信。您可以在以下情况下中断此通信,例如:

  • 运行可清除 kubernetes.io/pre-shared-cert 注解的自动化进程。
  • 存储 Ingress 的快照,然后通过快照删除和恢复 Ingress。在此期间,pre-shared-cert 注解中列出的 SslCertificate 资源可能已被删除。如果缺失关联的任何证书,Ingress 将不起作用。

如果由 Google 管理的证书与 Ingress 之间的通信中断,请删除 kubernetes.io/pre-shared-cert 注解的内容并等待系统调节。为防止重复发生,请确保该注解不会被无意中修改或删除。

创建由 Google 管理的证书时出现验证错误

ManagedCertificate 定义会在创建 ManagedCertificate 对象之前验证。如果验证失败,则不会创建 ManagedCertificate 对象并输出错误消息。下面解释了不同的错误消息和原因:

spec.domains in body should have at most 100 items

ManagedCertificate 清单在 spec.domains 字段中列出了超过 100 个网域。由 Google 管理的证书最多只支持 100 个网域。

spec.domains in body should match '^(([a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9])\.)+[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]\.?$'

您在 spec.domains 字段中指定的域名或通配符域名无效。ManagedCertificate 对象不支持通配符网域(例如 *.example.com)。

spec.domains in body should be at most 63 chars long

您指定的域名太长。由 Google 管理的证书支持的域名长度最多为 63 个字符。

手动更新由 Google 管理的证书

如需手动更新证书,以便旧网域的证书继续正常运作,直到预配新网域的证书,请按照以下步骤操作:

  1. 为新网域创建 ManagedCertificate
  2. 使用英文逗号分隔列表,将 ManagedCertificate 的名称添加到 Ingress 上的 networking.gke.io/managed-certificates 注释。请勿移除旧证书名称。
  3. 等待 ManagedCertificate 变为活动状态。
  4. 从 Ingress 中分离旧证书并将其删除。

创建 ManagedCertificate 时,Google Cloud 会创建一个由 Google 管理的 SSL 证书。您无法更新此证书。 如果您更新 ManagedCertificate,则 Google Cloud 会删除并重新创建由 Google 管理的 SSL 证书。

后续步骤