如何优雅的维护 K8S Worker 节点
前言
正常维护工作节点的流程
当我们要进行 K8S 节点维护时往往需要执行 kubectl drain
, 等待节点上的 Pod 被驱逐后再进行维护动作。
命令行如下:
kubectl drain NODE
待节点排空后再进行维护操作, 内核升级等。
存在问题吗?
drain
命令有一个问题, 他不会考虑资源所定义的 UpdateStrategy, 而直接强制驱逐或删除 Pod, 这样就会导致 Deployment 或 StatefulSet 资源的 Pod 达不到所设置的策略数.
思考一个案例
- 有一个 Deployment 资源, 它使用了如下配置
replicas: 2
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
副本数为 3, 采用了滚动更新, 并且先启动完成一个 Pod 后再进行旧 Pod 的删除(最大不可用为0,最小可用为2).
- 当下集群有 2 个 worker 节点
意味着, 其中一个节点被调度了 2 个 Pod, 其中一个节点被调度了 1 个 Pod.
假设 node1 运行着 pod1 和 pod3, node2 运行着 pod2. - 这时候 drain node1, 会出现 Deployment 只有一个 Pod 可用
更糟糕的情况
Deployment 的 Pod 全部运行在需要维护的节点上, 这时候执行 drain
那将是一个灾难, 这个 Deployment 在新的Pod启动之前它无法在对外提供服务了, 恢复的时间取决于新 Pod 的启动速度。
kubectl-safe-drain 项目
GitHub: https://github.com/majian159/kubectl-safe-drain
一个 kubectl 插件, 用于更为安全的排空节点。
对于 Deployment 和 StatefulSet 资源会根据其配置的更新策略先将Pod调度到其它可用节点。
逻辑和原理
- 先将需要排空的节点标记为不可调度 (kubectl cordon)
- 在找到该节点上的 Deployment 和 StatefulSet 资源
- 修改 Deployment 和 StatefulSet 的 PodTemplate, 让K8S根据对应的更新策略重新部署Pod, 这时候需要排空的节点不可被调度, 从而达到先将排空节点中的Pod安全重建到其它节点的逻辑。
目前支持安全迁移的资源
- Deployment
- StatefulSet
效果
首先我们有一个 Deployment 配置如下
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
操作前有两个可用 Pod
执行 safe-drain
后
查看 Deployment 变化过程
查看 Pod 变化过程
流程简述
从 Deployment watch 的信息中可见最小 Ready 数没有小于 2, 从 Pod watch 的信息中可见 kind-worker2 上承载了 2 个准备就绪的 nginx Pod, 也就是说 nginx 从 kind-worker 安全的移动到了 kind-worker2 节点上。
与 PDB (Pod Disruption Budget) 有什么区别?
PDB 只会保障 Pod 不被驱逐, 而不会帮助它在其它可用节点上重建。
使用了 PDB 后能防止服务不可用的尴尬情况,但它还是需要人工手动迁移 Pod。
理想的情况是搭配 PDB 使用, 防止严苛情况下服务不可用的问题。
安装
二进制文件
Linux
curl -sLo sdrain.tgz https://github.com/majian159/kubectl-safe-drain/releases/download/v0.0.1-preview1/kubectl-safe-drain_0.0.1-preview1_linux_amd64.tar.gz \
&& tar xf sdrain.tgz \
&& rm -f sdrain.tgz \
&& mv kubectl-safe-drain /usr/local/bin/kubectl-safe_drain
macOS
curl -sLo sdrain.tgz https://github.com/majian159/kubectl-safe-drain/releases/download/v0.0.1-preview1/kubectl-safe-drain_0.0.1-preview1_darwin_amd64.tar.gz \
&& tar xf sdrain.tgz \
&& rm -f sdrain.tgz \
&& mv kubectl-safe-drain /usr/local/bin/kubectl-safe_drain
Windows
基于 Krew
curl -O https://raw.githubusercontent.com/majian159/kubectl-safe-drain/master/krew.yaml \
&& kubectl krew install --manifest=krew.yaml \
&& rm -f krew.yaml
使用
kubectl safe-drain NODE
# safe-drain并没有调用 drain命令, 而是利用了 SchedulingDisabled 机制
# 所以如有需要可以继续使用 drain 命令来确保节点被驱逐
kubectl drain NODE
TODO
- 考虑节点亲和力和节点选择器的情况
- 输出更为友好的提示信息
写在最后
该项目部分代码源于 kubectl 项目。
如何优雅的维护 K8S Worker 节点的更多相关文章
- 使用KubeOperator扩展k8s集群的worker节点
官方文档网址:https://kubeoperator.io/docs/installation/install/ 背景说明 原先是一个三节点的k8s集群,一个master,三个woker(maste ...
- 013.Kubernetes二进制部署worker节点Nginx实现高可用
一 Nginx代理实现kube-apiserver高可用 1.1 Nginx实现高可用 基于 nginx 代理的 kube-apiserver 高可用方案. 控制节点的 kube-controller ...
- k8s pod节点调度及k8s资源优化
一.k8s pod 在节点间调度控制 k8s起pod时,会通过调度器scheduler选择某个节点完成调度,选择在某个节点上完成pod创建.当需要在指定pod运行在某个节点上时,可以通过以下几种方式: ...
- linux(centos8):安装kubernetes worker节点并加入到kubernetes集群(kubernetes 1.18.3)
一,安装kubernetes前的准备工作 安装前的准备工作(master\worker都要进行) 参见: https://www.cnblogs.com/architectfore ...
- ASP.NET Core on K8S学习初探(1)K8S单节点环境搭建
当近期的一个App上线后,发现目前的docker实例(应用服务BFF+中台服务+工具服务)已经很多了,而我司目前没有专业的运维人员,发现运维的成本逐渐开始上来,所以容器编排也就需要提上议程.因此我决定 ...
- k8s node节点部署(v1.13.10)
系统环境: node节点 操作系统: CentOS-7-x86_64-DVD-1908.iso node节点 IP地址: 192.168.1.204 node节点 hostname(主机名, 请和保持 ...
- Pod在多可用区worker节点上的高可用部署
一. 需求分析 当前kubernetes集群中的worker节点可以支持添加多可用区中的ECS,这种部署方式的目的是可以让一个应用的多个pod(至少两个)能够分布在不同的可用区,起码不能分布在同一个可 ...
- k8s删除节点
k8s 删除节点 线上环境 # ctl get nodes NAME STATUS ROLES AGE VERSION 10.0.0.123 Ready <none> 104d v1.20 ...
- K8s多节点部署+负载均衡+keepalived ——囊萤映雪
K8s多节点部署+负载均衡+keepalived --囊萤映雪 1.多节点master2 部署 2.负载均衡部署+keepalived 1.多节点master2部署: #从master01节点上拷贝证 ...
随机推荐
- js之for与forEach循环的区别
回武汉打卡第四天,武汉加油,逆战必胜!今天咱们探讨一下for循环和forEach()循环的区别. 首先,for循环在最开始执行循环的时候,会建立一个循环变量i,之后每次循环都是操作这个变量,也就是说它 ...
- F - 我们什么时候能见面? POJ - 2028
F - 我们什么时候能见面? POJ - 2028 ICPC委员会希望尽快召开会议,解决下一届比赛中的每一个小问题.然而,委员会的成员都忙于疯狂地开发(可能是无用的)程序,以至于很难安排他们的会议日程 ...
- Java – Try with Resources
1.介绍 Java 7中引入的对try-with-resources的支持使我们能够声明将在try块中使用的资源,并确保在执行该块后将关闭资源. ⚠️:声明的资源必须实现AutoCloseable接口 ...
- 使用Pytorch在多GPU下保存和加载训练模型参数遇到的问题
最近使用Pytorch在学习一个深度学习项目,在模型保存和加载过程中遇到了问题,最终通过在网卡查找资料得已解决,故以此记之,以备忘却. 首先,是在使用多GPU进行模型训练的过程中,在保存模型参数时,应 ...
- psutil运维必会模块
目录 psutil介绍 安装psutil 获取CPU信息 获取内存信息 获取磁盘信息 获取网络信息 获取进程信息 psutil介绍 用Python来编写脚本简化日常的运维工作是Python的一个重要用 ...
- 03使用Want Weapp进行路由跳转
因为这里使用的是第三方库,所以你要引入哈. 在app.json中引入哈. "usingComponents": { "van-cell": "@van ...
- (js描述的)数据结构[队列结构,优先级队列](3)
(js描述的)数据结构[队列结构](3) 一.队列结构的特点: 1.基于数组来实现,的一种受限的线性结构. 2.只允许在表头进行删除操作,在表尾进行插入操作. 3.先进先出(FIFO) 二.队列的一些 ...
- Go golang语言特性
一.垃圾回收 1.内存自动回收. 2.只需要创建,不需要释放 二.天然并发: 1.语言层支持并发,对比python,少了GIL锁. 2.goroute,轻量级线程. 3.基于CSP模型实现 三.cha ...
- Linux 权限管理篇(一)
可读 r 可写 w 可执行 x 档案属性: 第一栏:执行list -al后第一栏的十个标志[1 - 10] 1: d 目录 - 档案 l 连 ...
- 28.2 api-- System (gc、arraycopy、exit)
/* * System:包含一些有用的类字段和方法.它不能被实例化 * static void arraycopy(Object src, int srcPos, Object dest, int d ...