Dockerfile内修改/etc/hosts权限报错,非root用户如何更新hosts
问题解答
首先明确结论:你无法在Dockerfile中修改/etc/hosts的权限,这是Docker的内置设计限制,不是操作错误导致的。
原因说明
/etc/hosts、/etc/resolv.conf这类网络相关配置文件,Docker默认会以只读挂载的形式注入到容器的构建和运行环境中,不属于镜像内的可修改普通文件,因此任何在Dockerfile中修改文件本身、修改文件权限的操作都会触发只读文件系统报错。
可行解决方案
根据你的使用场景可以选以下任意一种方案实现需求:
场景1:需要添加的hosts记录是固定的
直接通过Docker命令参数注入即可,不需要修改容器内文件:
- 构建阶段需要固定hosts:执行
docker build --add-host=<域名>:<IP> .,对应记录会自动写入构建环境的/etc/hosts - 运行阶段需要固定hosts:执行
docker run --add-host=<域名>:<IP> <镜像名>,启动容器时自动写入记录
场景2:需要在容器运行时动态修改hosts
方案1:给用户配置sudo权限修改(推荐,无需给容器额外权限)
修改Dockerfile配置:
FROM maven:3.6.3-adoptopenjdk-11 COPY ./ ./ RUN addgroup --gid 900 --system gtest RUN adduser --uid 9000 --system --disabled-password --gecos "" --shell /bin/sh --ingroup gtest utest; # 安装sudo并配置utest无需密码即可修改hosts RUN apt update && apt install -y sudo && rm -rf /var/lib/apt/lists/* RUN echo "utest ALL=(ALL) NOPASSWD: /usr/bin/tee -a /etc/hosts" >> /etc/sudoers USER 9000 ENTRYPOINT ["./start.sh"]
在start.sh中需要修改hosts时,使用以下命令即可:
echo "<IP> <域名>" | sudo tee -a /etc/hosts
方案2:启动时先用root改hosts再切换普通用户
删除Dockerfile中的USER 9000配置,新增一个入口脚本entrypoint.sh:
#!/bin/bash # 先以root身份修改hosts echo "<IP> <域名>" >> /etc/hosts # 切换到utest用户执行业务脚本 exec su utest -c "./start.sh"
修改Dockerfile的ENTRYPOINT为执行这个入口脚本即可,这种方案不需要安装sudo,也不用给容器加额外权限。
方案3:给容器加 NET_ADMIN 权限
如果确实需要utest用户直接修改hosts文件,启动容器时添加权限参数:
docker run --cap-add=NET_ADMIN <镜像名>
此时容器内的/etc/hosts会变为可写,普通用户也可以直接修改,缺点是给容器开放了较高的网络权限,存在安全风险。
内容的提问来源于stack exchange,提问作者user10916892
相关产品推荐
相关产品推荐

