配置节点的安全上下文
除了让 pod 使用宿主节点的 Linux 命名空间,还可以在 pod 或其所属容器的描述中通过 security Context 边项配置其他与安全性相关的特性。这个选项可以运用于整个 pod ,或者每个 pod 中单独的容器。
了解安全上下文中可以配置的内容,配置安全上下文可以允许你做很多事
- 指定容器中运行进程的用户(用户ID )。
- 阻止容器使用 root 户运行(容器的默认运行用户通常在其镜像中指定,所以可能需要阻止容器 root 用户运行
- 使用特权模式运行容器,使其对宿主节点的内核具有完全的访问权限
- 与以上相反,通过添加或禁用内核功能,配置细粒度的内核访问权限。
- 设 SELinux C Security aced Linux 安全增强型 Linux )边项,加强对容器的限制。
- 阻止进程写入容器的根文件系统
以下内容将开始探索这些边项的细节
运行 pod 而不配置安全上下文
首先,运行
个没有任何安全上下文配置的
pod
(不指定任何安全上下文选项),与配置了安全上下文的
pod
形成对照:
$ kuhectl run pod-with-defaults --image alpine --restart Never -- /bin/sleep 999999
pod "pod-with defaults” created
来看一看这个容器中的用户
ID
和组
ID
,以及它所属的用户组
这可以通过在容器中运行 id
命令查看
$ kuhectl exec pod-with-defaults id
uid;Q(root) gid;Q(root) groups;Q(root), l(b n), 2 (daemon), 3 (sys) , 4 (adrn) ,
6 (disk ),工 (wheel), 11 (floppy), 20 (dialout), 26 (tape), 27 (v deo)
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-drb2s 1/1 Running 3 263d
[root@k8s-master ~]# kubectl exec -it nginx-6799fc88d8-drb2s bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-6799fc88d8-drb2s:/# id
uid=0(root) gid=0(root) groups=0(root)
root@nginx-6799fc88d8-drb2s:/#
这个容器在用户
ID
(uid
)为
的用
户,即
root
,用户组
ID
(gid
)为
(同
样是 root
)的用户组下运行
它同样还属于
一些其
他的用户组。
注意 : 容器运行时使用的用户在镜像中指定 Dockerfile 中,这是通过使用USER 命令实现的,如果该命令被省略,容器将使用 root用户运行。
现在来运行个使用特定用
户运行容器的
pod。
使用指定用户运行容器
为了使用
个与
镜像中不同的用户
ID
来运行pod
需要
设置该
pod securityContext.runAsUser 选项
可以通过以下代码
清单来运行一
个使用 guest 用户运行的容器,该用户在 a
lpine
镜像中的用户 ID
405
[root@k8s-master ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-as-user-guest
spec:
containers:
- name: main
image: alpine
command: ["/bin/sleep","99999"]
securityContext:
runAsUser: 405
注意:你需要指定用户ID,而不是用户名,id 405 guest 用户
现在可以像之前 样在 pod 中运行 id 命令, 查看 runAsUser 选项的效果:
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-as-user-guest 1/1 Running 0 63s
[root@k8s-master ~]# kubectl exec -it pod-as-user-guest sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ $ id
uid=405(guest) gid=100(users)
与要求的样,该容器在 guest 用户下运行。
阻止容器以 root 用户运行
如果你不关心容器是哪个用户运行的,只是希望阻止以 root 用户运行呢?
假设有一个己经部署好的
pod
,它使用
在
Dock
file
使用
USER
daemon命令制作的镜像,使其在
daemon
用户下运行,
如果攻击者获取了访问镜像仓库的权限,并上传了
个标签完全相同,在
root 用户下运行的镜像,会发生什么?
当 Kubernetes 的调度器运行该 pod 新实例时, kubelet 会下载攻击者的镜像,并运行该镜像中的任何代码。
虽然容器与宿主节点基本上是隔离的,使用
root
用户运行容器中的进程仍然是一种不好的实践,
例如,当宿主节点上的
个目录被挂载到容器中时,如果这个容器中的进程使用了 root
用户运行,
它就拥有该目录的完整访问权限,如果用非 root用户运行,则没有完整权限。
为了防止以上的攻击场景发生,可以进行配置,使得 pod 中的容器以非 root户运行,
如以下的代码清单所示:(
阻止容器使用 root 用户运行
)
[root@k8s-master ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-as-user-guest
spec:
containers:
- name: main
image: alpine
command: ["/bin/sleep","99999"]
securityContext:
runAsNonRoot: true
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-as-user-guest 0/1 CreateContainerConfigError 0 53s
Normal Pulling 8h (x5 over 8h) kubelet, k8s-node2 Pulling image "alpine"
Warning Failed 8h (x5 over 8h) kubelet, k8s-node2 Error: container has runAsNonRoot and image will run as root
现在,即使攻击者篡改了镜像,他们也无法做出进
步的破坏。