ns的克星-nsenter

容器技术的基础之一就是隔离,nsenter可以从ns1进入ns2操作,就像是直接在ns2操作资源一样。 类似的,在pod容器中可以操作host上的资源,命令。

以下面pod做测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# cat dp.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubectl
spec:
selector:
matchLabels:
app: kubectl
replicas: 1
template:
metadata:
labels:
app: kubectl
spec:
hostPID: true // 避免pid隔离,容器可以看到host的进程号
nodeSelector:
kubernetes.io/hostname: master1
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
containers:
- image: nginx
name: nginx
command: ["/bin/sh", "-c", "while true;do sleep 1s;done"]
securityContext:
privileged: true

对于yaml中配置的解释:

  1. hostPID:true。 跟hostnetwork类似,共享host的pid空间,让容器看到host的1号进程
  2. command: 该命令可以覆盖镜像中的entrypoint和cmd,放心使用
  3. [“/bin/sh”, "-c"]的原因是command默认是以可执行程序方式运行,类似a.out方式,即查看当前目录及PATH下是否有该文件,有的话就直接加载到内存执行,对于有些shell命令依赖shell的环境变量,shell命令前增加“/bin/sh”表示将/bin/sh当作可执行程序加载到内存执行,即打开了一个shell; ‘-c’表示要执行的是一个命令字符串,即一个命令整体。如果不加-c, 则是开启了shell, 且以交互的方式输入命令,按回车键后执行命令。

仅验证mount ns

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# kubectl exec -it kubectl-7bff6c4cf8-c9dgx sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

/ # nsenter --mount=/proc/1/ns/mnt mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,size=7786688k,nr_inodes=121667,mode=755)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)


/ # mount
overlay on / type overlay (rw,relatime,lowerdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/27664/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/26330/fs,upperdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/27942/fs,workdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/27942/work)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuse

在容器中mount只能看到容器里的挂载点, 通过nsenter进入host上1号进程挂载点,可以在容器中看到host上的挂在点。

通过nsenter可以实现在容器中查看host上的资源。容器种敲命令像在host上敲一样。