Dockerfile构建镜像过程中的错误记录及解决方法
目录
需求背景
错误及解决方法
2.1 需求理解错误
2.2 Docker build 无法解析域名
2.3 Docker build 找不到Dockerfile文件
2.4 镜像拉取的权限问题
1. 需求背景
一个镜像基底的Linux环境没有telnet工具,所以想要将telnet加入这个基底镜像后构建一个新的基底镜像,同时要删除安装过程中的软件包和一些缓存。
基本方法:编写dockerfile文件;使用这个dockerfile进行镜像的构建;上传镜像到镜像仓库。
2. 错误及解决方法
2.1 需求理解出错
开始博主理解错了意思,直接在一个Dockerfile文件中追加了以下的Run指令:
RUN .. \
&& .. \
&& yum install telnet -y \
&& yum clean all \
&& rm -rf /var/cache/yum/*
后和导师交流后,改成只对某个镜像基底追加安装telnet:
FROM <repository>:<tag>
RUN yum install telnet -y \
&& yum clean all \
&& rm -rf /var/cache/yum/*
2.2 Docker build 无法解析域名
开始进行 docker build 构建镜像时,就遇到了以下的问题:
[root@localhost dockerfile1]# docker build -t xx:xx .
...
=> ERROR [2/2] RUN yum install telnet -y && yum clean all && rm -rf /var/cache/yum/*
------
> [2/2] RUN yum install telnet -y && yum clean all && rm -rf /var/cache/yum/*:
0.443 Loaded plugins: fastestmirror, ovl
0.561 Determining fastest mirrors
21.11 Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=container error was
21.11 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown error"
根据百度和个人分析,发现是Linux环境网络配置出错了,无法解析这个域名。我的第一想法是,这不是容器内的网络吗,难道我要用RUN去更改配置然后再改回来?这种想法很快被我否决。为了解决(绕过)这个问题,我甚至用了离线安装包的方法让容器装上telnet,很明显这指标不治本。后来导员成功使用类似的Dockerfile进行了镜像的构建,这说明不是镜像的问题,是我的虚拟机或Docker配置的问题。
解决方法:在docker的daemon.json中追加DNS服务器地址。
# 追加到 etc/docker/daemon.json,注意JSON的格式
{
"dns": ["8.8.8.8", "114.114.114.114"]
}
# 修改完daemon.json之后
systemctl daemon-reload
systemctl docker restart
# 此时docker可以正常构建镜像了
2.3 Docker build 找不到Dockerfile文件
在构建镜像时出现下面的错误:
# docker build -t <repository>:<tag> .
ERROR: failed to solve: failed to read dockerfile: open /data/docker/tmp/buildkit-mount163215541/Dockerfile: no such file or directory
解决方法:运行该指令需要进入Dockerfile的文件夹,同时Dockerfile的文件名需要是“Dockerfile",其他名称也会提示找不到该文件。可以使用-f指定Dockerfile文件。
2.4 镜像拉取的权限问题
镜像拉取时,出现了这个错误信息:'pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed.'
这是因为拉取的镜像处于受保护的状态,即私有镜像。
解决方法:使用 docker login 登入镜像仓库:
# 将会提示你输入用户名和密码
docker login your_registory_url