如何通过 kubectl 进入 node shell

如何,通过,kubectl,进入,node,shell · 浏览次数 : 186

小编点评

## 总结 该场景下,通过 kubectl 登录到 K8S 集群里的 Node,可以实现以下方法: 1. 创建一个特权容器,通过 nsenter 命令进入 node shell。 2. 进入 node shell后,使用 kubectl 命令进行安全操作。 3. 使用 krew 或 Lens 等工具轻松地进入 node shell。 **本质上,通过容器的弱隔离实现的权限逃逸。** **注意:** 1. 此方法需要在使用之前创建特权容器。 2. 进入 node shell的权限要受到限制,例如使用 `SecurityContext` 的 `privileged` 属性设置为 `true`。 3. 在使用该方法时,请注意安全问题,例如使用 `PodSecurityPolicy` 等规则对容器进行限制。

正文

概述

假设这样一个场景:

生产环境中,Node 都需要通过堡垒机登录,但是 kubectl 是可以直接在个人电脑上登录的。

这种场景下,我想要通过 kubectl 登录到 K8S 集群里的 Node,可以实现吗?

可以的!
本质上是利用容器(runC)的弱隔离(共享内核,Cgruop 等实现进程隔离)实现的权限逃逸。

如果贵司使用的一些商业容器平台(如:openshift,rancher)等,可能默认安装时就会通过 PSP scc 或 policy 等预先屏蔽掉这层隐患。
但是如果是原生的 Kubernetes, 往往下面的办法是可行的。

原理概述

先说本质,本质上就是:

容器(runC)是弱隔离

  • 对于虚拟机来说,虚拟机是通过内核(kernel)级别的隔离,不同的虚拟机有不同的内核,所以安全性要高很多,从虚拟机逃逸到其所在的物理机上是非常困难的。
  • 但是,容器(runC)是弱隔离,一台机器上的所有容器都共享同一个内核,他们之所以默认互相看不见,是通过 Cgroup、net namespace 等实现的进程级别的隔离。

那么,加入你没有对容器的权限做进一步的限制,我是可以通过运行一个特权容器,直接进入到其所在的 node 上的。

具体步骤

适用于 K8S 1.25 之前的版本。

步骤很简单,就是创建上文说的这么一个特权容器,通过 nsenter command 进入 node shell。示例 yaml 如下:

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nsenter-v0l86q
  name: nsenter-v0l86q
  namespace: default
spec:
  containers:
  - command:
    - nsenter
    - --target
    - "1"
    - --mount
    - --uts
    - --ipc
    - --net
    - --pid
    - --
    - bash
    - -l
    image: docker.io/library/alpine
    imagePullPolicy: Always
    name: nsenter
    securityContext:
      privileged: true
    stdin: true
    stdinOnce: true
    tty: true
  hostNetwork: true
  hostPID: true
  restartPolicy: Never
  tolerations:
  - key: CriticalAddonsOnly
    operator: Exists
  - effect: NoExecute
    operator: Exists

直接 kubectl apply -f node-shell.yaml 即可进入 node shell。

上面的 yaml,关键有这么几点:

进入 node shell 的命令:nsenter --target 1 --mount --uts --ipc --net --pid -- bash -l,在 Linux 系统里, nsenter 是一个命令行工具,用于进入到另一个 namespace 。 譬如, nsenter -n -t 1 bash 就是进入到 pid 为 1 的进程所在的网络 namespace 里。

以及进入 node shell 的权限:

  • hostPID: true 共享 host 的 pid
  • hostNetwork: true 共享 host 的网络
  • privileged: true: PSP 权限策略是 privileged, 即完全无限制。

进入 node shell 的 pod 后, 效果如下:

node shell-可以切换 shell

node shell-可以查看所有的进程信息

node shell-可以执行 root 权限的 systemctl

实用工具 - 进入 node shell 更方便

这里推荐 2 个工具,可以更方便地进入 node shell。

krew node-shell

可以通过 kubectl 插件管理工具 krew 安装 node-shell.

如下:

# 安装工具
kubectl krew install node-shell
# 进入 node shell
Kubectl node-shell <node-name>

Lens

Kubernetes 图形化管理工具 - Lens 也有相关功能。

具体使用方法如下:

Lens-选择指定 node 进入 shell

Lens-实际上也是启动个特权 pod,可以执行 root 命令

总结

上文介绍了通过 kubectl 命令以 root 权限进入 node shell 的方法,非常简单,实际上在大多数的原生 Kubernetes 上都生效。

这个命令实际上是一定程度上利用了安全上的未加固配置。

这里最后还是建议大家除了对 OS 进行安全加固,对 Kubernetes 也要按照安全最佳实践进行安全加固。(典型的就是起码 PSP 等 policy 不要设置为 privileged, 而是设置为 BaselineRestricted

注意安全!🚧🚧🚧

EOF

本文由博客一文多发平台 OpenWrite 发布!

与如何通过 kubectl 进入 node shell相似的内容:

如何通过 kubectl 进入 node shell

概述 假设这样一个场景: 生产环境中,Node 都需要通过堡垒机登录,但是 kubectl 是可以直接在个人电脑上登录的。 这种场景下,我想要通过 kubectl 登录到 K8S 集群里的 Node,可以实现吗? 可以的! 本质上是利用容器(runC)的弱隔离(共享内核,Cgruop 等实现进程隔离

【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)

问题描述 使用Azure Kubernetes服务(AKS),可以通过kubectl连接 pod 中查看日志,但是如何来查看节点的系统日志呢?如是否有ubuntu系统升级的记录? 问题解答 是的,可以进入AKS的节点查看系统文件,如日志文件(/var/log) 或者由应用生产的其他日志。 具体的操作

使用metrics-server监控k8s的资源指标

首先,欢迎使用DHorse部署k8s应用。 k8s可以通过top命令来查询pod和node的资源使用情况,如果直接运行该命令,如下所示。 [root@centos05 deployment]# kubectl top pod W0306 15:23:24.990550 8247 top_pod.go

js需要同时发起百条接口请求怎么办?--通过Promise实现分批处理接口请求

如何通过 Promise 实现百条接口请求? 实际项目中遇到需要发起上百条Promise接口请求怎么办? 前言 不知你项目中有没有遇到过这样的情况,反正我的实际工作项目中真的遇到了这种玩意,一个接口获取一份列表,列表中的每一项都有一个属性需要通过另一个请求来逐一赋值,然后就有了这份封装 真的是很多功

如何提升百度小程序的收录?百度小程序如何做优化?

如何通过百度小程序获得更多的自然流量?这是做百度小程序肯定要考虑的问题,做百度小程序的目的就是想借助百度生态,做相应的关键词给自己的小程序引流

如何通过前后端交互的方式制作Excel报表

前言 Excel拥有在办公领域最广泛的受众群体,以其强大的数据处理和可视化功能,成了无可替代的工具。它不仅可以呈现数据清晰明了,还能进行数据分析、图表制作和数据透视等操作,为用户提供了全面的数据展示和分析能力。 今天小编就为大家介绍一下,如何通过葡萄城公司的纯前端表格控件SpreadJS和后端表格组

[转帖]如何通过shell脚本对一个文件中的所有数值相加并求和

https://developer.aliyun.com/article/886170?spm=a2c6h.24874632.expert-profile.255.7c46cfe9h5DxWK 1.背景 在一些巡检脚本中有时通常需要把一个文件中的数值进行相加得出综合,由于是文件中的所有数值,因此不能

[转帖]如何通过JMeter测试金仓数据库KingbaseES并搭建环境

1.安装JMeter Apache JMeter是Apache组织开发的基于Java的压力测试工具,主要用于对软件的压力测试,它最初被设计用于Web应用测试,但后来扩展到其它测试领域。它可测试静态、动态资源,如静态文件、Java小服务程序、CGI脚本、Java对象、数据库等等。JMeter可以用于对

[转帖]如何通过dba_hist_active_sess_history分析数据库历史性能问题

https://www.cnblogs.com/DataArt/p/10018932.html 在数据库运行的过程中,我们有时会碰到数据库hung住的问题,在这个时候很多人会选择尽快让它恢复正常而不是找出问题的root cause. 只有在问题被解决后,才意识到需要找到root cause来避免再次

如何通过jstat命令进行查看堆内存使用情况?

摘要:jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。 本文分享自华为云社区《JVM之通过jstat命令进行查看堆内存使用情况》,作者:共饮一杯无 。 基本概念 jstat是JDK自带的一个轻量级小工具。它位于java的bin目录下,主要利用JVM内建的指令对Java应用程序的资源和性