探索 Pod 及其端点的终止行为

一旦你按照将应用程序连接到服务中概述的步骤将应用程序与服务连接起来后,你就会拥有一个持续运行、复制的应用程序,该应用程序会在网络上公开。本教程帮助你了解 Pod 的终止流程,并探索实现优雅连接耗尽的方法。

Pod 及其端点的终止过程

在很多情况下,你需要终止 Pod,无论是为了升级还是缩减规模。为了提高应用程序的可用性,实施适当的活动连接耗尽可能很重要。

本教程通过使用一个简单的 nginx Web 服务器来演示概念,解释 Pod 终止与相应端点状态以及删除之间的流程。

带端点终止的示例流程

以下是在Pod 终止文档中描述的示例流程。

假设你有一个 Deployment,其中包含一个 nginx 副本(假设只是为了演示目的)和一个 Service。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 120 # extra long grace period
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        lifecycle:
          preStop:
            exec:
              # Real life termination may take any time up to terminationGracePeriodSeconds.
              # In this example - just hang around for at least the duration of terminationGracePeriodSeconds,
              # at 120 seconds container will be forcibly terminated.
              # Note, all this time nginx will keep processing requests.
              command: [
                "/bin/sh", "-c", "sleep 180"
              ]
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

现在使用上面的文件创建 Deployment Pod 和 Service。

kubectl apply -f pod-with-graceful-termination.yaml
kubectl apply -f explore-graceful-termination-nginx.yaml

一旦 Pod 和 Service 运行起来,你可以获取任何关联的 EndpointSlices 的名称。

kubectl get endpointslice

输出类似于这样

NAME                  ADDRESSTYPE   PORTS   ENDPOINTS                 AGE
nginx-service-6tjbr   IPv4          80      10.12.1.199,10.12.1.201   22m

你可以看到它的状态,并验证是否注册了一个端点。

kubectl get endpointslices -o json -l kubernetes.io/service-name=nginx-service

输出类似于这样

{
    "addressType": "IPv4",
    "apiVersion": "discovery.k8s.io/v1",
    "endpoints": [
        {
            "addresses": [
                "10.12.1.201"
            ],
            "conditions": {
                "ready": true,
                "serving": true,
                "terminating": false

现在让我们终止 Pod,并验证 Pod 是否在终止时尊重了优雅终止期限配置。

kubectl delete pod nginx-deployment-7768647bf9-b4b9s

所有 Pod

kubectl get pods

输出类似于这样

NAME                                READY   STATUS        RESTARTS      AGE
nginx-deployment-7768647bf9-b4b9s   1/1     Terminating   0             4m1s
nginx-deployment-7768647bf9-rkxlw   1/1     Running       0             8s

你可以看到新的 Pod 被调度了。

在为新的 Pod 创建新端点的同时,旧端点仍然处于终止状态。

kubectl get endpointslice -o json nginx-service-6tjbr

输出类似于这样

{
    "addressType": "IPv4",
    "apiVersion": "discovery.k8s.io/v1",
    "endpoints": [
        {
            "addresses": [
                "10.12.1.201"
            ],
            "conditions": {
                "ready": false,
                "serving": true,
                "terminating": true
            },
            "nodeName": "gke-main-default-pool-dca1511c-d17b",
            "targetRef": {
                "kind": "Pod",
                "name": "nginx-deployment-7768647bf9-b4b9s",
                "namespace": "default",
                "uid": "66fa831c-7eb2-407f-bd2c-f96dfe841478"
            },
            "zone": "us-central1-c"
        },
        {
            "addresses": [
                "10.12.1.202"
            ],
            "conditions": {
                "ready": true,
                "serving": true,
                "terminating": false
            },
            "nodeName": "gke-main-default-pool-dca1511c-d17b",
            "targetRef": {
                "kind": "Pod",
                "name": "nginx-deployment-7768647bf9-rkxlw",
                "namespace": "default",
                "uid": "722b1cbe-dcd7-4ed4-8928-4a4d0e2bbe35"
            },
            "zone": "us-central1-c"

这允许应用程序在终止期间传达它们的状态,并允许客户端(如负载均衡器)实现连接耗尽功能。这些客户端可以检测到正在终止的端点,并为其实现特殊的逻辑。

在 Kubernetes 中,正在终止的端点的 ready 状态始终设置为 false。这需要为了向后兼容而发生,以便现有的负载均衡器不会将其用于常规流量。如果需要在终止 Pod 上耗尽流量,则可以将实际的就绪状态作为条件 serving 进行检查。

当 Pod 被删除时,旧的端点也将被删除。

下一步

上次修改时间为 2024 年 11 月 18 日下午 6:41 PST:docs: factor out typos into new pr (6a73d0e087)