探索 Pod 及其 Endpoints 的终止行为
遵循诸如将应用程序与 Service 相关联中概述的步骤,将应用程序与 Service 连接后,你就拥有了一个持续运行、已复制且在网络上暴露的应用程序。本教程将帮助你了解 Pod 的终止流程,并探讨如何实现优雅的连接排空。
Pod 及其端点的终止过程
在许多情况下,你需要终止一个 Pod——无论是为了升级还是缩容。为了提高应用程序的可用性,实现适当的活跃连接排空可能非常重要。
本教程使用一个简单的 nginx Web 服务器来演示这一概念,解释了 Pod 终止与其对应端点状态和移除相关的流程。
端点终止的示例流程
以下是在Pod 的终止文档中描述的示例流程。
假设你有一个包含单个 nginx
副本的 Deployment(例如,仅为了演示目的)和一个 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 运行后,你可以获取任何关联的 EndpointSlice 的名称。
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 被删除时,旧的端点也将被删除。
下一步
- 学习如何将应用程序与 Service 相关联
- 学习更多关于使用 Service 访问集群中的应用程序的信息
- 学习更多关于使用 Service 连接前端与后端的信息
- 学习更多关于创建外部负载均衡器的信息