在升级到 GKE 1.29 版之前确保 TLS 证书的兼容性


运行 1.29 版或更高版本的 GKE 集群不支持使用 SHA-1 算法签名的传输层安全协议 (TLS) 证书。为了防止您的集群受到影响,您需要先将 webhook扩展程序 API 服务器后端的不兼容证书替换为使用兼容的签名算法的证书,然后再将集群升级到 1.29 版。

此移除行为对集群的影响

GKE 在检测到集群所使用的证书与 1.29 版不兼容时,会暂停自动升级。在将证书替换为使用兼容的签名算法的证书或是 1.28 版服务终止之后,GKE 会继续进行自动升级。

如果您在升级到 1.29 版之前未替换不兼容的证书,则您的集群可能会遇到以下问题:

  • 使用通过 SHA-1 算法签名的 TLS 证书的 GKE webhook 后端会由于身份验证失败而停止工作。对于与使用不兼容证书的 webhook 通信的 Kubernetes 控制平面,webhook 调用会失败。根据您的配置,尤其是在使用准入 webhook 时,无法联系 webhook 可能会阻止集群上的资源创建(例如 Pod 创建),这可能很容易造成中断。
  • 调用由扩展程序 API 服务器提供服务的 API 的操作会失败。

Kubernetes 为什么移除此功能

GKE 运行的是开源 Kubernetes,它使用 kube-apiserver 组件,通过 TLS 联系您的 webhook 和扩展程序 API 服务器后端。kube-apiserver 组件是使用 Go 编程语言编写的。

从 Go 1.18 版开始,Go 开始拒绝使用 SHA-1 算法签名的 TLS 证书,但留下了一个调试开关 x509sha1=1 来用于启用旧行为,从而简化迁移过程。GKE 1.24 版是使用 Go 1.18 版构建的第一个版本。Kubernetes 的 GKE 构建在 1.29 版之前一直启用此调试开关。此开关将在 Go 1.24 版中移除。GKE 1.29 版在构建 Kubernetes 时停用了此开关,以便为将来 Go 移除此调试开关做好准备。在 GKE 将您的集群升级到 1.29 版之后,从集群的控制平面调用集群中提供用 SHA-1 算法签名的 TLS 证书的 webhook 或扩展程序 API 服务器的操作会失败。

识别受影响的集群

GKE 会监控集群,并使用 Recommender 服务通过分析洞见和建议提供指导信息,以识别满足以下条件的集群:其 webhook 或扩展程序 API 服务器后端使用通过 SHA-1 算法签名的 TLS 证书。或者,您可以使用日志来识别从集群调用受影响后端的操作。

如何获取分析洞见和建议

对于运行 1.24 版或更高版本的集群,请按照说明查看分析洞见和建议。 您可以使用 gcloud CLI 或 Recommender API 获取分析洞见,并使用子类型 DEPRECATION_K8S_SHA_1_CERTIFICATE 进行过滤。

如何获取日志

对于在启用了 Cloud Logging 的情况下运行 1.24 版或更高版本的集群,GKE 提供 Cloud Audit Logs 日志来识别从集群调用受影响后端的操作。您可以使用以下过滤条件来搜索日志:

logName =~ "projects/.*/logs/cloudaudit.googleapis.com%2Factivity"
resource.type = "k8s_cluster"
operation.producer = "k8s.io"
"insecure-sha1.invalid-cert.kubernetes.io"

审核日志包括受影响后端的主机名。如需详细了解如何解读结果,请参阅下一部分。

从分析洞见和建议中解读指导信息

建议包括受影响后端的主机名以及它是 webhook 还是扩展程序 API 服务器。引用集群中的 Service 的主机名遵循 <service-name>.<namespace>.svc 格式。

如果受影响后端证书来自 webhook 服务器,则主机名可以是集群中的 Service,也可以是网址。如需了解详情,请参阅联系 webhook

如果受影响证书来自扩展程序 API 服务器,则主机名是集群中的 Service。如需了解详情,请参阅联系扩展程序 API 服务器

在识别出受影响的后端之后,请按照说明检查 Service 的证书检查网址后端的证书,具体取决于类型。

如果您的集群在过去 30 天内未调用使用受影响证书的服务器,您不会看到任何建议。

示例建议

请参阅以下示例建议列表:

RECOMMENDATION_ID                     PRIMARY_IMPACT_CATEGORY  RECOMMENDATION_STATE  LAST_REFRESH_TIME               PRIORITY  RECOMMENDER_SUBTYPE                DESCRIPTION
26bfcb32-6f2a-407c-874f-8cf55b3af912  RELIABILITY              ACTIVE                2024-02-15T01:09:04.454456273Z  P2        DEPRECATION_K8S_SHA_1_CERTIFICATE  Update the webhook and/or extension API servers that use certificates signed with SHA-1 algorithm to use certificates with compatible signing algorithms prior to upgrading the cluster to version 1.29. [Learn more](https://cloud.google.com/kubernetes-engine/docs/deprecations/sha1-1-29#mitigate_the_risk_of_upgrading_to_129).

如需获取集群和 Service 的详细信息,请描述建议default 命名空间中名为 example-webhook 的 Service 的输出类似于以下内容:

associatedInsights:
- insight: projects/<CLUSTER_PROJECT_NUMBER>/locations/<CLUSTER_LOCATION>/insightTypes/google.container.DiagnosisInsight/insights/d76887a8-9eed-41a0-9459-d49dee43455e
content:
  overview:
    featureDeprecationRecommendation:
    - featureName: x.509_certificate_signature_algorithm
      featureReplacementValue: algorithm [compatible with GKE v1.29](https://cloud.google.com/kubernetes-engine/docs/deprecations/sha1-1-29#compatible-signing-algorithms)
      featureValue: SHA1
      stopServingVersion: '1.29'
      targetType: hostname
      targetValue: example-webhook.default.svc
    targetClusters:
    - clusterId: 3be916a554724c79a2314c8baee3fd57cf1c39df1ad34c3daf291db701b6d541
      clusterUri: //container.googleapis.com/projects/<CLUSTER_PROJECT_NUMBER>/locations/<CLUSTER_LOCATION>/clusters/<CLUSTER_NAME>
description: Update the webhook and/or extension API servers that use certificates
  signed with SHA-1 algorithm to use certificates with compatible signing algorithms
  prior to upgrading the cluster to version 1.29. [Learn more](https://cloud.google.com/kubernetes-engine/docs/deprecations/sha1-1-29#mitigate_the_risk_of_upgrading_to_129).
etag: '"ad50aac8278951d5"'
lastRefreshTime: '2024-02-15T01:09:04.454456273Z'
name: projects/<CLUSTER_PROJECT_NUMBER>/locations/<CLUSTER_LOCATION>/recommenders/google.container.DiagnosisRecommender/recommendations/26bfcb32-6f2a-407c-874f-8cf55b3af912
primaryImpact:
  category: RELIABILITY
  reliabilityProjection:
    risks:
    - SERVICE_DISRUPTION
priority: P2
recommenderSubtype: DEPRECATION_K8S_SHA_1_CERTIFICATE
stateInfo:
  state: ACTIVE
targetResources:
- //container.googleapis.com/projects/<CLUSTER_PROJECT_NUMBER>/locations/<CLUSTER_LOCATION>/clusters/<CLUSTER_NAME>

检查 Service 的证书

webhook 和扩展程序 API 服务器均可由 Service 提供支持。

在识别出要检查的相关后端 Service 之后,请按照以下说明检查每个 Service 的证书,以检查哪些证书使用 SHA-1 算法并需要更新。

  1. 找到该 Service 的选择器和目标端口:

    kubectl describe service --namespace=NAMESPACE SERVICE_NAME
    

    NAMESPACESERVICE_NAME 替换为来自 targetValue 的值。

    输出类似于以下内容:

    Name: example-service
    Namespace: default
    Labels: run=nginx
    Selector: run=nginx
    Type: ClusterIP
    IP: 172.21.xxx.xxx
    Port: 443
    TargetPort: 444
    

    此输出表明 example-service 具有选择器 run=nginx 和目标端口 444

  2. 找到与选择器匹配的 Pod:

    kubectl get pods --namespace=NAMESPACE --selector=run=nginx
    

    输出类似于以下内容:

    NAME          READY   STATUS    RESTARTS   AGE
    example-pod   1/1     Running   0          21m
    

    此输出表明匹配的 Pod 为 example-pod

  3. 设置从您的 kubectl localhost 到 Pod 的端口转发:

    kubectl port-forward --namespace=NAMESPACE pods/example-pod 8888:SERVICE_TARGET_PORT &
    

    SERVICE_TARGET_PORT 替换为来自 Service 的 TargetPort 值。如果未包含 TargetPort,则使用 Port 值。

  4. 使用 openssl 显示 Service 使用的证书:

    openssl s_client -connect localhost:8888 </dev/null | openssl x509 -noout -text
    

    此示例输出显示使用 SHA-256 算法签名的有效证书:

    Certificate:
        Data:
            ...
            Signature Algorithm: sha256WithRSAEncryption
    ...
        Signature Algorithm: sha256WithRSAEncryption
    

    此示例输出显示使用 SHA-1 算法签名的无效证书:

    Certificate:
        Data:
            ...
            Signature Algorithm: sha1WithRSAEncryption
    ...
        Signature Algorithm: sha1WithRSAEncryption
    

    如果证书具有类似输出,您必须更新证书以使用兼容的签名算法。例如,如果您使用 certificate.k8s.io API 管理集群中的 TLS 证书,则可以按照说明创建证书签名请求

清理端口转发

如需清理在后台运行的端口转发,请找到该进程并终止它。

  1. 运行以下命令以列出正在运行的进程:

    jobs
    

    查看输出以获取要终止的进程的 ID:

    [1]+  Running                 kubectl port-forward pods/example-pod 8888:444 &
    

    此示例输出表明进程 ID 为 1

  2. 终止该进程(在命令中替换 PROCESS_ID):

    kill %PROCESS_ID
    

    请参阅以下输出:

    [1]+  Terminated              kubectl port-forward pods/example 8888:444
    

    此示例输出显示进程已终止。

检查网址后端的证书

如果 webhook 使用 url 后端,请直接连接到网址中指定的主机名。例如,如果网址为 https://example.com:123/foo/bar,请使用以下 openssl 命令显示后端使用的证书:

openssl s_client -connect example.com:123 </dev/null | openssl x509 -noout -text

此示例输出显示使用 SHA-256 算法签名的有效证书:

Certificate:
    Data:
        ...
        Signature Algorithm: sha256WithRSAEncryption
...
    Signature Algorithm: sha256WithRSAEncryption

此示例输出显示使用 SHA-1 算法签名的无效证书:

Certificate:
    Data:
        ...
        Signature Algorithm: sha1WithRSAEncryption
...
    Signature Algorithm: sha1WithRSAEncryption

如果证书具有类似输出,您必须更新证书以使用兼容的签名算法。例如,如果您使用 certificate.k8s.io API 管理集群中的 TLS 证书,则可以按照说明创建证书签名请求

降低升级到 1.29 版的风险

在识别出受影响的集群及其使用通过 SHA-1 算法签名的证书的后端 Service 之后,您必须在将集群升级到 1.29 版之前,更新 Service 以使用具有兼容的签名算法的证书。

受影响的集群由 GKE 自动检测,不会自动升级到 1.29 版,直到不再使用不兼容的证书或 1.28 版服务终止。 一旦 1.28 版服务终止,集群便会自动升级到 1.29 版。

兼容的签名算法

GKE 1.29 版与 Go x509 软件包中支持的算法兼容。这包括以下算法:

  • SHA256WithRSA
  • SHA384WithRSA
  • SHA512WithRSA
  • ECDSAWithSHA256
  • ECDSAWithSHA384
  • ECDSAWithSHA512
  • SHA256WithRSAPSS
  • SHA384WithRSAPSS
  • SHA512WithRSAPSS
  • PureEd25519

如需查找可用算法,请查看 x509.go 源文件并搜索 UnknownSignatureAlgorithm SignatureAlgorithm = iota。Go x509 软件包支持的算法会在包含上述搜索内容的 const 块中列出。如需查找不支持的不安全签名算法,请在该文件中搜索 InsecureAlgorithmError 的使用情况。

资源

如需详细了解此变化,请参阅以下资源: