Kubernetes中的优雅关闭和零停机时间部署
新钛云服已累计为您分享771篇技术干货
在Kubernetes中,创建和删除Pod是最常见的任务之一。
当你执行滚动更新、扩展部署、发布新版本、执行作业和定时作业等操作时,都会创建Pod。
但是,在Pod被驱逐后,例如将节点标记为不可调度时,Pod也会被删除并重新创建。
如果这些Pod的性质是如此短暂,那么当一个Pod正在响应请求时,如果被告知关闭,会发生什么?在关闭之前,请求是否会完成?那么后续的请求呢?是否会被重定向到其他地方?
在讨论Pod被删除时会发生什么之前,有必要谈谈当Pod被创建时会发生什么。
假设你想在集群中创建以下Pod:
pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
$ kubectl apply -f pod.yaml
在数据库中保存集群的状态
Pod的定义被API接收并进行检查,随后存储在数据库(etcd)中。
Pod也被添加到调度器的队列中。
调度器执行以下操作:
- 检查Pod的定义。
- 收集关于工作负载的详细信息,例如CPU和内存请求。
- 通过筛选器和判定的过程决定最适合运行该Pod的节点。
在此过程结束时:
- Pod在etcd中被标记为已调度。
- Pod被分配给一个节点。
- Pod的状态被存储在etcd中。
然而,此时Pod仍然不存在。
- 当你使用
kubectl apply -f
命令提交一个Pod的YAML文件时,该YAML文件会被发送到Kubernetes API。 - API将Pod保存在数据库(etcd)中。
3. 调度器为该Pod分配了最适合的节点,Pod的状态变为Pending。此时,Pod只存在于etcd中。
在控制平面中发生了前述任务,并且状态存储在数据库中。
**那么是谁在你的节点上创建Pod呢?
Kubelet-Kubernetes代理
容器运行时接口(CRI):负责为Pod创建容器。 容器网络接口(CNI):负责将容器连接到集群网络并分配IP地址。 容器存储接口(CSI):负责在容器中挂载卷。
$ docker run -d <my-container-image>
为Pod生成有效的IP地址。 将容器连接到网络的其他部分。
Pods和服务
选择器(selector):用于指定接收流量的Pod。 目标端口(targetPort):Pod用于接收流量的端口。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 3000
selector:
name: app
IP address + port = endpoint
---------------------------------
10.0.0.3 + 3000 = 10.0.0.3:3000
$ kubectl get services,endpoints
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
service/my-service-1 ClusterIP 10.105.17.65 <none> 80/TCP
service/my-service-2 ClusterIP 10.96.0.1 <none> 443/TCP
NAME ENDPOINTS
endpoints/my-service-1 172.17.0.6:80,172.17.0.7:80
endpoints/my-service-2 192.168.99.100:8443
创建一个Pod。 删除一个Pod。 在Pod上修改标签。
$ kubectl get services,endpoints
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
service/my-service-1 ClusterIP 10.105.17.65 <none> 80/TCP
service/my-service-2 ClusterIP 10.96.0.1 <none> 443/TCP
NAME ENDPOINTS
endpoints/my-service-1 172.17.0.6:80,172.17.0.7:80
endpoints/my-service-2 192.168.99.100:8443
6. 当删除一个Pod时会发生什么?
7. 服务立即移除该端点,最终该Pod也会从数据库中删除。
在Kubernetes中使用端点
端点在Kubernetes中被多个组件使用。
让我们考虑一个由三个节点组成的集群,其中有两个Pod,并且没有服务。Pod的状态被存储在etcd中。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- backend:
service:
name: my-service
port:
number: 80
path: /
pathType: Prefix
在这张图片中,有一个带有两个副本的Ingress控制器和一个Service的部署(Deployment)。
2. 如果你想通过Ingress将外部流量路由到Pods,你应该创建一个Ingress配置文件(一个YAML文件)。
kubectl apply -f ingress.yaml
命令,Ingress控制器就会从控制平面中获取配置文件。serviceName
属性,用于描述应该使用哪个Service。Pod被存储在etcd中。 调度器分配一个节点,并将该节点写入etcd。 kubelet收到新的已调度Pod的通知。 kubelet将创建容器的任务委托给容器运行时接口(CRI)。 kubelet将容器连接到容器网络接口(CNI)的任务委托给它。 kubelet将容器中的挂载卷的任务委托给容器存储接口(CSI)。 容器网络接口分配一个IP地址。 kubelet将IP地址报告给控制平面。 IP地址被存储在etcd中。
kubelet等待成功的就绪探针(Readiness probe)。 所有相关的端点(对象)都会收到变更的通知。 端点将新的端点(IP地址+端口对)添加到它们的列表中。 Kube-proxy收到端点变更的通知。Kube-proxy在每个节点上更新iptables规则。 Ingress控制器收到端点变更的通知。控制器将流量路由到新的IP地址上。 CoreDNS收到端点变更的通知。如果Service的类型是Headless,DNS条目将被更新。 云服务提供商收到端点变更的通知。如果Service的类型是LoadBalancer,新的端点将作为负载均衡池的一部分进行配置。 集群中安装的任何服务网格都会收到端点变更的通知。 任何订阅端点变更的其他操作员也会收到通知。
删除Pod
kubectl delete pod
删除一个Pod,该命令首先会发送到Kubernetes API。将容器中的任何挂载卷从容器存储接口(CSI)卸载。 将容器从网络中分离,并释放IP地址给容器网络接口(CNI)。 将容器销毁给容器运行时接口(CRI)。
kubectl delete pod
删除一个Pod,该命令首先会发送到Kubernetes API。优雅关闭
在退出之前等待更长的时间。 尽管收到SIGTERM信号,仍然处理传入的流量。 最后,关闭现有的长连接(例如数据库连接或WebSockets)。 关闭进程。
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
lifecycle:
preStop:
exec:
command: ["sleep", "15"]
优雅期限和滚动更新
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 3
selector:
matchLabels:
name: app
template:
metadata:
labels:
name: app
spec:
containers:
- name: app
# image: nginx:1.18 OLD
image: nginx:1.19
ports:
- containerPort: 3000
创建一个包含新容器镜像的Pod。 销毁一个现有的Pod。 等待Pod就绪。
首先创建一个新的Pod,并终止一个之前的Pod。 新的Pod需要2秒钟准备就绪,然后Kubernetes创建一个新的Pod。 与此同时,正在终止的Pod保持终止状态20秒钟。
终止长时间运行的任务
总结
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。