听起来您正在自己的计算机上构建一个用于开发的容器。与生产环境不同,您可以(并且可能应该)选择privileged container。在特权容器中sysfs 以读写方式挂载,因此您可以像在主机上一样控制内核参数。这是我用于在我的 Debian 桌面上开发的 Amazon Linux 容器的示例,它显示了差异
$ docker run --rm -it amazonlinux
bash-4.2# grep ^sysfs /etc/mtab
sysfs /sys sysfs ro,nosuid,nodev,noexec,relatime 0 0
bash-4.2# exit
$ docker run --rm -it --privileged amazonlinux
bash-4.2# grep ^sysfs /etc/mtab
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
bash-4.2# exit
$
注意ro 在非特权情况下挂载,rw 在特权情况下挂载。
注意 Dockerfile 命令
RUN sudo echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
没有意义。它将在 (a) 容器构建期间 (b) 在您构建映像的机器上执行。您希望 (a) 在容器的运行时发生,并且 (b) 在运行容器的机器上发生。如果您需要在映像启动时更改 sysctls,请编写一个脚本来完成所有设置,然后将您放入交互式 shell,例如将脚本放入例如/root 并将其设置为入口点
#!/bin/sh
sudo sysctl kernel.randomize_va_space=0
exec /bin/bash -l
(假设您将主机工作目录挂载到 /home/jas 这是一个很好的做法,因为 bash 会读取您的启动文件等)。
你需要确保容器内有相同的 UID 和 GID,并且可以做到sudo。如何启用 sudo 取决于发行版。在 Debian 中,sudo 组的成员具有不受限制的 sudo 访问权限,而在 Amazon Linux(以及 IIRC、其他类似 RedHat 的系统中,wheel 组具有。通常这归结为您想要的笨拙的运行命令编写脚本而不是键入,例如
docker run -it -v $HOME:$HOME -w $HOME -u $(id -u):$(id -g) --group-add wheel amazonlinux-devenv
由于您的主 UID 和 GID 与主机匹配,因此挂载的主机目录中的文件最终不会归 root 所有。另一种方法是在图像构建期间(即在 Dockerfile 中)为自己创建一个真正的用户,但我发现这更容易出错,因为我最终可以在我的用户名具有不同 UID 的情况下运行这个 devenv 图像,并且这会导致问题。在启动命令中使用 id(1) 可以保证 UID 匹配。