1. 概述
本文我们将学习如何在Docker容器中使用不同的用户执行命令。
首先我们使用root用户访问Docker容器,以获取最高权限,然后讨论如何为root用户和非root用户设置密码,以保护容器免受攻击。
2. 运行一个示例容器
为了方便演示,我们创建一个Dockerfile。Docker容器默认以root用户运行,为了安全考虑限制用户权限,这里添加一个用户john,并将其作为默认用户:
FROM ubuntu:16.04
RUN apt-get update
RUN useradd -m john
USER john
CMD /bin/bash
这里我们使用 ubuntu:16.04 作为基础镜像,下面使用 docker build 命令来构建镜像
$ docker build -t baeldung .
Sending build context to Docker daemon 2.048kB
Step 1/5 : FROM ubuntu:16.04
16.04: Pulling from library/ubuntu
58690f9b18fc: Pull complete
...
Step 5/5 : CMD /bin/bash
---> Running in d04af94585e2
Removing intermediate container d04af94585e2
---> 312faa93c781
Successfully built 312faa93c781
Successfully tagged baeldung:latest
现在,使用我们新构建的 baeldung 镜像来运行一个Docker容器:
$ docker run -id --name baeldung baeldung
34dbc77279a2a6244b0e4ee87890d79e814128391c6a4387d2e2fd10fa6e8f20
使用 docker ps 命令检查容器是否正在运行:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
34dbc77279a2 baeldung "/bin/sh -c /bin/bash" About a minute ago Up About a minute baeldung
3. 访问Docker容器
3.1. 使用非root用户
使用 docker exec 命令我们可以进入正在运行的容器里:
$ docker exec -it baeldung bash
记得前面我们创建的Dockerfile中,我们添加了一个名为 john 的用户,它被设置为运行容器时的默认用户。我们可以使用whoami命令来验证这一点:
$ whoami
john
因为是非root运行,所以如果安装任何软件,会报错:
$ apt-get update
Reading package lists... Done
W: chmod 0700 of directory /var/lib/apt/lists/partial failed - SetupAPTPartialDirectory (1: Operation not permitted)
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/
现在,我们退出容器,下面学习使用root用户重新登录。
3.2. 使用 root 用户
我们可以通过 -u 参数 指定进入容器时使用的用户:
$ docker exec -it -u 0 baeldung bash
上面的 -u 0
为 root 用户的ID,我们也可以使用用户名:
$ docker exec -it -u root baeldung bash
执行whoami命令确认当前用户信息:
$ whoami
root
现在,我们以root用户身份进入了容器。我们可以在容器上执行任何操作。
另一种方案,我们也可以 nsenter 命令。首先我们需要知道正在运行的容器的PID,获取命令如下:
$ docker inspect --format {{.State.Pid}} baeldung
6491
得到 PID 后,执行 nsenter 命令:
$ nsenter --target 6491 --mount --uts --ipc --net --pid
这使我们可以作为root用户访问Docker容器,并执行任何操作。
4. 在容器内使用 sudo 命令
将前面的 Dockerfile 稍加修改,安装下 sudo:
FROM ubuntu:16.04
RUN apt-get update && apt-get -y install sudo
RUN useradd -m john && echo "john:john" | chpasswd && adduser john sudo
USER john
CMD /bin/bash
我们还使用了 chpasswd 命令为 john 用户添加密码,然后将其作为默认用户。
然后构建镜像:
$ docker build -t baeldung .
运行容器:
$ docker run -id --name baeldung baeldung
b0f83a7e8b49ddf043c80792f21d5c483c0c5ab56c700815a83b0a40e5292754
进入容器:
$ docker exec -it baeldung bash
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
检测当前登录的用户名
$ whoami
john
这确认了我们以非root用户的身份登录。如果我们运行 apt-get update 命令,我们将遇到与3.2节相同的权限相关问题。
这次,我们将使用 sudo 命令为非root用户 john 获取特权:
$ sudo apt-get update
[sudo] password for john:
Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [99.8 kB]
Hit:2 http://archive.ubuntu.com/ubuntu xenial InRelease
Get:3 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [99.8 kB]
Get:4 http://archive.ubuntu.com/ubuntu xenial-backports InRelease [97.4 kB]
Fetched 297 kB in 1s (178 kB/s)
Reading package lists... Done
然后操作成功了
5. 总结
在本文中,我们展示了如何在Docker容器中使用不同用户运行命令。首先,我们讨论了在运行的Docker容器中root用户和非root用户的角色。然后,我们学习了如何作为root用户访问Docker容器以获取额外的特权。
理想情况下,我们不应该允许root用户访问Docker容器。这增加了更多的安全顾虑。相反,我们应该创建一个单独的用户来访问容器。这是在容器世界中的标准安全步骤。