使用由 Google 管理的 SSL 证书

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

API 版本

您可以使用 ManagedCertificate 自定义资源配置 Google 管理的 SSL 证书,该资源以不同的 API 版本提供,具体取决于您的 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 版本。系统会定期更新资源,因此您无需执行任何操作来迁移资源。

使用托管式证书创建 Ingress

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

  • 创建一个 ManagedCertificate 对象。
  • 通过向 Ingress 添加注释 networking.gke.io/managed-certificates,将 ManagedCertificate 对象与 Ingress 相关联。此注释是 ManagedCertificate 资源列表(以英文逗号分隔),例如 cert1,cert2,cert3

限制

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

如果您需要自行管理的证书,或者您已经拥有要在 Ingress 上配置的 SSL 证书,请参阅 Ingress 文档。

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

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

如需进行手动更改并将停机时间缩至最短,请按照手动更新由 Google 管理的证书中的步骤操作。

前提条件

  • 您必须拥有域名。域名长度不得超过 63 个字符。您可以使用 Google Domains 或其他注册商。
  • 创建预留的(静态)外部 IP 地址。 预留静态 IP 地址可以保证该地址始终属于您,即使您删除 Ingress 也是如此。如果您不预留地址,则地址可能会更改,这样您需要重新配置您的网域的 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
    ...
    

    控制台

    1. 转到 Cloud Console 中的“预留静态地址”页面。

      转到“预留静态地址”页面

    2. 指定此 IP 地址的名称(例如 example-ip-address)。
    3. 指定该地址为 IPv4 地址还是 IPv6 地址。以下示例使用的是 IPv4 地址。
    4. 为地址类型选择“全球”选项。
    5. 点击预留以预留该 IP。
    6. IP 地址在外部地址列中列出。

    配置连接器

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

    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

设置托管式证书

  1. 创建 ManagedCertificate 资源。此资源会指定将为其创建 SSL 证书的网域。不支持通配符网域。

    以下是一个 ManagedCertificate 清单示例:

    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: certificate-name
    spec:
      domains:
        - domain-name1
        - domain-name2
    

    其中:

    • certificate-nameManagedCertificate 资源的名称。
    • domain-name1domain-name2 是您的域名,例如 example.commail.example.comwww.example.com

    将清单另存为名为 certificate-name.yaml 的文件,然后使用以下命令创建资源:

    kubectl apply -f certificate-name.yaml
    
  2. 创建 NodePort 服务,以便在互联网上公开应用。

    以下是一个 Service 清单文件示例:

    apiVersion: v1
    kind: Service
    metadata:
      name: service-name
    spec:
      selector:
        key: value
      type: NodePort
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    

    本示例规范使用 selector 选择要包含在 Service 中的 Pod。如需详细了解如何配置 Service,请参阅 NodePort 文档

    将清单另存为名为 service-name.yaml 的文件,然后使用以下命令创建 Service:

    kubectl apply -f service-name.yaml
    
  3. 创建一个 Ingress,将其关联到您之前创建的 ManagedCertificate。

    以下是一个 Ingress 清单示例:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: ingress-name
      annotations:
        kubernetes.io/ingress.global-static-ip-name: address-name
        networking.gke.io/managed-certificates: certificate-name
    spec:
      backend:
        serviceName: service-name
        servicePort: service-port
    

    其中:

    • ingress-name 是 Ingress 对象的名称。
    • address-name 是预留的 IP 地址的名称。
    • certificate-name 是您的证书的名称。
    • service-name 是您在上一步创建的服务的名称。
    • service-port 是您在 Service 清单中指定的端口。请注意,这应该是 port 字段(而不是 targetPort)的值。

    将清单另存为名为 ingress-name.yaml 的文件,然后使用以下命令创建 Ingress:

    kubectl apply -f ingress-name.yaml
    
  4. 查找上一步中创建的负载平衡器的 IP 地址。使用以下命令获取负载平衡器的 IP 地址:

    kubectl get ingress
    

    输出类似于以下内容:

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

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

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

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

  6. 等待预配托管式证书。此过程最多可能需要 15 分钟。您可以使用以下命令来查看证书的状态:

    kubectl describe managedcertificate certificate-name
    

    成功预配证书后,Status.CertificateStatus 字段的值将为 Active。以下示例显示了成功预配证书后 kubectl describe 的输出:

    Name:         certificate-name
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         ManagedCertificate
    (...)
    Spec:
      Domains:
        domain-name1
        domain-name2
    Status:
      CertificateStatus: Active
    (...)
    
  7. 使用 https:// 前缀访问您的网域,验证 SSL 是否正常工作。您的浏览器将指示连接是否安全,您可以查看证书详细信息。

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

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

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

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

    kubectl describe managedcertificate certificate-name
    
  3. 状态为“活跃”时,更新 Ingress,移除对自行管理证书的引用。

移除托管式证书

要从集群中移除托管式证书,您必须删除 ManagedCertificate 资源并移除引用它的 Ingress 注释。

  1. 使用 kubectl 删除 ManagedCertificate 资源:

    kubectl delete -f certificate-name.yaml
    

    您将获得以下输出:

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

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

    注意命令末尾的减号“-”。

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

    gcloud

    使用 gcloud 命令行工具:

    gcloud compute addresses delete address-name --global
    

    其中,address-name 是 IP 地址的名称。

    控制台

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

      转到“外部 IP 地址”页面

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

    配置连接器

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

    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

问题排查

本部分介绍了如何解决托管式证书的相关问题。

检查 ManagedCertificate 和 Ingress 资源上的事件

如果超过了允许的证书数量,则系统将向 ManagedCertificate v1 添加一个原因为 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。

托管式证书与 Ingress 之间的通信中断

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

  • 运行一个不断清理 kubernetes.io/pre-shared-cert 注释的自动化进程。
  • 存储 Ingress 的快照,损坏 Ingress,然后根据快照恢复 Ingress。在此期间,Ingress 的 pre-shared-cert 注释中列出的 SslCertificate 资源可能已被删除。Ingress 具有“一刀切” (all-or-nothing) 式的语义,如果缺失附加的任何证书,Ingress 将不起作用。

创建托管式证书时出现验证错误

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

spec.domains in body should have at most 100 items

您的 ManagedCertificate 清单在 spec.domains 字段中列出了超过 100 个网域。托管式证书最多只支持 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

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

手动更新由 Google 管理的证书

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

  1. 为新网域创建新的代管式证书。
  2. 将其关联到 Ingress,而不移除旧证书。
  3. 等待直到其变为活动状态。
  4. 从 Ingress 中分离旧证书并将其删除。

后续步骤