镜像的使用与命令
# 镜像的使用与命令
会使用docker的特征之一就是能通过镜像启动容器,来帮助我们进行各种工作。但问题是,安装好docker后,系统内是没有镜像可以使用的。
# 查看镜像指令
查看系统内有多少镜像可以通过如下命令:
docker images
# 或者
docker image ls
2
3
如果你没有下载任何镜像,结果会像下面这般,如果有镜像,则title下会多几行
REPOSITORY TAG IMAGE ID CREATED SIZE
那如何下载镜像呢?还记得之前提到的仓库吗?通过它就可以实现镜像的下载。
Docker 默认使用 Docker Hub
作为镜像仓库,通常不需要特别配置。但如果你想要使用特定的镜像仓库地址(比如国内镜像源以加快下载速度),可以通过修改 Docker 的配置文件来实现(因为一些原因,国内访问它有点困难,后续我们便将默认仓库地址设为国内镜像源)。
# 配置镜像源
docker安装后,是有一个默认仓库地址的,既然有,那我们可以看吗?当然可以,使用如下命令,即可查看
# 查看docker仓库地址指令
docker info
在输出的信息中,找到 Registry Mirrors
部分,这里会列出所有配置的镜像源地址。例如:
Registry Mirrors:
https://registry.docker-cn.com/
http://hub-mirror.c.163.com/
2
3
但,你也可能会发现,你没有 Registry Mirrors
,只有一个Registry
,这是因为你没有配置额外的仓库地址(加速地址)。
那如何进行配置呢?使用文本编辑器(如 nano
或 vim
)以 root 权限打开 /etc/docker/daemon.json
文件。如果文件不存在,创建它。
可能你会差异,为什么配置文件会不存在,是否是安装出了问题。
这里是官网给的配置方法:daemon配置 (opens new window)
To configure the Docker daemon using a JSON file, create a file at /etc/docker/daemon.json on Linux systems, or C:\ProgramData\docker\config\daemon.json on Windows. On MacOS go to the whale in the taskbar > Preferences > Daemon > Advanced.
如果要使用Docker daemon,则请创建,官网中并没说明一定能找到,那我们就进行创建吧。
# 配置加速仓库地址
sudo vim /etc/docker/daemon.json
然后是添加对应配置
{
"registry-mirrors": [
"https://xx4bwyg2.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
2
3
4
5
6
7
8
完成后,记得重启docker,这之后再使用docker info,就能看到 Registry Mirrors
部分了,同时也能看到我们刚刚配置的仓库地址,到此配置加速地址结束。
systemctl restart docker
实际上执行docker pull <image name>
命令,都是先从本地搜索,如果本地搜索不到xxx
镜像则从配置的加速仓库地址中查询,如果还找不到最后才是从 Docker Hub 下载镜像。
# 镜像的相关操作
# 查看与寻找
镜像成功获取后,可以通过之前说的命令来查看
docker images
如果我们想要查询指定的镜像,可以使用docker image ls
命令来查询。
docker image ls mysql
当然你也可以使用docker images
命令列出所有镜像,然后使用grep
命令进行过滤。使用方法如下:
docker images |grep mysql
# “重命名”镜像
如果你想要自定义镜像名称或者推送镜像到其他镜像仓库,你可以使用docker tag
命令将镜像重命名。docker tag
的命令格式为 docker tag [SOURCE_IMAGE][:TAG] [TARGET_IMAGE][:TAG]。
下面我们通过实例演示一下:
docker tag busybox:latest mybusybox:latest
执行完docker tag
命令后,可以使用查询镜像命令查看一下镜像列表:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 018c9d7b792b 3 weeks ago 1.22MB
mybusybox latest 018c9d7b792b 3 weeks ago 1.22MB
2
3
4
可以看到,镜像列表中多了一个mybusybox
的镜像。但细心的同学可能已经发现,busybox
和mybusybox
这两个镜像的 IMAGE ID 是完全一样的。为什么呢?实际上它们指向了同一个镜像文件,只是别名不同而已。 如果我不需要mybusybox
镜像了,想删除它,应该怎么操作呢?
# 删除镜像
你可以使用docker rmi
或者docker image rm
命令删除镜像。
$ docker image rm mybusybox
Untagged: mybusybox:latest
2
# 构建镜像-重要
构建镜像主要有两种方式:
- 使用
docker commit
命令从运行中的容器提交为镜像; - 使用
docker build
命令从 Dockerfile 构建镜像。
这里主要介绍第二种,通过Dockerfile+docker build命令进行构建。这种方式是最重要也是最常用的镜像构建方式。
Dockerfile 是一个包含了用户所有构建命令的文本。通过docker build
命令可以从 Dockerfile 生成镜像。
使用 Dockerfile 构建镜像具有以下特性:
- Dockerfile 的每一行命令都会生成一个独立的镜像层,并且拥有唯一的 ID;
- Dockerfile 的命令是完全透明的,通过查看 Dockerfile 的内容,就可以知道镜像是如何一步步构建的;
- Dockerfile 是纯文本的,方便跟随代码一起存放在代码仓库并做版本管理。
看到使用 Dockerfile 的方式构建镜像有这么多好的特性,你是不是已经迫不及待想知道如何使用了。别着急,我们先学习下 Dockerfile 常用的指令。
Dockerfile 指令 | 指令简介 |
---|---|
FROM | Dockerfile 除了注释第一行必须是 FROM ,FROM 后面跟镜像名称,代表我们要基于哪个基础镜像构建我们的容器。 |
RUN | RUN 后面跟一个具体的命令,类似于 Linux 命令行执行命令。 |
ADD | 拷贝本机文件或者远程文件到镜像内 |
COPY | 拷贝本机文件到镜像内 |
USER | 指定容器启动的用户 |
ENTRYPOINT | 容器的启动命令 |
CMD | CMD 为 ENTRYPOINT 指令提供默认参数,也可以单独使用 CMD 指定容器启动参数 |
ENV | 指定容器运行时的环境变量,格式为 key=value |
ARG | 定义外部变量,构建镜像时可以使用 build-arg = 的格式传递参数用于构建 |
EXPOSE | 指定容器监听的端口,格式为 [port]/tcp 或者 [port]/udp |
WORKDIR | 为 Dockerfile 中跟在其后的所有 RUN、CMD、ENTRYPOINT、COPY 和 ADD 命令设置工作目录。 |
看了这么多指令,感觉有点懵?别担心,我通过一个实例让你来熟悉它们。这是一个 Dockerfile:
FROM centos:7
COPY nginx.repo /etc/yum.repos.d/nginx.repo
RUN yum install -y nginx
EXPOSE 80
ENV HOST=mynginx
CMD ["nginx","-g","daemon off;"]
2
3
4
5
6
好,我来逐行分析一下上述的 Dockerfile。
- 第一行表示我要基于 centos:7 这个镜像来构建自定义镜像。这里需要注意,每个 Dockerfile 的第一行除了注释都必须以 FROM 开头。
- 第二行表示拷贝本地文件 nginx.repo 文件到容器内的 /etc/yum.repos.d 目录下。这里拷贝 nginx.repo 文件是为了添加 nginx 的安装源。
- 第三行表示在容器内运行
yum install -y nginx
命令,安装 nginx 服务到容器内,执行完第三行命令,容器内的 nginx 已经安装完成。 - 第四行声明容器内业务(nginx)使用 80 端口对外提供服务。
- 第五行定义容器启动时的环境变量 HOST=mynginx,容器启动后可以获取到环境变量 HOST 的值为 mynginx。
- 第六行定义容器的启动命令,命令格式为 json 数组。这里设置了容器的启动命令为 nginx ,并且添加了 nginx 的启动参数 -g ‘daemon off;’ ,使得 nginx 以前台的方式启动。
# 总结
通过上面的目录结构可以看到,Dockerfile 的每一行命令,都生成了一个镜像层,每一层的 diff 夹下只存放了增量数据,如图 2 所示。
分层的结构使得 Docker 镜像非常轻量,每一层根据镜像的内容都有一个唯一的 ID 值,当不同的镜像之间有相同的镜像层时,便可以实现不同的镜像之间共享镜像层的效果。
总结一下, Docker 镜像是静态的分层管理的文件组合,镜像底层的实现依赖于联合文件系统(UnionFS)。充分掌握镜像的原理,可以帮助我们在生产实践中构建出最优的镜像,同时也可以帮助我们更好地理解容器和镜像的关系。