198 lines
8.6 KiB
Markdown
198 lines
8.6 KiB
Markdown
告别`sudo`!无需Root权限也能玩转Docker?本文教你如何在无Root模式下安装Docker,利用用户命名空间隔离权限,保障安全。但需注意端口限制和`cgroup v2`依赖。更有`uidmap`安装、`NGINX`测试等干货,更有`Podman`等替代方案,云原生安全再升级!
|
||
|
||
> 译自:[How to Run Docker in Rootless Mode](https://link.juejin.cn/?target=https%3A%2F%2Fthenewstack.io%2Fhow-to-run-docker-in-rootless-mode%2F "https://thenewstack.io/how-to-run-docker-in-rootless-mode/")
|
||
>
|
||
> 作者:Jack Wallen
|
||
|
||
虽然可以在没有 root 权限的情况下部署 [Docker](https://link.juejin.cn/?target=https%3A%2F%2Fwww.docker.io%2F "https://www.docker.io/") 容器,但这并不一定意味着它完全是无 root 的。这是因为堆栈中还有其他组件(例如 runc、containerd 和 dockerd)确实需要 root 权限才能运行。这可能会因权限提升攻击而导致安全问题。
|
||
|
||
当然,您可以将您的用户添加到 docker 组并在没有 sudo 帮助的情况下运行 docker 部署命令,但这实际上并没有解决问题。还有其他运行 docker 的方法看起来不错,但最终,它们与使用 sudo 权限运行 docker 一样危险。
|
||
|
||
那么,您该怎么办?您可以始终选择无 root 模式。
|
||
|
||
无 Root 模式的工作原理
|
||
--------------
|
||
|
||
实际上,运行无 root Docker 利用了用户命名空间。该子系统提供跨进程的权限隔离和用户身份隔离。自 3.8 版本以来,Linux 内核就提供了此功能,并且可以与 docker 一起使用以映射一系列用户 ID,以便最内层命名空间中的 root 用户映射到父命名空间中的非特权范围。
|
||
|
||
Docker 已经能够利用用户命名空间功能一段时间了。这是使用 `--userns-remap` 选项完成的。唯一的问题是运行时引擎仍然以 root 身份运行,因此它并没有解决我们的问题。
|
||
|
||
这就是无 root docker 发挥作用的地方。
|
||
|
||
局限性
|
||
---
|
||
|
||
### 特权端口访问
|
||
|
||
不幸的是,无 root 模式并不完美。第一个问题是无 root docker 将无法访问特权端口,即任何低于 1024 的端口。这意味着您需要记住将 [您的容器](https://link.juejin.cn/?target=https%3A%2F%2Fthenewstack.io%2Fintroduction-to-containers%2F "https://thenewstack.io/introduction-to-containers/") 暴露给 1024 以上的端口,否则它们将无法运行。
|
||
|
||
### 容器的资源限制
|
||
|
||
另一个问题是,只有在使用 cgroup v2 和 systemd 运行时,才支持使用诸如 –cpus、–memory 和 –pids-limit 之类的选项来限制资源。
|
||
|
||
您可能遇到的其他限制包括:
|
||
|
||
* 不支持 AppArmor、checkpoint、overlay network 和 SCTP 端口暴露。
|
||
* 存储驱动程序支持有限(仅支持 overlay2、fuse-overlayfs 和 vfs 存储驱动程序)。
|
||
* 不支持 –net-host。
|
||
|
||
综上所述,我们如何安装 docker 以便它可以在无 root 模式下运行?实际上非常简单。让我来告诉你怎么做。
|
||
|
||
我将在我首选的服务器 Ubuntu Server 20.04 上进行演示,但您几乎可以在任何 Linux 发行版上执行此操作。唯一的区别是为唯一依赖项运行的安装命令。
|
||
|
||
安装唯一的依赖项
|
||
--------
|
||
|
||
我们必须做的第一件事是为此设置安装唯一的依赖项。该依赖项是 uidmap,它处理系统的用户命名空间映射。要安装 uidmap,请登录到您的服务器并发出以下命令:
|
||
|
||
```bash
|
||
sudo apt-get install uidmap -y
|
||
|
||
```
|
||
|
||
这就是依赖项的全部内容。
|
||
|
||
安装 Docker
|
||
---------
|
||
|
||
接下来,我们安装 Docker。我们不想使用标准存储库中找到的版本,因为它无法在无 root 模式下成功运行。相反,我们需要下载一个特殊的安装脚本,该脚本将安装无 root Docker。
|
||
|
||
**下载并运行 Docker 无 root 安装程序**
|
||
|
||
我们可以使用单个命令下载并安装无 root 版本的 docker:
|
||
|
||
```bash
|
||
curl -fsSL https://get.docker.com/rootless | sh
|
||
|
||
```
|
||
|
||
**添加必要的变量**
|
||
|
||
安装完成后,您需要将一对环境变量添加到 .bashrc。使用以下命令打开文件:
|
||
|
||
```bash
|
||
nano ~/.bashrc
|
||
|
||
```
|
||
|
||
在该文件中,将以下行添加到末尾:
|
||
|
||
```bash
|
||
export PATH=/home/jack/bin:$PATH
|
||
export DOCKER_HOST=unix:///run/user/1000/docker.sock
|
||
|
||
```
|
||
|
||
注意:请务必添加您的特定用户 ID。在上面的代码中,我的 ID 是 1000。要查找您的用户 ID,请发出以下命令:
|
||
|
||
```bash
|
||
id
|
||
|
||
```
|
||
|
||
您需要添加 _uid=_ 后面的数字,如下所示:
|
||
|
||
```bash
|
||
export DOCKER_HOST=unix:///run/user/ID/docker.sock
|
||
|
||
```
|
||
|
||
其中 _ID_ 是您的用户 ID 号。 保存并关闭文件。
|
||
|
||
注销并重新登录到服务器(以便更改生效),您就可以测试无 root docker 了。
|
||
|
||
测试无 Root Docker
|
||
---------------
|
||
|
||
我们将部署我们值得信赖的 NGINX 容器作为测试。请记住,我们尚未将我们的用户添加到 docker 组。如果这是一个标准的 Docker 安装,那么如果不将我们的用户添加到 docker 组或使用 `sudo` 权限运行部署命令,我们将无法成功部署 NGINX 容器。
|
||
|
||
**使用 NGINX 测试无 Root Docker**
|
||
|
||
要测试无 root 模式(以分离模式部署 NGINX),请发出以下命令:
|
||
|
||
```bash
|
||
docker run --name docker-nginx -p 8080:80 -d nginx
|
||
|
||
```
|
||
|
||
打开一个 Web 浏览器并将其指向 [http://SERVER:8080(其中](https://link.juejin.cn/?target=http%3A%2F%2FSERVER%3A8080%25EF%25BC%2588%25E5%2585%25B6%25E4%25B8%25AD "http://SERVER:8080%EF%BC%88%E5%85%B6%E4%B8%AD") SERVER 是您的 Docker 服务器的 IP 地址),您应该会看到 NGINX 欢迎页面。 这个容器的部署未使用 root 用户,因此整个堆栈都没有那些提升的权限。
|
||
|
||
**使用 Ubuntu 容器测试无根模式**
|
||
|
||
您甚至可以部署一个完整的 Linux 容器,并通过如下命令访问它的 bash shell:
|
||
|
||
```bash
|
||
docker run -it ubuntu bash
|
||
|
||
```
|
||
|
||
所有这些操作都不需要触及 root 权限。
|
||
|
||
结论
|
||
--
|
||
|
||
显然,这并不是解决 Docker 容器所有安全问题的完美方案。您甚至可能会发现 [Podman](https://link.juejin.cn/?target=https%3A%2F%2Fthenewstack.io%2Fdeploy-a-pod-on-centos-with-podman%2F "https://thenewstack.io/deploy-a-pod-on-centos-with-podman/") 是一个更好的解决方案,因为它可以在开箱即用的情况下以无根模式运行。但是对于那些已经投资 Docker,但又希望尽可能提高安全性的用户来说,以无根模式运行 Docker 肯定是一个可行的选择。
|
||
|
||
尝试一下无根 Docker,看看它是否能稍微缓解您的安全难题。
|
||
|
||
无 root 模式常见问题解答
|
||
---------------
|
||
|
||
### 1\. 什么是 Docker 无根模式?
|
||
|
||
答:Docker 无根模式允许您在不需要超级用户权限的情况下运行容器,它利用 Linux 内核提供的命名空间和 cgroups。
|
||
|
||
### 2\. 为什么要使用 Docker 无根模式?
|
||
|
||
以无根模式运行 Docker 提供了以下几个好处:
|
||
|
||
**安全性**:降低了潜在的安全风险,因为没有进程以提升的权限运行。
|
||
|
||
**隔离性**:提高了系统隔离性,因为每个容器都在其自己的用户命名空间中运行。
|
||
|
||
**灵活性**:允许使用非 root 用户,并避免与现有的基于 root 的应用程序发生冲突。
|
||
|
||
### 4\. 我还需要 Dockerd 吗?
|
||
|
||
答:是的,您仍然需要一个 docker 守护进程 (dockerd)。您可以按如下方式启动它:
|
||
|
||
```bash
|
||
dockerd-rootless-setuptool.sh install –non-suid
|
||
|
||
```
|
||
|
||
此命令以无根模式启动 dockerd。
|
||
|
||
### 5\. 如何运行容器?
|
||
|
||
答:一旦 Docker 无根模式设置完成,您就可以使用标准的 docker 命令来运行容器,例如:
|
||
|
||
```bash
|
||
docker run -it ubuntu bash
|
||
|
||
```
|
||
|
||
### 6\. 我可以在无根模式下使用 Docker Compose 吗?
|
||
|
||
答:是的,您可以在无根模式下使用 Docker Compose。只需确保 Docker 和 Docker Compose 都已安装。
|
||
|
||
### 7\. 网络配置如何?
|
||
|
||
答:在无根模式下,网络设置与 root 模式不同。默认情况下,_dockerd-rootless-setuptool.sh_ 使用 SLIRP4NetNS 为网络配置一个用户特定的网络堆栈。可以通过修改 /home/USER/.local/share/docker/rootless 下的配置文件(其中 USER 是您的用户名)来自定义此设置。
|
||
|
||
### 8\. 我可以与主机共享 Docker 卷吗?
|
||
|
||
答:是的,但是您需要挂载可以从您的用户命名空间访问的卷。例如,您可以这样做:
|
||
|
||
```bash
|
||
docker run -v /host/data:/container/data ubuntu bash
|
||
|
||
```
|
||
|
||
请注意,共享卷的某些功能可能在无根模式下未完全支持。
|
||
|
||
### 9\. 我可以访问 docker system prune 和其他命令吗?
|
||
|
||
答:并非所有命令都可以在无根模式下直接工作。例如,您不能使用 _docker system prune_,因为它需要访问非 root 用户无法访问的主机内核。
|
||
|
||
您可以通过使用容器化的 Docker 版本来运行这些命令。 |