目录
前言
容器的镜像管理分为两个部分,一个是镜像的操作及镜像制作,另一个是镜像仓库的操作。本章我们将展开说说容器镜像的基础和镜像制作(docker commit 和dockerfile),这章主要介绍docker commit的构建功能,关于dockerfile的构建方式我们会在后面专门拿几个章节来介绍。
镜像管理
1. 镜像命名规范
无论我们对镜像做何种操作,首先它得有个名字。我们在前面使用docker run来运行容器的时候,就需要传递一个镜像名称,容器基于该镜像来运行。
一个完整的镜像名称由两部分组成:
<image name> = <repository>:[tag]
其中repository包含如下内容:
[Docker Registry地址/][项目目录/]<名称>
所以一个完整的镜像命名如下:
[Docker Registry地址/][项目目录/]<名称>:[标签]
示例:
# 官方镜像
nginx:latest ===>docker.io/library/nginx:latest
# 个人仓库镜像
hub.xhz.com/library/nginx:v1.1
当没指明镜像tag时,默认为latest,但latest没有任何特殊含义,在docker hub上很多repository将latest作为最新稳定版本的别名,但这只是一种约定,不是强制规定,一个repository可以有多个tag,而多个tag也可能对应同一个镜像。关于镜像的命名我们将在后续docker 镜像仓库管理中详细说明。
2. 镜像基础操作
2.1 下载镜像
# 直接从docker hub下载
docker pull centos:7.6
# 从个人仓库下载镜像
docker pull hub.docker.com:5000/centos:7.6
2.2 查看镜像信息
# 查看本地已下载的镜像
docker image ls / docker images
# #获取镜像的详细信息
docker inspect centos:7.6
2.3 镜像创建tag
# 一般在镜像镜像上传到本地仓库的时候会给镜像打tag
docker tag centos:latest hu.hxz.com:5000/centos:7.6
2.4 查看镜像
# 查看mysql镜像
docker search mysql
2.5 删除镜像
#如果一个镜像有多个tag,只会删除指定的tag,镜像本身不会删除,如果docker rmi后指定镜像ID,则所有tag都会被删除
docker rmi centos:6.6
# 删除无标签镜像(即为none)
#--filter 选项用来根据一些条件来过滤命令的输出结果。在这里,过滤器 dangling=true 用来只显示那些没有被标记(没有标签)并且没有被任何容器使用的“悬空镜像”
docker rmi $(docker images -q --filter "dangling=true")
docker images
命令可以列出本地所有的Docker镜像。--filter
选项可以用来过滤这些镜像,以便快速找到需要的镜像。1. 按照镜像的名称过滤:
#这个命令将会列出所有名称包含“nginx”的镜像。 docker images --filter "name=nginx"
2. 按照镜像的标签过滤
#这个命令将会列出所有带有标签“version=1.2”的镜像 docker images --filter "label=version=1.2"
3. 按照镜像的大小过滤:
#这个命令将会列出所有大小在ubuntu:18.04之前的镜像。 docker images --filter "before=ubuntu:18.04"
4. 按照镜像的ID过滤
#这个命令将会列出所有ID为abcd1234的镜像。 docker images --filter "id=sha256:abcd1234"
5. 按照镜像的过滤条件组合过滤:
#这个命令将会列出所有带有标签“version=1.2”且大小在ubuntu:18.04之前的镜像 docker images --filter "before=ubuntu:18.04" --filter "label=version=1.2"
2.6 导出和载入镜像
# 将本地镜像导出
docker save -o nginx_latest.tar nginx:latest
# 将本地文件导入镜像
docker load --input nginx_latest.tar
2.7 提交镜像
docker commit -m "Add a new file" -a "xhz" a925cb42bi90 test #使用a925cb42bi90容器生成一个名为test的镜像
-a:指定作者
-m:相关说明信息
-p:提交时暂停容器运行
镜像构建
镜像构建有两种方式,一是在容器容器中进行相应的操作之后,通过docker commit进行构建,一个是通过dockerfile的方式进行构建(主要/重要)
1. docker commit构建
1.1 commit构建原理
我们需要先创建一个运行的容器,作为基础容器;然后通过exec进入到容器内部,在容器内部操作我们需要添加或修改的内容,最后通过docker commit命令将该容器制作成一个新的镜像。
1.2 commit命令
docker commit -m "Add a new file" -a "xhz" a925cb42bi90 test #使用a925cb42bi90容器生成一个名为test的镜像
-a:指定作者
-m:相关说明信息
-p:提交时暂停容器运行
1.3 构建示例
以启动的centos7容器为基础,部署一个ssh服务。
Step1:前台运行一个centos:7的容器
[root@clinet ~]#docker run -it centos:7
Step2: 在容器内安装openssh-server服务
[root@205db1bbdd9a ssh]# yum -y install openssh-server
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
* base: mirrors.ustc.edu.cn
* extras: mirrors.ustc.edu.cn
* updates: mirrors.ustc.edu.cn
Package openssh-server-7.4p1-22.el7_9.x86_64 already installed and latest version
Nothing to do
[root@205db1bbdd9a ssh]#
Step3: 给root用户设置密码
[root@205db1bbdd9a ssh]# echo 'xhz123' |passwd root --stdin
Changing password for user root.
passwd: all authentication tokens updated successfully.
[root@205db1bbdd9a ssh]#
step4: 前台启动sshd服务
[root@205db1bbdd9a ssh]# /usr/sbin/sshd -D
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
sshd: no hostkeys available -- exiting.
[root@205db1bbdd9a ssh]#
启动报错,提示缺少ssh_host_rsa_key,ssh_host_ecdsa_key,ssh_host_ed25519_key
Step5,:解决报错
将宿主机本地的文件拷贝至容器内
## 将文件拷贝至容器内
[root@clinet ~]# docker cp /etc/ssh/ssh_host_rsa_key 205db1bbdd9a:/etc/ssh
Preparing to copy...
Copying to container - 3.584kB
Successfully copied 3.584kB to 205db1bbdd9a:/etc/ssh
[root@clinet ~]#
[root@clinet ~]# docker cp /etc/ssh/ssh_host_ecdsa_key 205db1bbdd9a:/etc/ssh
Preparing to copy...
Copying to container - 2.048kB
Successfully copied 2.048kB to 205db1bbdd9a:/etc/ssh
[root@clinet ~]# docker cp /etc/ssh/ssh_host_ed25519_key 205db1bbdd9a:/etc/ssh
Preparing to copy...
Copying to container - 2.048kB
Successfully copied 2.048kB to 205db1bbdd9a:/etc/ssh
[root@clinet ~]#
#修改拷贝文件的权限
[root@205db1bbdd9a ssh]# ls -l
total 592
-rw-r--r--. 1 root root 581843 Nov 24 2021 moduli
-rw-r--r--. 1 root root 2276 Nov 24 2021 ssh_config
-rw-r-----. 1 root input 227 Oct 10 13:54 ssh_host_ecdsa_key
-rw-r-----. 1 root input 387 Oct 10 13:54 ssh_host_ed25519_key
-rw-r-----. 1 root input 1675 Oct 10 13:54 ssh_host_rsa_key
-rw-------. 1 root root 3907 Nov 24 2021 sshd_config
[root@205db1bbdd9a ssh]#
[root@205db1bbdd9a ssh]#
[root@205db1bbdd9a ssh]# chown root:root ssh_host_*
[root@205db1bbdd9a ssh]# chmod 0600 ssh_host_*
[root@205db1bbdd9a ssh]#
[root@205db1bbdd9a ssh]# ls -l
total 592
-rw-r--r--. 1 root root 581843 Nov 24 2021 moduli
-rw-r--r--. 1 root root 2276 Nov 24 2021 ssh_config
-rw-------. 1 root root 227 Oct 10 13:54 ssh_host_ecdsa_key
-rw-------. 1 root root 387 Oct 10 13:54 ssh_host_ed25519_key
-rw-------. 1 root root 1675 Oct 10 13:54 ssh_host_rsa_key
-rw-------. 1 root root 3907 Nov 24 2021 sshd_config
[root@205db1bbdd9a ssh]#
Setp6: 前台启动sshd服务
前台启动服务是占用进程的。
Step7:通过commit构建镜像
docker commit -m 'install openssh-server' -a 'xhz' -p 205db1bbdd9a opensssh_v1.0
sha256:01a141d087eade8bb58b2ab9d3bd8b06b7622e3c4fd0eb27f1c19a9f538d999b
[root@clinet ~]#
注意:在commit的时候基础的centos:7的容器 不可用关闭,制作完成之后可以关闭。
Step8: 通过openssh:v1.0镜像启动容器
[root@clinet ~]# docker run -d opensssh_v1.0
48ba4cca55569261ce73700af779c0f48eab87e2964942958042aaf51c83072c
[root@clinet ~]#
我们可以看到后台启动的容器是退出状态的,这是为什么呢?我们稍后解释
再次启动容器:
[root@clinet ~]# docker run -d opensssh_v1.0 /usr/sbin/sshd -D
6f5f1dfae9f2af788082dac13980cd448763a623ac86dd6956a1a6247b79cc33
[root@clinet ~]#
Step9:宿主机远程连接
登录成功:
1.4 容器为什么会退出?
前面我们说过一个容器能否正常在后台运行,主要是看容器内部是否有进程在前台运行,那为什么我们在容器制作的时候已经执行了/usr/sbin/sshd -D在容器内前台运行,在制作之后启动的容器却还是退出了呢?首先我们启动一个openssh:v1的容器,登入容器查看进程如下:
我们看的pid=1的进程是/bin/bash.
当我们传入cmd参数之后,在启动openssh:v1.0,查看的如下:
此时查看到的容器pid=1的进程就是/usr/sbin/sshd -D。所有综上所述,一个容器是否能在后台正常运行,需要容器内有进程在前台运行,且该前台运行的进程的pid为1.
关于镜像制作我们简单介绍了一下docker commit命令,但是我们在实际工作中主要用的还是dockerfile,关于dockerfile相关的内容,会在后面几个章节中详细说明。