我不是在问如何从头开始创建一个无根的容器。相反,我得到了一些软件部署为预构建的Docker容器映像,默认情况下以root身份运行。我需要修改这些容器,以便它们可以部署在Kubernetes上,这意味着我需要使这些容器无根。需要说明的是,我没有这些容器的源代码,所以我不能简单地从头开始重新构建它们。
我发现了很多关于构建无根容器的文章,但它们都假设您从头开始构建容器。我花了几个小时搜索,但找不到任何关于修改一个现有的容器是无根的。
我知道这可能是一个非常开放的问题,但我不知道我需要考虑的所有事情。我已经能够收集的两件事是添加一行,如USER 1000
到Dockerfile,并调整某些文件和文件夹的所有权和权限。除此之外,我不确定我需要做什么。
在容器中创建用户并切换用户;
Add a new user, named user;
Let this user have root privileges;
Set its password to password;
After the Container is started, log in as user and go directly to the user's home directory;
把下面的代码片段放到Dockerfile中。
RUN useradd --create-home --no-log-init --shell /bin/bash user
&& RUN adduser user sudo
&& RUN echo 'user:password' | chpasswd
USER user
WORKDIR /home/user
使用fixuid修改容器中非root用户的uid和gid;
使用上述代码创建非root用户后,用户的uid和gid一般为1000:1000。
Docker和主机共享一组内核,内核控制的uid和gid仍然只有一组。也就是说,我们在容器中以新创建的docker用户(uid 1000)的身份执行进程,主机会认为这个进程是由主机上uid为1000的用户执行的,这个用户不一定是我们的账号,这就相当于我们一个用户用冒名顶替了别人,很难追踪到真正的用户。
要解决这个问题,可以在添加用户时将uid指定为用户的uid,例如1002;
RUN addgroup --gid 1002 docker &&
adduser --uid 1002 --ingroup docker --home /home/docker --shell /bin/sh --gecos "" docker
一个更好的解决方案是使用fixuid在容器启动时切换uid:
RUN useradd --create-home --no-log-init --shell /bin/bash user
&& adduser user sudo
&& echo 'user:password' | chpasswd
RUN USER=user &&
GROUP=docker &&
curl -SsL https://github.com/boxboat/fixuid/releases/download/v0.4.1/fixuid-0.4.1-linux-amd64.tar.gz | tar -C /usr/local/bin -xzf - &&
chown root:root /usr/local/bin/fixuid &&
chmod 4755 /usr/local/bin/fixuid &&
mkdir -p /etc/fixuid &&
printf "user: $USERngroup: $GROUPn" > /etc/fixuid/config.yml
USER user:docker
ENTRYPOINT ["fixuid"]
此时,您需要在启动容器时指定uid和gid。命令如下:
docker run --rm -it -u $(id -u):$(id -g) image-name bash