如何通过 kubectl 进入 node shell

简介: 如何通过 kubectl 进入 node shell

本文最后更新于:2023年5月6日 上午

概述

假设这样一个场景:

生产环境中,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
YAML

直接 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>
BASH

Lens

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

具体使用方法如下:

Lens- 选择指定 node 进入 shell

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

总结

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

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

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

注意安全!🚧🚧🚧

EOF

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
7月前
|
JavaScript 前端开发 Unix
Node.js Shell 脚本开发指南(中)
Node.js Shell 脚本开发指南(中)
132 0
|
7月前
|
JavaScript 前端开发 Shell
Node.js Shell 脚本开发指南(上)
Node.js Shell 脚本开发指南(上)
164 0
|
4月前
|
Kubernetes 容器
Kubernetes(K8S) 安装 Metrics-Server kubectl top (metrics-server) node NotFound
Kubernetes(K8S) 安装 Metrics-Server kubectl top (metrics-server) node NotFound
50 0
|
7月前
|
Kubernetes Shell Docker
容器服务ACK常见问题之容器服务ACK kubectl命令写到shell脚本失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
7月前
|
JavaScript 前端开发 Unix
Node.js Shell 脚本开发指南(下)
Node.js Shell 脚本开发指南(下)
139 0
kubectl 如何查看 node、pod 的 cpu、ram使用率
kubectl 如何查看 node、pod 的 cpu、ram使用率
1807 0
|
运维 JavaScript 前端开发
使用zx 库在 Node 中编写 Shell 脚本
在文章《2021 年 6 个GitHub推荐前端项目》中提到了脚本库 zx.js,一个可以使用 Node.js 编写 Shell 脚本的工具。在本文中,将介绍如何来使用 Google 的 zx 库编写 Shell 脚本。
352 0
使用zx 库在 Node 中编写 Shell 脚本
|
2月前
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
106 1
|
1月前
|
Shell Linux 测试技术
6种方法打造出色的Shell脚本
6种方法打造出色的Shell脚本
59 2
6种方法打造出色的Shell脚本