前言
本文主要对Docker的三大组件镜像、容器、仓库基础『常用』命令进行整理。
依据命令的用途对其进行分类(来源:《Docker:容器与容器云(第2版)》):
从docker命令使用出发,梳理出如图所示的命令结构图:
一、Docker镜像
操作系统分为 内核 和 用户空间。对于 Linux
而言,内核启动后,会挂载 root
文件系统为其提供用户空间支持。而 Docker 镜像(Image
),就相当于是一个 root
文件系统。比如官方镜像 ubuntu:18.04
就包含了完整的一套 Ubuntu 18.04 最小系统的 root
文件系统。
Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。
1、从仓库获取镜像
从 Docker 镜像仓库获取镜像的命令是 docker pull
。其命令格式为:
$ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
通过 docker pull --help
命令来看一下具体的『选项』命令:
$ docker pull --help
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from a registry
Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
--platform string Set platform if server is multi-platform capable
-q, --quiet Suppress verbose output
示例:
# 从官方仓库获取ubuntu18.04的镜像
$ docker pull ubuntu:18.04
# 从网易镜像仓库获取mysql最新版本镜像
$ docker pull hub.c.163.com/library/mysql:latest
2、列出镜像
要想列出本地已经下载下来的镜像,可以使用 docker image ls
或 docker images
命令。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 5f515359c7f8 5 days ago 183 MB
nginx latest 05a60462f8ba 5 days ago 181 MB
mongo 3.2 fe9198c04d62 5 days ago 342 MB
<none> <none> 00285df0df87 5 days ago 342 MB
ubuntu 18.04 329ed837d508 3 days ago 63.3MB
ubuntu bionic 329ed837d508 3 days ago 63.3MB
列表包含了 仓库名
、标签
、镜像 ID
、创建时间
以及 所占用的空间
。
镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个 标签。因此,在上面的例子中,可以看到 ubuntu:18.04
和 ubuntu:bionic
拥有相同的 ID,因为它们对应的是同一个镜像。
镜像体积
仔细观察,注意到, docker images
这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同。比如,ubuntu:18.04
镜像大小,在这里是 63.3MB
,但是在 Docker Hub 显示的却是 25.47 MB
。
因为仓库中的镜像是压缩过的,在上传和下载过程中都是保持压缩状态,节省网络传输流量。
而本地通过 docker images
看到的是展开后的体积。
虚悬镜像
docker images
列出来的镜像,发现有一个特殊的镜像,这个镜像既没有仓库名,也没有标签,均为 <none>
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 00285df0df87 5 days ago 342 MB
这个镜像原本是有镜像名和标签的,原来为 mongo:3.2
,随着官方镜像维护,发布了新版本后,重新 docker pull mongo:3.2
时,mongo:3.2
这个镜像名被转移到了新下载的镜像身上,而旧的镜像上的这个名称则被取消,从而成为了 <none>
。除了 docker pull
可能导致这种情况,docker build
也同样可以导致这种现象。
由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 <none>
的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image) ,可以用下面的命令专门显示这类镜像:
$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 00285df0df87 5 days ago 342 MB
一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除。
$ docker image prune
中间层镜像
为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像。列出中间层镜像:
$ docker image ls -a
这样会看到很多无标签的镜像,与之前的虚悬镜像不同,这些无标签的镜像很多都是中间层镜像,是其它镜像所依赖的镜像。
不应该删除,被其他镜像所依赖;不用管,删除依赖对象后会连带删除。
列出部分镜像
根据仓库名列出镜像:
$ docker images ubuntu
指定仓库名和标签
$ docker images ubuntu:18.04
过滤器参数 --filter
,简写 -f
,示例:
# 列出虚悬镜像
$ docker images -f dangling=true
# mongo:3.2之后建立的镜像
$ docker images -f since=mongo:3.2
# mongo:3.2之前建立的镜像
$ docker images -f before=mongo:3.2
# 通过lable过滤
$ docker images -f label=com.example.version=0.1
以特定格式显示
仅列出ID列,-q
参数
$ docker images -q
另外一些时候,我们可能只是对表格的结构不满意,希望自己组织列;或者不希望有标题,这样方便其它程序解析结果等,这就用到了 Go 的模板语法。
$ docker image ls --format "{{.ID}}: {{.Repository}}"
5f515359c7f8: redis
05a60462f8ba: nginx
fe9198c04d62: mongo
00285df0df87: <none>
329ed837d508: ubuntu
329ed837d508: ubuntu
$ docker image ls --format "table {{.ID}} {{.Repository}} {{.Tag}}"
IMAGE ID REPOSITORY TAG
5f515359c7f8 redis latest
05a60462f8ba nginx latest
fe9198c04d62 mongo 3.2
00285df0df87 <none> <none>
329ed837d508 ubuntu 18.04
329ed837d508 ubuntu bionic
3、删除镜像
要删除本地的镜像,可以使用 docker image rm
命令,其格式为:
$ docker image rm [选项] <镜像1> [<镜像2> ...]
其中,<镜像>
可以是 镜像短 ID
、镜像长 ID
、镜像名
或者 镜像摘要
。
示例:比如我们有如下镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 0584b3d2cf6d 3 weeks ago 196.5 MB
redis alpine 501ad78535f0 3 weeks ago 21.03 MB
docker latest cf693ec9b5c7 3 weeks ago 105.1 MB
nginx latest e43d811ce2f4 5 weeks ago 181.5 MB
删除
# 长ID
$ docker image rm 501ad78535f0
# 短ID,即只输入部分ID 一般取前3个字符以上,只要足够区分于别的镜像就可以了。
$ docker image rm 501
# 镜像名删除
$ docker image rm centos
# 镜像摘要删除
$ docker images --digests
$ docker image rm node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228
# 用docker images命令配合
$ docker image rm $(docker images -q redis)
# 删除mongo:3.2之前创建的镜像
$ docker image rm $(docker images -q -f before=mongo:3.2)
4、构建镜像
链接(下篇整理通过Dockerfile构建镜像)--待完善
二、Docker容器
简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
1、启动容器
新建启动
$ docker run ubuntu:18.04 /bin/echo 'Hello world'
启动一个 bash 终端,允许用户进行交互.其中,-t
选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i
则让容器的标准输入保持打开。
$ docker run -t -i ubuntu:18.04 /bin/bash
当利用 docker run
来创建容器时,Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从 registry 下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
启动已终止容器
可以利用 docker container start
命令,直接将一个已经终止(exited
)的容器启动运行。
$ docker container start b9198ea30925
容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。可以在伪终端中利用 ps
或 top
来查看进程信息。
root@ba267838cc1b:/# ps
PID TTY TIME CMD
1 ? 00:00:00 bash
11 ? 00:00:00 ps
可见,容器中仅运行了指定的 bash 应用。这种特点使得 Docker 对资源的利用率极高,是货真价实的轻量级虚拟化。
2、后台运行
使用 -d
参数运行容器。
$ docker run -d ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a
此时容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面(输出结果可以用 docker logs
查看)。
$ docker logs 77b
查看容器信息
# 查看正在运行的容器
$ docker container ls
$ docker ps
# 查看所有运行过的容器
$ docker ps -a
3、终止容器
可以使用 docker container stop
或者 docker stop
来终止一个运行中的容器。
处于终止状态的容器,可以通过 docker container start
命令来重新启动。
此外,docker container restart
命令会将一个运行态的容器终止,然后再重新启动它。
4、进入容器
在使用 -d
参数时,容器启动后会进入后台。需要进入容器进行操作,包括使用 docker attach
命令或 docker exec
命令,推荐使用 docker exec
命令。
attach命令
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
218a71b508bf base:v1 "/bin/bash" 2 months ago Up 6 seconds 0.0.0.0:2333->22/tcp, :::2333->22/tcp distracted_robinson
$ docker attach 218
[root@218a71b508bf /]# ls
bin data dev etc home lib lib64 media mnt nas opt proc root run sbin srv sys tmp Users usr var
[root@218a71b508bf /]#
注意: 如果从这个 stdin 中 exit,会导致容器的停止。
exec命令
docker exec
后边可以跟多个参数,这里主要说明 -i
-t
参数。
只用 -i
参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。
当 -i
-t
参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。
$ docker exec -i 218a bash
ls
bin
data
dev
etc
home
lib
lib64
media
mnt
nas
opt
proc
root
run
sbin
srv
sys
tmp
Users
usr
var
exit
$ docker exec -it 218a bash
[root@218a71b508bf /]# ls
8e13963c663a4bfe9fe4b873ffe35d47-6696_decode.py_ anaconda-post.log bin data dev etc home lib lib64 media mnt nas opt proc root run sbin srv sys tmp Users usr var
[root@218a71b508bf /]#
如果从这个 stdin 中 exit,不会导致容器的停止。这就是为什么推荐使用 docker exec
的原因。
5、导入和导出容器
导出容器
导出本地某个容器,可以使用 docker export
命令。
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7691a814370e ubuntu:18.04 "/bin/bash" 36 hours ago Exited (0) 21 hours ago test
$ docker export 7691a814370e > ubuntu.tar
这样将导出容器快照到本地文件。
导入容器
使用 docker import
从容器快照文件中再导入为镜像,例如:
$ cat ubuntu.tar | docker import - test/ubuntu:v1.0
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test/ubuntu v1.0 9d37a6082e97 About a minute ago 171.3 MB
此外,也可以通过指定 URL 或者某个目录来导入,例如:
$ docker import http://example.com/exampleimage.tgz example/imagerepo
注:用户既可以使用 docker load
来导入镜像存储文件到本地镜像库,也可以使用 docker import
来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
6、删除容器
使用 docker container rm
来删除一个处于终止状态的容器。例如:
$ docker container rm mysql
mysql
如果要删除一个运行中的容器,可以添加 -f
参数。Docker 会发送 SIGKILL
信号给容器。
$ docker container rm -f mysql
清除所有终止状态的容器
$ docker container prune
三、Docker仓库
仓库(Repository
)是集中存放镜像的地方。
一个容易混淆的概念是注册服务器(Registry
)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 docker.io/ubuntu
来说,docker.io
是注册服务器地址,ubuntu
是仓库名。
大部分时候,并不需要严格区分这两者的概念。
1、Docker Hub
目前 Docker 官方维护了一个公共仓库 Docker Hub (opens new window),其中已经包括了数量超过 8,250,000 (opens new window)的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
注册
登录
可以通过执行 docker login
命令交互式的输入用户名及密码来完成在命令行界面登录 Docker Hub。
通过 docker logout
退出登录。
拉取镜像
以通过 docker search
命令来查找官方仓库中的镜像,并利用 docker pull
命令来将它下载到本地。
例如以 centos
为关键词进行搜索:
$ docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 6449 [OK]
ansible/centos7-ansible Ansible on Centos7 132 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC session… 126 [OK]
jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 117 [OK]
centos/systemd systemd enabled base container. 96 [OK]
推送镜像
用户也可以在登录后通过 docker push
命令来将自己的镜像推送到 Docker Hub。
以下命令中的 username
请替换为你的 Docker 账号用户名。
$ docker tag ubuntu:18.04 username/ubuntu:18.04
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 275d79972a86 6 days ago 94.6MB
username/ubuntu 18.04 275d79972a86 6 days ago 94.6MB
$ docker push username/ubuntu:18.04
$ docker search username
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
username/ubuntu
2、私有仓库
链接(下篇整理通过搭建私有仓库)--待完善