使用 kubectl exec 执行指令

如果您在 Kubernetes 上运行软件,您会想要在某些时候去调试您所部署的软件的一些方面。对于习惯于使用虚拟机 (VMs) 的人来说能自然使用的一种简单的调试方法,就是连接到一个正在运行的 pod,然后进行解译:

kubectl exec -it podname -c containername -- bash

这通常行之有效,而且非常管用。然而,至少有两种 Kubernetes "最佳实践 "限制了 exec 的实用性:

  • 不以 root 用户身份运行。容器尽可能以最少的特权运行,甚至可能使用随机的用户标识符 (UID) 运行。
  • 最小化镜像。镜像尽可能小,你甚至可以将二进制文件写入到 distroless image。

当应用这些最佳实践时,使用 kubectl exec连接到您的容器要么不可行,要么进入到不适合进行调试的环境。

kubectl exec 指令不允许指定用户标志或能力以启动进程,而是会从目标容器的主指令中复制这些设置。

调试容器

在解决运行容器问题时,Kubernetes 提供了一种原生化调试策略,即使用 kubectl debug。调试指令会在运行中的 pod 中启动一个新的容器。这个新容器能够以不同的用户身份以及从您选择的任何镜像去运行。由于调试容器与目标容器位于同一个 pod 中运行(因此在同一个节点上),两者之间不需要绝对的隔离。调试容器可以与同一 pod 中运行的其他容器共享系统资源。

考虑去检查在 pod postpod 中的容器 postcont 里运行的 PostgreSQL 数据库的 CPU 使用情况。这个 pod 并不以 root 用户身份运行,并且 Postgres 镜像没有安装类似 top 或 htop 的工具,也就是说,kubectl exec 指令几乎没有作用。您可以按照以下的指令去运行:

kubectl debug -it \
--container=debug-container \
--image=alpine \
--target=postcont \
postpod

您将以 root 身份登录(这是 Alpine 镜像的默认设置),并可以轻松安装您最喜欢的交互式进程查看器 htop (apt add htop)。您与 postcont 容器共享同一个进程命名空间,可以查看并甚至终止在此运行的所有进程!当您退出进程时,临时容器也会终止。

如果希望调试容器与 postcont 共享相同的进程命名空间,即使 postcont 是在 postpod 中运行的唯一容器,指定 --target 是不具备选择性的 (non-optional)。

 

您可以按 CTRL+P CTRL+D 断开与临时容器/bash 会话 (session) 的连接,而无需退出 (终止) 它。再使用 kubectl attach 即可重新连接。

 

kubectl debug 提供的功能比这里概述的更多,比如使用一个修改后的启动指令复制 pods,或通过访问节点文件系统的启动一个 "节点 (node) " pod。

原理解释

以上的 kubectl debug 指令是通过创建临时容器 (ephemeral container) 来实现。这些容器应在现有 pod 中临时运行,以支持故障排除等操作。“普通”容器和临时容器之间的区别很小。而查看 Kubernetes 在创立之初所做的基础架构选择最能让我们理解使用临时容器的原因:

Pod 应该是一次性的、可替换的,并且 Pod 规范也是不可改变的。

当 Kubernetes 主要用于部署无状态工作负载时,这一点更加合理——因为此时 pod 本身会被认为是临时的。在这个 Kubernetes 中它可能会受到限制。Pod 规范保持不变,但 Kubernetes 会将临时容器作为 Pod 的子资源建模。与“普通”容器不同,临时容器不属于 Pod 规范的一部分

挂载卷 (volumes)

内置指令 kubectl debug 非常有用。它允许您在运行的 pod 中添加一个临时容器,并可选择与运行中的容器共享进程命名空间。不过,如果您希望使用 kubectl debug 来检查或修改运行中容器文件系统的某个部分,那就不走运了——因为调试 pod 的文件系统与您将其连接到的容器的文件系统是分离的。幸运的是,我们可以做的更好。原理很简单:

  • 读取正在运行的目标容器的规范。
  • 将一个临时容器填充到 pod 中。将其配置成与目标容器共享相同的进程命名空间,并包含相同的卷挂载。

因为没有用于创建临时容器的 kubectl 命令,所以我们需要构建一个 PATCH 请求到 K8s API 来创建它。kubectl proxy 指令允许访问 K8s API。这一过程对用户来说并不太友好,因此将这一过程封装到脚本或 kubectl 插件中是合理的。您可以在这里找到这样一个脚本实现示例:

https://github.com/JonMerlevede/kubectl-superdebug?source=post_page-----2ba160c47ef5------

需要注意的是,这种方法和脚本可以很容易地扩展到从目标容器中复制环境变量的规范。如果您将此脚本保存为 kubectl-superdebug,并将其放在您的路径上,就可以在任何地方以 kubectl superdebug 的形式运行,如下所示:

还可以尝试扩展此脚本,将目标容器的其他方面复制到调试容器中,例如环境变量引用。

至此,Kubernetes 本机调试运行中的容器的方法概述就完成了,应该能满足大多数人的需求。

非 Kubernetes 原生方法

Kubernetes 不提供以 root 身份连接到正在运行的容器的方法(除非主进程以 root 身份运行),也不提供从另一个容器访问容器根文件系统的方法。但这并不意味着这些事情不可能做到。毕竟, Kubernetes 只是一个位于容器化引擎之上的容器编排器。如果出于某种原因,确实有必要的话,您通常可以通过移除抽象层来做任何您想做的事。

如果您使用的是 Docker 引擎,并且可以直接从节点或通过节点上运行的特权容器访问您的引擎,那么您就可以运行 docker exec --user,并以您选择的用户身份执行一个进程。

kubectl sshkubectl exec-user 等插件实现了这种方法。但遗憾的是,containerd 和 CRI-O 等现代引擎不再提供 --user 这样标志功能,这意味着这些插件无法在当下的 Kubernetes 安装上运行。

不过,即使是这些现代引擎,通常也只是与 Linux 命名空间接口。通过输入相应的 Linux 命名空间集,您可以在任何您想要的“容器”中运行指令。kpexec 工具实现了这种方法。它在与目标容器相同的节点上启动一个有权限的 pod,然后确定要针对哪些 (Linux) 命名空间,在这些 (Linux) 命名 空间中执行命令,最后将其输出流式传输到您的终端。作为额外的收获,它还能在目标容器的文 件系统之上叠加一套用于调试的工具。

与 kubectl exec 不同,kpexec 可以使用不同的 uid/gid 运行指令,甚至可以使用与容器主进程不同的功能。它与 containerd 和 cri-o 兼容。只是 kpexec 采用的方法有些笨重和脆弱,可能与集群的安全配置不兼容。但如果 kubectl (super) 调试无法满足您的需求,则值得考虑它。

需要注意,kpexec 使用 nsenter 是直接在命名空间中执行指令的。它与无处不在的容器运行时 runc 兼容,但与 Kata Containers 等运行时不兼容。

借助 Appilot 对话式诊断 K8s

Appilot 是一款面向 DevOps 场景的开源 AI 助手,它可以充分利用 AI 大语言模型的能力让用户直接输入自然语言进一步简化应用部署与管理体验。用户可以根据自身的需求和使用习惯,将 Appilot 集成到任意平台,进而实现通过输入自然语言即可调用后端平台的能力,轻松完成 Kubernetes debug 工作。

 

Appilot 项目地址 https://github.com/seal-io/appilot

K8s容器debug高级技巧的更多相关文章

  1. 微服务与K8S容器云平台架构

    微服务与K8S容器云平台架构 微服务与12要素 网络 日志收集 服务网关 服务注册 服务治理- java agent 监控 今天先到这儿,希望对技术领导力, 企业管理,系统架构设计与评估,团队管理, ...

  2. K8s容器编排

    K8s容器编排 Kubernetes(k8s)具有完备的集群管理能力: 包括多层次的安全防护和准入机制 多租户应用支撑能力 透明的服务注册和服务发现机制 内建智能负载均衡器 强大的故障发现和自我修复能 ...

  3. @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本

    今天遇到了很奇葩的问题,我本机的是以test环境启动的,调用另一个服务接口的时候返回参数却不同,调用接口是没错,怎么会这样,排查了很久,发现在eureka上注册的另一个服务是testone环境,而这个 ...

  4. k8s容器拷贝文件到本地、本地文件拷贝到k8s容器

    k8s容器拷贝文件到本地 kubectl cp qzcsbj/order-b477c8947-tr8rz:/tmp/jstack.txt /root/test/jstack.txt 本地文件拷贝到k8 ...

  5. Kubernetes_手把手打镜像并运行到k8s容器上(亲测可用)

    一.前言 本文使用两个机器 192.168.100.150 是master节点,192.168.100.151 是node1 节点,如下: 演示三个示例,第一个示例wordpress博客系统是指将别人 ...

  6. 【运维】通过gotty实现网页代理访问服务器及K8S容器操作实践

    Gotty 是Golang编写的可以方便的共享系统终端为web应用,是一个灵活强大的通过web访问终端的工具.本文将主要通过搭建Gotty实现对K8S容器的访问操作,开发如果想要正常的进行容器访问以及 ...

  7. Rancher 快速构建k8s容器管理平台解决方案(图片见原文链接)

    转载自Rancher 快速构建k8s容器管理平台解决方案_IT干货的博客-CSDN博客_k8s容器管理平台 一.Rancher 概述 Rancher 是企业级多集群Kubernetes管理平台,一个为 ...

  8. k8s容器互联-flannel host-gw原理篇

    k8s容器互联-flannel host-gw原理篇 容器系列文章 容器系列视频 简析host-gw 前面分析了flannel vxlan模式进行容器跨主机通信的原理,但是vxlan模式需要对数据包进 ...

  9. Kubernetes(k8s)容器运行时(CRI)

    Kubernetes节点的底层由一个叫做"容器运行时"的软件进行支撑,它负责比如启停容器这样的事情.最广为人知的容器运行时当属Docker,但它不是唯一的.事实上,容器运行时这个领 ...

  10. k8s容器的资源限制

    1.k8s支持内存和cpu的限制 requests:容器运行需求,最低保障limits:限制,硬限制(资源上限) CPU: 1颗逻辑CPU(1核CPU=4个逻辑CPU) 1物理核=1000个微核(mi ...

随机推荐

  1. CVE-2023-2825-GitLab目录穿越poc

    Gitlab CVE-2023-2825 目录穿越漏洞 前言 昨天 GitLab 出了一个版本目录穿越漏洞(CVE-2023-2825),可以任意读取文件.当时我进行了黑盒测试并复现了该漏洞. &qu ...

  2. 部署属于自己的New bing Ai

    该项目来源 https://github.com/adams549659584/go-proxy-bingai 项目体验地址 https://bing.vcanbb.top/web/#/ 项目介绍 基 ...

  3. 9k+ Star 简洁好用的开源 Linux 运维管理面板

    如果你的公司需要进行服务器运维管理,那么运维管理面板就是一个不可或缺的需求.因为并非每一位运维工程师都能在命令行下游刃有余,不需要借助辅助工具就能确保服务器安全.流畅运行.尤其是对于刚刚踏入运维领域的 ...

  4. Socket.io入门

    Socket.io入门 根据官方文档socket.io使用必须客户端根服务端一致,socket.io不兼容webSocket或者其他模块,因为socket.io在连接时做了自定义处理, 所以不同的长连 ...

  5. Jquery 将 JSON 列表的 某个属性值,添加到数组中,并判断一个值,在不在数据中

    jquery 将 JSON 列表的 某个属性值,添加到数组中 如果你有一个JSON列表,并且想要将每个对象的某个属性值添加到数组中,你可以使用jQuery的$.each()函数来遍历JSON列表,并获 ...

  6. tree-test

    #include <iostream> #include <stack> using namespace std; typedef struct BiTNode{ char d ...

  7. 「tricks」平凡二分幻术

    其实这个的标题叫 平凡线段树上二分幻术,因为这是一个民科在乱叫. 如标题所言,这个东西确实非常 trivial.碍于网络上没有一个成体系的文章供参考就只能自己来炒炒冷饭. 如果出了什么 bug 就当个 ...

  8. 算法打卡|Day2 数组part02

    Day2 数组part02 今日任务:977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II 目录 Day2 数组part02 今日任务:977.有序数组的平方 ,209.长度最小的 ...

  9. xftp 7必须更新最新版本怎么解决

    下载可以查看16进制的软件: Sublime Text 运行XFTP7 双击打开是:这样的 解决方案 用Sublime Text进行打开nslicense.dll, 打开之后查找"0f88 ...

  10. Shell 文件或目录操作符(-e、-d、-f、-r、-w、-x)

    操作符 操作符 含义-e 判断对象是否存在(Exist),若存在则结果为真-d 判断对象是否为目录(Directory),是则为真-f 判断对象是否为一般文件(File),是则为真-r 判断对象是否有 ...