前言

正常维护工作节点的流程

当我们要进行 K8S 节点维护时往往需要执行 kubectl drain, 等待节点上的 Pod 被驱逐后再进行维护动作。

命令行如下:

kubectl drain NODE

待节点排空后再进行维护操作, 内核升级等。

存在问题吗?

drain 命令有一个问题, 他不会考虑资源所定义的 UpdateStrategy, 而直接强制驱逐或删除 Pod, 这样就会导致 Deployment 或 StatefulSet 资源的 Pod 达不到所设置的策略数.

思考一个案例

  1. 有一个 Deployment 资源, 它使用了如下配置
     replicas: 2
    strategy:
    rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0
    type: RollingUpdate

    副本数为 3, 采用了滚动更新, 并且先启动完成一个 Pod 后再进行旧 Pod 的删除(最大不可用为0,最小可用为2).

  2. 当下集群有 2 个 worker 节点

    意味着, 其中一个节点被调度了 2 个 Pod, 其中一个节点被调度了 1 个 Pod.

    假设 node1 运行着 pod1 和 pod3, node2 运行着 pod2.
  3. 这时候 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调度到其它可用节点。

逻辑和原理

  1. 先将需要排空的节点标记为不可调度 (kubectl cordon)
  2. 在找到该节点上的 Deployment 和 StatefulSet 资源
  3. 修改 Deployment 和 StatefulSet 的 PodTemplate, 让K8S根据对应的更新策略重新部署Pod, 这时候需要排空的节点不可被调度, 从而达到先将排空节点中的Pod安全重建到其它节点的逻辑。

目前支持安全迁移的资源

  1. Deployment
  2. 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

https://github.com/majian159/kubectl-safe-drain/releases/download/v0.0.1-preview1/kubectl-safe-drain_0.0.1-preview1_windows_amd64.tar.gz

基于 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

  1. 考虑节点亲和力和节点选择器的情况
  2. 输出更为友好的提示信息

写在最后

该项目部分代码源于 kubectl 项目。

如何优雅的维护 K8S Worker 节点的更多相关文章

  1. 使用KubeOperator扩展k8s集群的worker节点

    官方文档网址:https://kubeoperator.io/docs/installation/install/ 背景说明 原先是一个三节点的k8s集群,一个master,三个woker(maste ...

  2. 013.Kubernetes二进制部署worker节点Nginx实现高可用

    一 Nginx代理实现kube-apiserver高可用 1.1 Nginx实现高可用 基于 nginx 代理的 kube-apiserver 高可用方案. 控制节点的 kube-controller ...

  3. k8s pod节点调度及k8s资源优化

    一.k8s pod 在节点间调度控制 k8s起pod时,会通过调度器scheduler选择某个节点完成调度,选择在某个节点上完成pod创建.当需要在指定pod运行在某个节点上时,可以通过以下几种方式: ...

  4. linux(centos8):安装kubernetes worker节点并加入到kubernetes集群(kubernetes 1.18.3)

    一,安装kubernetes前的准备工作      安装前的准备工作(master\worker都要进行)      参见: https://www.cnblogs.com/architectfore ...

  5. ASP.NET Core on K8S学习初探(1)K8S单节点环境搭建

    当近期的一个App上线后,发现目前的docker实例(应用服务BFF+中台服务+工具服务)已经很多了,而我司目前没有专业的运维人员,发现运维的成本逐渐开始上来,所以容器编排也就需要提上议程.因此我决定 ...

  6. k8s node节点部署(v1.13.10)

    系统环境: node节点 操作系统: CentOS-7-x86_64-DVD-1908.iso node节点 IP地址: 192.168.1.204 node节点 hostname(主机名, 请和保持 ...

  7. Pod在多可用区worker节点上的高可用部署

    一. 需求分析 当前kubernetes集群中的worker节点可以支持添加多可用区中的ECS,这种部署方式的目的是可以让一个应用的多个pod(至少两个)能够分布在不同的可用区,起码不能分布在同一个可 ...

  8. k8s删除节点

    k8s 删除节点 线上环境 # ctl get nodes NAME STATUS ROLES AGE VERSION 10.0.0.123 Ready <none> 104d v1.20 ...

  9. K8s多节点部署+负载均衡+keepalived ——囊萤映雪

    K8s多节点部署+负载均衡+keepalived --囊萤映雪 1.多节点master2 部署 2.负载均衡部署+keepalived 1.多节点master2部署: #从master01节点上拷贝证 ...

随机推荐

  1. java初学复习

    作为学Java的小白,忽然想看一看自己学了些什么东西,话不多说,(这都是新手弄的总结)让我们看一看: 1.我们要先了解Java技术 Java SE:标准版java技术的基础和核心 Java EE:企业 ...

  2. php 安装教程

    php 安装教程 本文采用php7.0.1作为样例,进行安装. 系统环境: CentOS6.7. gcc 4.8.2 libzip 1.0.1 在安装之前,可以先更新CentOS系统. yum -y ...

  3. CSAPP实验——DataLab

    任务:按照要求补充13个函数,会限制你能使用的操作及数量 bitXor(x,y) 只使用 ~ 和 & 实现 ^ tmin() 返回最小补码 isTmax(x) 判断是否是补码最大值 allOd ...

  4. Oracle创建函数例子

    编写一个函数计算学生某一门课程在班级内的排名. 表结构如下: create or replace function fun_score_rank( p_in_stuid in number,--学号 ...

  5. STM32F103ZET6 PWM输出

    1.通用定时器的PWM功能 STM32F103ZET6有4个通用定时器,分别是TIM2.TIM3.TIM4.TIM5. 通用定时器由一个可编程预分频器驱动的16位自动装载计数器构成. 通用定时器的很多 ...

  6. 构建LNMP

                                                                             构建LNMP 案例1:部署LNMP环境 案例2:构建L ...

  7. ssh秘钥免交互批量分发脚本

    将以下内容保存为.sh文件后运行即可,需根据各自情况修改ip_up和ip_arr #!/bin/bash #脚本功能:ssh秘钥免交互批量分发 #制 作 人:罗钢 联系方式:278554547@qqc ...

  8. 使用ping命令探测系统

    什么是ping命令 ping命令是测试网络连接.信息发送和接收状况的实用型工具,是系统内置的探测性工具.它的原理是:每台网络上的主机都有唯一确定的IP地址,用户给目标IP发送一个数据报,对方就要返回一 ...

  9. 薅羊毛? 月入10万? | 这是自动化测试老司机的特长--Python自动化带你薅视频红包,一个都不放过!

    一.目标场景 如今短视频横行的时代,以某短视频为首的,背后依靠着强大的资金后盾,疯狂地对平台用户进行红包轰炸. ​ 与传统的红包不一样,视频红包包含位置的不确定性.大小不确定性.元素 ID 的不确定性 ...

  10. Jenkins构建项目后发送钉钉消息推送

    前言 钉钉是我们日常工作的沟通工具,在Jenkins构建持续集成项目配合钉钉机器人的功能,可以让我们在持续集成测试环节快速接收到测试结果的消息推送. 一:新建一个钉钉群,选择自定义机器人 二:添加机器 ...