前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker 和 Kubernetes 中的 root 与 privileged

Docker 和 Kubernetes 中的 root 与 privileged

作者头像
我是阳明
发布2020-11-20 09:51:38
4.9K0
发布2020-11-20 09:51:38
举报
文章被收录于专栏:k8s技术圈

我们大多数熟悉 Unix 类系统的人,都习惯于通过使用 sudo 来随意提升自己的权限,成为 root 用户。我们在使用 Docker 容器的过程中知道,他提供了一个 --privileged 的参数,其实它与随意使用 sudo 有很大的不同,它可能会让你的应用程序面临不必要的风险,下面我们将向你展示这与以 root 身份运行的区别,以及特权的实际含义。

作为 Root 运行

Docker 允许在其宿主机上隔离一个进程、capabilities 和文件系统,但是大多数容器实际上都是默认以 root 身份运行。这里我们拿 DockerHub 上几个比较流行的镜像来进行说明。

Postgres:

代码语言:javascript
复制
$ docker run -it postgres
# whoami
root
# id -u
0

Couchbase:

代码语言:javascript
复制
$ docker run -it couchbase sh
# whoami
root
# id -u
0

Alpine:

代码语言:javascript
复制
$ docker run -it alpine sh
# whoami
root
# id -u
0

我们可以看到这几个镜像默认都是以 root 身份运行,这样当然更容易调试,特别是当你要 exec 到容器中时,但最好的情况还是应该避免以 root 身份运行。

避免以 root 运行

虽然在容器内以 root 身份运行是很正常的,但如果你想加固你的容器,还是应该避免这样做。首先,,其次,容器将成为运行 Docker 命令的同一用户命名空间的一部分,如果容器能够逃逸,它将可以访问相同的资源,比如 volumes 和 sockets。

这里我们有两种方法可以避免以 root 身份运行。

  • 通过在 Dockerfile 文件中指定 user 用户:
代码语言:javascript
复制
// DockerfileFROM microsoft/windowsservercore
# Create Windows user in the container
RUN net user /add patrick
# Set it for subsequent commands
USER patrick
  • 运行容器的时候覆盖用户 ID:
代码语言:javascript
复制
$ docker run -it --user 4000 postgres sh
# whoami
whoami: cannot find name for user ID 4000
# id -u
4000

特权模式

--privileged 标志可以将我们前面看到的0的用户 ID 直接映射到主机的用户 ID 0上,使其可以不受限制地访问任何自己的系统调用。在正常的操作中,即使容器内有 root,Docker 也会限制容器的 Linux Capabilities 的,这种限制包括像 CAP_AUDIT_WRITE 这样的东西,它允许覆盖内核的审计日志--你的容器化工作负载很可能不需要这个 Capabilities。所以特权只应该在你真正需要它的特定设置中使用,简而言之,它给容器提供了几乎所有主机(作为root)可以做的事情的权限。

本质上,它就是一个免费的通行证,可以逃避容器所包含的文件系统、进程、sockets 套接字等,当然它有特定的使用场景,比如在很多 CI/CD 系统中需要的 Docker IN Docker 模式(在 Docker 容器内部需要 Docker 守护进程),以及需要极端网络的地方。即便如此,也有一些方法可以避免使用特权模式,例如,我们可以使用谷歌创建的名为 Kaniko 的工具来替代特权模式的容器。

下面让我们看一个使用 Ubuntu 镜像的例子。

在没有特权的情况下:

代码语言:javascript
复制
$ docker run -it ubuntu sh
# whoami
root # 注意这里,仍然是 root 用户
# id -u
0
# hostname
382f1c400bd
# sysctl kernel.hostname=Attacker
sysctl: setting key "kernel.hostname": Read-only file system  # Yet we can't do this

特权模式:

代码语言:javascript
复制
$ docker run -it --privileged ubuntu sh
# whoami
root. # Root again
# id -u
0
# hostname
86c62e9bba5e
# sysctl kernel.hostname=Attacker
kernel.hostname = Attacker # Except now we are privileged
# hostname
Attacker

如果我们在 Kubernetes 中要使用的话可以使用 SecurityContext 来进行配置:

代码语言:javascript
复制
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    securityContext:
      privileged: true

此外 Kubernetes 还包含一个名为 PodSecurityPolicy 的资源对象,它是一个准入控制器(Kubernetes 在允许容器进入集群之前会它进行检查),强烈建议的一项策略就是配置不允许特权模式的 Pod。

代码语言:javascript
复制
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: example
spec:
  privileged: false  # 禁止特权模式

总结

最后希望你对 root 用户和 --privileged 标志以及它们与宿主机的关系有了更多的认识。我们可以通过不以 root 用户运行、不以特权模式运行以及添加 SecurityContextPodSecurityPolicy 来实现更高的容器安全。

“原文链接:https://itnext.io/docker-and-kubernetes-root-vs-privileged-9d2a37453dec ”

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 k8s技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 作为 Root 运行
  • 避免以 root 运行
  • 特权模式
  • 总结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档