k8s pod 抢占后陷入失败/关闭状态 (gke v1.20)

2024-01-11

TL;DR - gke 1.20 可抢占节点导致 Pod 僵尸化并导致失败/关闭

我们已经使用 GKE 几年了,集群中包含稳定节点池和可抢占节点池。最近,自 gke v1.20 以来,我们开始看到抢占的 Pod 进入奇怪的僵尸状态,它们被描述为:

状态:失败

原因: 关机

消息:节点正在关闭,正在驱逐 Pod

当这种情况开始发生时,我们确信这与我们的 Pod 未能在抢占时正确处理 SIGTERM 有关。我们决定通过将服务软件简化为一个大部分处于睡眠状态的简单服务来消除其问题根源:

/* eslint-disable no-console */
let exitNow = false

process.on( 'SIGINT', () => {
  console.log( 'INT shutting down gracefully' )
  exitNow = true
} )

process.on( 'SIGTERM', () => {
  console.log( 'TERM shutting down gracefully' )
  exitNow = true
} )

const sleep = ( seconds ) => {
  return new Promise( ( resolve ) => {
    setTimeout( resolve, seconds * 1000 )
  } )
}

const Main = async ( cycles = 120, delaySec = 5 ) => {
  console.log( `Starting ${cycles}, ${delaySec} second cycles` )

  for ( let i = 1; i <= cycles && !exitNow; i++ ) {
    console.log( `---> ${i} of ${cycles}` )
    await sleep( delaySec ) // eslint-disable-line
  }

  console.log( '*** Cycle Complete - exiting' )
  process.exit( 0 )
}

Main()

此代码使用 tini init 构建到 docker 映像中,以生成在 nodejs 下运行的 pod 进程(fermium-alpine 映像)。无论我们如何调整信号处理,吊舱似乎永远不会真正完全关闭,即使日志表明它们是这样的。

另一个奇怪的地方是,根据 Kubernetes Pod 日志,我们看到 Pod 终止开始,然后被取消:

2021-08-06 17:00:08.000 EDT 停止容器 preempt-pod

2021-08-06 17:02:41.000 EDT 取消删除 Pod preempt-pod

我们还尝试添加 preStop 15 秒延迟,只是为了看看是否有任何效果,但我们尝试的任何操作似乎都不重要 - 豆荚变成了僵尸。新副本在池中可用的其他节点上启动,因此它始终保持系统上成功运行的 Pod 的最小数量。

我们还使用 sim 维护事件来测试抢占周期:

gcloud 计算实例模拟维护事件节点 ID


在浏览了各种帖子后,我最终决定每 9 分钟运行一次 cronjob,以避免 pod 处于关闭状态超过 10 分钟后触发 AlertManager。对我来说,这仍然感觉像是一种 hack,但它确实有效,并且它迫使我深入研究 k8s cronjob 和 RBAC。

这篇文章让我走上了这条道路:如何删除 Kubernetes“关闭”pod https://stackoverflow.com/questions/68344231/how-to-remove-kubernetes-shutdown-pods

以及由此产生的 cronjob 规范:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-accessor-role
  namespace: default
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "delete", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-access
  namespace: default
subjects:
- kind: ServiceAccount
  name: cronjob-sa
  namespace: default
roleRef:
  kind: Role
  name: pod-accessor-role
  apiGroup: ""
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cronjob-sa
  namespace: default
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: cron-zombie-killer
  namespace: default
spec:
  schedule: "*/9 * * * *"
  successfulJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        metadata:
          name: cron-zombie-killer
          namespace: default
        spec:
          serviceAccountName: cronjob-sa
          restartPolicy: Never
          containers:
          - name: cron-zombie-killer
            imagePullPolicy: IfNotPresent
            image: bitnami/kubectl
            command:
              - "/bin/sh"
            args:
              - "-c"
              - "kubectl get pods -n default --field-selector='status.phase==Failed' -o name | xargs kubectl delete -n default 2> /dev/null"
status: {}

请注意,将 stderr 重定向到 /dev/null 只是为了避免当 kubectl get 找不到任何处于失败状态的 pod 时 kubectl delete 的错误输出。

Update添加了角色中缺少的“删除”动词,并添加了缺少的 RoleBinding

Update添加了 imagePullPolicy

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

k8s pod 抢占后陷入失败/关闭状态 (gke v1.20) 的相关文章

  • 设置ejs在express中查看文件夹的查找路径

    I have app js in Express 服务器文件夹 aap js 的完整位置是I WEB Development Node Express server 我做了views该位置的文件夹I WEB Development Node
  • Mongoose 更新嵌入文档不起作用

    问候大家 我定义了一个深度嵌入的猫鼬模型 Person 其中包含一个字段 Contact Contact 有一个 Address 数组 用于这个人的工作 家庭 送货等地址 当我想要更新地址并使用模型的 保存 功能时 更改并未反映在数据库中
  • 将实时流音频从 NodeJS 服务器获取到客户端

    我需要从 1 个客户端到服务器到多个侦听器客户端的实时实时音频流 目前 我正在从客户端进行录音 并通过 socket io 将音频流式传输到服务器 服务器接收此数据 并且必须将音频流式传输 也通过 socket io 到想要收听此流的客户端
  • 当rest api应用程序服务器(express)和Angulars js应用程序在不同端口上运行时出现Cors问题

    我有用node js编写的rest api应用程序 express在端口3000上运行 而angularjs应用程序在同一服务器上的端口9001上运行 从 angularjs 应用程序调用 rst api 时 出现了 cors 问题 在re
  • 如何告诉node.js mysql没有在默认端口上运行?

    我遇到了与此人类似的问题 连接 ECONNREFUSED 节点 js sql https stackoverflow com questions 8825342 connect econnrefused node js sql 我正在尝试将
  • 如何使用 ejs post 表单更新 node.js 和 MongoDB 应用程序中的现有用户数据?

    我对 javascript 非常陌生 发现 Brad Traversy 的视频 Node js with Passport Authentication 并关注了他的视频 它对我有用 但后来我想添加更多 我创建了自定义仪表板和导航 我添加的
  • 如何在 Node.js 中获取 RSA 公钥的模数和指数

    我正在创建一个ACME https www rfc editor org rfc rfc8555客户端和我需要找到 RSA 公钥的模数和指数 我使用以下代码生成该公钥 crypto generateKeyPairSync rsa modul
  • 使用 Javascript 展平父子 JSON 数组

    我有一个如下所示的数组 const arr name x type type1 parent name a type type1 name y type type1 parent name b type type1 我想将其展平并最终得到如
  • 少吞咽然后缩小任务

    我必须在 gulp 中执行 2 个步骤 减少 css 文件格式 缩小生成的 css 文件 这是我的吞咽文件 var gulp require gulp watch require gulp watch less require gulp l
  • Node.js Google-云存储上传目的地规范

    我有一个 Node js 服务器并且正在使用谷歌云上传一些图像文件的包Firebase 存储 上传本身工作正常 但 google cloud API 似乎只能将文件上传到 Firebase Storage 根文件夹 有没有办法指定远程位置来
  • 我应该在 Kubernetes 前面添加 DMZ 吗?

    Kubernetes Ingress 是否足够安全 可以避免在 Kubernetes 前面添加 DMZ 来暴露 Pod 和服务 如果有人 黑进 Pod 会发生什么 Thanks 这是一个意见问题 所以我会用一个选项来回答 如果您遵循 这是非
  • 设置环境变量供节点检索

    我正在尝试遵循教程 它说 有几种加载凭据的方法 从环境变量加载 从磁盘上的 JSON 文件加载 键需要如下所示 USER ID USER KEY 这意味着如果您正确设置环境变量 您 根本不需要管理应用程序中的凭据 根据一些谷歌搜索 我似乎需
  • microk8s加入节点没有效果

    我确实命令 om 主节点 microk8s add node From the node you wish to join to this cluster run the following microk8s join 192 168 0
  • nslookup 无法在最新的 busybox 上获取服务 ip

    重现步骤 kubectl run busybox1 generator run pod v1 image busybox 1 28 sleep 3600 kubectl run busybox2 generator run pod v1 i
  • 从 Promise 块返回函数值

    我正在尝试编写一个函数 使用 WebdriverJS lib 来迭代元素列表 检查名称并构建与该名称对应的 xpath 定位器 我这里简化了xpath定位器 大家不用关注 我在这里面临的问题是 1 调用该函数返回未定义 据我了解 这是因为
  • Windows - 启动时自动启动特定应用程序

    在 Windows 操作系统中开发信息亭应用程序 当机器启动时 必须依次发生 3 件事 Node js 服务器启动 包含 Web 应用程序的浏览器以 kiosk 模式启动 另一个客户端应用程序启动 是否有一个实用程序可以轻松完成此操作 或者
  • 如何使用 chrome puppeteer 访问 ssl 证书内容

    我想使用 chrome puppeteer 访问 url 的证书详细信息 是否可以使用当前的 puppeteer API 来做到这一点 使用以下代码获取证书列表 结果无法直接读取 将每个条目存储在具有 pem 扩展名的文件中 BEGIN C
  • 如何在 Mongoose.js 查询中执行大于语法

    如何获得适用于此 Mongoose 查询的 大于 语法 var where where id req wine id where sameAs undefined where scoreTotal gt 0 THIS NEEDS TO SE
  • Node.js 中的 SetTimeout 问题

    我有以下代码 它在 Chrome V8 下运行良好 但在节点内失败 var id id setTimeout TimeoutHandler 10 console log SET function TimeoutHandler clearTi
  • 显示服务器端运行的长进程的状态

    我正在基于 Node js 的 Web 应用程序中进行 CSV 导入 大多数给定的 CSV 文件都有数万条记录 并且需要几分钟的时间 因此 在导入完成之前 我想向用户显示 当前正在导入 消息 我想要创建的内容类似于 Github 的分叉屏幕

随机推荐

  • Rails 在新控制器中结合 RESTful 方法

    我有一个 Rails 应用程序 其中users create projects 目前 这些是嵌套的 并作为单独的操作完成 Auser寄存器 然后从project仪表板创建一个新的project 为了提高转化率 以及跟踪来自 adwords
  • PySpark - 将单个整数列表与列表列进行比较

    我正在尝试检查 Spark 数据帧 带有列表的列 中的哪些条目包含给定列表中最大数量的值 我想出的最好的方法是迭代数据框rdd foreach 并使用 python 比较给定列表与每个条目set1 intersection set2 我的问
  • ??空合并运算符 --> 合并是什么意思?

    我很想撒谎说英语是我的第二语言 但事实是我只是不知道 合并 是什么意思 我知道什么 在 C 中是 does 但这个名字对我来说没有意义 我查了一下这个词 我知道它是 加入 的同义词 空连接运算符 仍然没有意义 有人可以启发我吗 我很想撒谎说
  • 如何使用UIAppearance外观WhenContainedIn:

    我注意到在 iOS5 中我们可以通过以下方式自定义 UIKit 控件UIAppearance我开始使用它 我想用appearanceWhenContainedIn 定制UINavigationBar s tintColor在不同的班级 例如
  • 使用 puppeteer 和 MutationObserver 检测 DOM 更改

    我想检测某些加载页面上的 DOM 更改 例如 本地新闻页面上添加的新文章 并在检测后执行某些操作 发送电子邮件 在此示例中 我尝试检测子节点是否已从父节点 目标 div 节点 添加或删除 并在检测后在控制台中输出某些内容 我需要实现暴露功能
  • 在python中读取大csv文件的行

    我有一个非常大的 csv 文件 无法完全加载到内存中 所以我想一块一块地读取它 将其转换为numpy数组 然后再做一些处理 我已经检查过了 在Python中读取大文件的惰性方法 https stackoverflow com questio
  • 如何在谷歌应用程序引擎(Python)中使用numpy

    根据官方文档 numpy 作为谷歌应用程序引擎中的库支持here https developers google com appengine docs python tools libraries27 经过几次尝试后我无法导入它 有人可以分
  • 如何使用 Matplotlib 在对数刻度上显示次要刻度标签

    有谁知道如何使用 Python Matplotlib 以对数刻度显示次要刻度的标签 您可以使用plt tick params axis y which minor 设置小刻度并使用matplotlib ticker FormatStrFor
  • JSON 服务在失败/错误时应返回什么

    我正在用 C ashx 文件 编写 JSON 服务 成功请求服务后 我会返回一些 JSON 数据 如果请求失败 要么是因为抛出了异常 例如数据库超时 要么是因为请求在某种程度上是错误的 例如作为参数给出了数据库中不存在的 ID 服务应该如何
  • 将 Swagger Java 对象转换为 JSON/YAML

    我需要阅读 修改并重新生成 JSON YAML swagger 文件文档 我已经使用 Swagger Parser 反序列化了一个 JSON 文件 并且有一个 Swagger Java 对象 其中原始 JSON 数据已正确映射 现在 我需要
  • Dynamics CRM 视图中的串联/计算列

    我是 MS Dynamics 的新手 我想知道是否有一种方法可以将列添加到视图中 该视图是其他一些列的串联 例如 Firstname Lastname As Fullname 似乎没有一个明显的 优雅的 解决方案 我看到的所有建议都建议使用
  • 如何替换默认的 SortArgumentResolver

    我需要添加private static final Sort sortById new Sort Sort Direction DESC ID 每一个Pageable 我想 最好的方法是创建装饰器 适配器SortArgumentResolv
  • sqrt(float) 有标准返回类型吗?

    我注意到 appleclang v14 0 0 在将浮点输入传递给时似乎返回单精度浮点cmath s sqrt 当切换到 gcc clang 时 我很惊讶地得到了不同的结果 这是我的最小可重现示例 include
  • Hibernate 与连接表的一对多关系,并在连接表中添加列

    我正在寻找一种在两个表之间建立 OneToMany 关系并在连接表中具有额外属性的方法 但我找不到太多有用的示例 抱歉 如果这听起来很蹩脚 但有人能给我建议一个好方法吗 如果连接表中有其他列 则它不再是连接表 并且您需要一种方法来获取和设置
  • 将对象数组及其属性转换为数组

    我尝试了几种地图功能 但找不到合适的方法来获得我想要的东西 案例如下 Object Results Array 3 Results Array 3 0 2 0 Object id null name Rick upper 0 67 1 Ob
  • 为什么关闭窗口时没有触发componentWillUnmount?

    有人会认为componentWillUnmount https reactjs org docs react component html componentwillunmountin React 会在关闭应用程序时触发 根据文档 comp
  • Firebase、Swift:返回类型上的可空性说明符冲突,“nullable”与现有说明符“nonnull”冲突

    警告已进入火力地堡 3 6 0 Xcode 8 斯威夫特 3 这些是 Firebase 类 class FIROptions class FIRAuthCredential class FIRUserProfileChangeRequest
  • 取消鼠标投影以获得 3D 世界坐标 Libgdx

    我的问题 如何让 3D 模型随着鼠标光标移动 并将模型的 y 位置保持在 0 使用 Libgdx 我尝试过的 我正在尝试让 3D 模型跟随我的光标 目前 我只是让模型随着鼠标的 x 和 y 坐标移动 并添加乘数和相机位置等因素 这不是很好
  • HTML5 电话号码验证与模式

    我正在使用 HTML5 表单验证来验证来自印度的电话号码 印度的电话号码长度为 10 位 以 7 8 或 9 开头 例如 7878787878 9898989898 8678678878 这些电话号码有效 但是 1212121212 343
  • k8s pod 抢占后陷入失败/关闭状态 (gke v1.20)

    TL DR gke 1 20 可抢占节点导致 Pod 僵尸化并导致失败 关闭 我们已经使用 GKE 几年了 集群中包含稳定节点池和可抢占节点池 最近 自 gke v1 20 以来 我们开始看到抢占的 Pod 进入奇怪的僵尸状态 它们被描述为