原理
User Namespaces允许容器内的UID/GID和宿主机上的UID/GID做映射。
在没有User Namespace的情况下,容器内UID 0(root)映射到宿主机上的UID 0(也是root)。有了User Namespace,可以映射到宿主机上的一个非特权UID范围(如100000-101536)。
这样即容器被攻破,攻击者在宿主机上的权限也非常有限。
启用条件
- Kubernetes >= 1.25(Alpha,需开启Feature Gate)
- Kubernetes >= 1.27(Beta)
- Kubernetes >= 1.36(GA,生产可用)
- 内核支持userns(>= 4.14)
Pod配置示例
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
containers:
- name: app
image: nginx:1.36
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
验证方法
# 检查节点是否支持User Namespace
kubectl get nodes -o jsonpath='{.items[*].status.capabilities[*]}'
# 查看容器内进程的实际UID
kubectl exec -it secure-pod -- cat /proc/self/status | grep Uid
# 输出:Uid: 100000 100000 100000 100000
# 表示容器内看到的1000,实际映射到宿主机上的100000
# 在宿主机上验证映射
cat /proc/<container_pid>/uid_map
适用场景
✅ 多租户共享集群(安全隔离)
✅ 运行不可信第三方容器
✅ 对容器逃逸有严格合规要求的场景
局限性
❌ 需要内核4.14+支持userns
❌ 与某些HostPath挂载不兼容
❌ 不能完全替代seccomp/AppArmor(应配合使用)