Docker容器内执行sed命令时出现无法rename设备或资源忙报错
Docker容器内执行sed修改resolv.conf报错解决方案
报错原因
容器内的/etc/resolv.conf、/etc/hosts、/etc/hostname三个文件默认是Docker通过绑定挂载注入到容器内的,不属于容器文件系统可直接替换的普通文件。sed -i(原地修改)的实现逻辑是先生成临时修改文件,再用临时文件重命名替换原文件,而绑定挂载的文件不允许被直接替换重命名,因此触发Device or resource busy报错。
解决方案
- 方案1:容器内直接修改内容,不替换原文件
不要使用sed -i的原地替换逻辑,改用读取文件内容替换后覆盖写入原文件的方式,执行命令如下:
sed 's/127.0.0.11/8.8.8.8/g' resolv.conf > /tmp/resolv.tmp && cat /tmp/resolv.tmp > resolv.conf && rm /tmp/resolv.tmp
该方案仅修改文件内容,不会触发重命名替换原文件的操作,可绕过挂载限制。
- 方案2:启动容器时直接指定DNS(推荐)
如果需要容器默认使用指定DNS,不需要进入容器后修改,启动容器时添加--dns参数即可:
docker run --dns 8.8.8.8 --dns 114.114.114.114 <你的镜像名称>
启动后容器的resolv.conf会自动写入指定的DNS地址,无需二次修改。
- 方案3:docker-compose配置固定DNS
如果使用docker-compose管理容器,在对应服务的配置项中添加dns配置即可:
services: 你的服务名: image: 你的镜像名 dns: - 8.8.8.8 - 114.114.114.114
- 方案4:挂载自定义resolv.conf文件
如果需要自定义更多resolv.conf配置项,可以提前在本地准备好resolv.conf文件,启动容器时直接挂载覆盖:
docker run -v /本地路径/resolv.conf:/etc/resolv.conf <你的镜像名称>
内容的提问来源于stack exchange,提问作者cao ting
相关产品推荐
相关产品推荐

