本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.24:gRPC 容器探针进入 Beta 阶段

_更新:自本文发布以来,该功能已在 v1.27 中升级为 GA(正式发布),无需启用任何特性门控。_

在 Kubernetes 1.24 中,gRPC 探针功能进入 Beta 阶段并默认可用。现在,你可以为你的 gRPC 应用配置启动(startup)、存活(liveness)和就绪(readiness)探针,而无需暴露任何 HTTP 端点,也不需要额外的可执行文件。Kubernetes 可以通过 gRPC 原生连接到你的工作负载并查询其状态。

历史回顾

让管理你工作负载的系统能够检查应用是否健康、是否已正常启动以及应用是否认为自己可以接受流量,这是非常有用的。在增加 gRPC 支持之前,Kubernetes 已经允许你通过在容器镜像内部运行可执行文件、发出 HTTP 请求或检查 TCP 连接是否成功来检查健康状况。

对于大多数应用来说,这些检查已经足够了。如果你的应用为健康(或就绪)检查提供了一个 gRPC 端点,那么很容易将 exec 探针 repurposed 用于 gRPC 健康检查。在博客文章 在 Kubernetes 上对 gRPC 服务器进行健康检查 中,Ahmet Alp Balkan 描述了如何做到这一点——这个机制至今仍然有效。

有一个常用的工具可以实现这一点,该工具于 2018 年 8 月 21 日 创建,并于 2018 年 9 月 19 日发布了第一个版本。

这种对 gRPC 应用进行健康检查的方法非常流行。在撰写本文时,通过 GitHub 的基本搜索发现,有 3,626 个 Dockerfile 包含 grpc_health_probe,以及 6,621 个 yaml 文件。这很好地说明了该工具的受欢迎程度以及原生支持此功能的需求。

Kubernetes v1.23 引入了一个 Alpha 质量的原生支持,用于通过 gRPC 查询工作负载状态。由于它是一个 Alpha 功能,在 v1.23 版本中默认是禁用的。

使用该功能

我们以与其他探针类似的方式构建了 gRPC 健康检查,并相信如果你熟悉 Kubernetes 中的其他探针类型,它会易于使用。与涉及 grpc_health_probe 可执行文件的变通方法相比,原生支持的健康探针有许多好处。

有了原生的 gRPC 支持,你就不需要在你的镜像中下载并携带一个 10MB 的额外可执行文件。Exec 探针通常比 gRPC 调用慢,因为它们需要实例化一个新进程来运行可执行文件。这也使得在 Pod 资源使用达到上限且难以实例化新进程的边缘情况下,这些检查的敏感性降低。

不过也有一些限制。由于为探针配置客户端证书很困难,所以不支持需要客户端身份验证的服务。内置探针也不会检查服务器证书并忽略相关问题。

内置检查也无法配置为忽略某些类型的错误(grpc_health_probe 会为不同的错误返回不同的退出码),也无法“链式”地在单个探针中对多个服务运行健康检查。

但所有这些限制对于 gRPC 来说都是相当标准的,并且有简单的变通方法可以解决。

亲自动手尝试

集群级别的设置

你今天就可以尝试这个功能。要尝试原生的 gRPC 探针,你可以自己启动一个启用了 GRPCContainerProbe 特性门控的 Kubernetes 集群,有许多可用的工具

由于特性门控 GRPCContainerProbe 在 1.24 版本中默认启用,许多供应商将提供开箱即用的此功能。因此,你只需在你选择的平台上创建一个 1.24 版本的集群即可。一些供应商也允许在 1.23 版本的集群上启用 Alpha 功能。

例如,在撰写本文时,你可以在 GKE 上启动一个测试集群进行快速测试。其他供应商也可能有类似的功能,特别是如果你在 Kubernetes 1.24 发布很久之后阅读这篇博客文章。

在 GKE 上,使用以下命令(注意,版本是 1.23 并且指定了 enable-kubernetes-alpha)。

gcloud container clusters create test-grpc \
    --enable-kubernetes-alpha \
    --no-enable-autorepair \
    --no-enable-autoupgrade \
    --release-channel=rapid \
    --cluster-version=1.23

你还需要配置 kubectl 以访问该集群。

gcloud container clusters get-credentials test-grpc

试用该功能

让我们创建一个 Pod 来测试 gRPC 探针的工作方式。对于这个测试,我们将使用 agnhost 镜像。这是一个由 k8s 维护的镜像,可用于各种工作负载测试。例如,它有一个有用的 grpc-health-checking 模块,该模块暴露两个端口——一个用于提供健康检查服务,另一个是 HTTP 端口,用于响应 make-servingmake-not-serving 命令。

这是一个 Pod 定义的示例。它启动 grpc-health-checking 模块,暴露端口 50008080,并配置 gRPC 就绪探针。

---
apiVersion: v1
kind: Pod
metadata:
  name: test-grpc
spec:
  containers:
  - name: agnhost
    # image changed since publication (previously used registry "k8s.gcr.io")
    image: registry.k8s.io/e2e-test-images/agnhost:2.35
    command: ["/agnhost", "grpc-health-checking"]
    ports:
    - containerPort: 5000
    - containerPort: 8080
    readinessProbe:
      grpc:
        port: 5000

在名为 test.yaml 的清单文件中,你可以创建 Pod 并检查其状态。如输出片段所示,Pod 将处于就绪状态。

kubectl apply -f test.yaml
kubectl describe test-grpc

输出将包含类似以下内容:

Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True

现在让我们将健康检查端点的状态更改为 NOT_SERVING。为了调用 Pod 的 HTTP 端口,让我们创建一个端口转发。

kubectl port-forward test-grpc 8080:8080

你可以使用 curl 来调用该命令...

curl https://:8080/make-not-serving

...几秒钟后,端口状态将切换为未就绪。

kubectl describe pod test-grpc

现在的输出将是:

Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True

...

  Warning  Unhealthy  2s (x6 over 42s)  kubelet            Readiness probe failed: service unhealthy (responded with "NOT_SERVING")

一旦切换回来,大约一秒钟后,Pod 将恢复到就绪状态。

curl https://:8080/make-serving
kubectl describe test-grpc

输出表明 Pod 已经恢复到 Ready 状态。

Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True

Kubernetes 上这个新的内置 gRPC 健康探测功能,使得通过 gRPC 实现健康检查比依赖于单独的 exec 探针的旧方法要容易得多。请阅读官方文档以了解更多信息,并在该功能升级到 GA(正式发布)之前提供反馈。

总结

Kubernetes 是一个流行的工作负载编排平台,我们根据反馈和需求添加新功能。像 gRPC 探针支持这样的功能是一个小改进,它将使许多应用开发人员的生活更轻松,并使应用更具弹性。今天就试试吧,并在该功能进入 GA 之前提供你的反馈。