这篇文章已超过一年。较旧的文章可能包含过时的内容。请检查页面上的信息自发布以来是否已失效。

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

_更新:自本文发布以来,该功能已在 v1.27 中升级到 GA,并且不需要启用任何 feature gates。

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

一些历史回顾

让管理工作负载的系统检查应用程序是否健康、是否正常启动以及应用程序自身是否可以接受流量,这是很有用的。在添加 gRPC 支持之前,Kubernetes 已经允许您通过在容器镜像内运行可执行文件、发起 HTTP 请求或检查 TCP 连接是否成功来进行健康检查。

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

有一个常用的工具可以实现这一点,它于 2018 年 8 月 21 日创建,并于 2018 年 9 月 19 日首次发布

这种用于 gRPC 应用程序健康检查的方法非常流行。在 GitHub 上进行基本搜索时,可以找到包含 grpc_health_probe3,626 个 Dockerfile6,621 个 yaml 文件(截至撰写本文时)。这很好地表明了该工具的流行程度以及原生支持此功能的必要性。

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

使用此功能

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

借助原生 gRPC 支持,您无需下载并随镜像携带额外的 10MB 可执行文件。Exec 探针通常比 gRPC 调用慢,因为它们需要实例化一个新的进程来运行可执行文件。这使得在 Pod 运行在最大资源并难以实例化新进程的边缘情况下,检查变得不那么敏感。

不过,也存在一些限制。由于为探针配置客户端证书很困难,因此不支持需要客户端认证的服务。内置探针也不检查服务器证书并忽略相关问题。

内置检查也不能配置为忽略某些类型的错误(grpc_health_probe 对不同的错误返回不同的退出代码),并且不能“链式调用”在一个探针中对多个服务运行健康检查。

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

自己试试

集群级设置

您今天就可以尝试此功能。要试用原生 gRPC 探针,您可以自己启动一个启用了 GRPCContainerProbe feature gate 的 Kubernetes 集群,有许多工具可用

由于 feature gate 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 的 manifest 文件中,您可以创建 Pod 并检查其状态。根据输出片段所示,Pod 将处于 ready 状态。

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 http://localhost:8080/make-not-serving

... 几秒钟后,端口状态将切换为 not ready。

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 将恢复到 ready 状态

curl http://localhost: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 之前提供反馈。