Docker是一种基于GO语言开发的轻量级的隔离软件。与虚拟机不同的是,Docker是直接运行在内核中的,不需要虚拟出一套硬件设备和操作系统,因此十分的轻便与快捷。
使用Docker主要解决的是开发、测试与生产环境的统一问题。
镜像(image):镜像是一种特殊的文件系统,提供了容器运行时所需的程序、库、资源、配置等文件,还为运行时准备的一些配置参数。镜像不包含任何动态数据,其内容在生成后也不会改变。
容器(container):容器可以视为镜像的实例,一个容器其实就是一个有着独立命名空间的独立进程,可以被启动、暂停、删除。容器也是Docker分层中的一层。容器在运行时,会以镜像作为基础层,同时创建一个对应的容器存储层。存储层的生命周期与容器同步,会在容器被删除时销毁。如果想让容器写入宿主机的数据,需要使用数据卷(Volume)。
仓库(repository):仓库是集中管理镜像的地方。类似于git仓库,不过管理的内容从代码文件变成了镜像。Docker有着默认的仓库Docker Hub,对应GitHub,其中有着许许多多的通用镜像,有针对语言的python、golang,针对场景的nginx、tomcat,针对操作系统的centos、ubuntu等等。
Docker的镜像并不是一个完整的文件系统,而是一组文件系统的集合,一个文件系统称为一层。一个层可以被多个其他层复用,这样可以大大减小镜像占用的空间。同时,每一层在是完全独立的,在构建完成之后就不会再被改变,每一层也无法对其它层进行操作。因此在构建镜像时,最好在一层构建完成之后删除无用文件,只保留构建时这一层需要的部分,这样可以大大缩减镜像大小。
镜像需要从仓库获取,使用的也是pull命令。如果不指定仓库地址(repository addr),则会从默认的Docker Hub获取镜像,对应的地址位docker.io。仓库名(repository name)由两部分组成,分别是用户名和软件名。如果不指定用户名,默认为library。tag相当于版本号,如果不指定tag,则会获取最新的版本。
docker pull [option] [repository_addr[:port]]/repository_name[:tag]
Docker Hub可以类比于GitHub,是官方维护的镜像仓库,可以在里面获取官方镜像,还可以推送自己的镜像。
docker search 可以通过名称在仓库中查找相关镜像,查找时可以通过–filter=stars=N筛选出收藏数大于N的镜像。随后可以通过docker pull 将镜像拉取到本地。
构建完成后可以通过docker push
运行一个镜像实际上就是基于该镜像创建一个容器并启动该容器,使用的命令为docker run,格式如下
docker run [option] $image
-i:交互式操作,常与-t一起使用。
-t:启动终端,常与-i一起使用。
–name:指定生成的容器名。
-d:使镜像后台运行。
-p:将主机端口与容器端口进行绑定。-p host_port:container_port。
–rm:退出时删除镜像,常用于测试。
–help:查看所有选项及其使用说明。
基本的查询语句为ls
docker image ls
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
查询结果包含以下几列,REPOSITORY-镜像名,TAG-镜像版本,IMAGE ID-镜像id。
p:只保留镜像id,可以与其他命令和选项结合使用批量对镜像进行操作。
-a:显示包含中间层在内的所有镜像,中间层通常不要操作。
镜像名:镜像名可以直接作为选项输出,此时会作为查询条件
-f:删选条件,详细请参考手册。
–format:指定打印的列,格式为–format “table {{.REPOSITORY}} \t {{.TAG}}”。table表示带首行标题。
此外还可以通过docker system df查看镜像占据的实际空间大小。由于docker会复用一些层,因此image占据的实际空间会比ls显示的空间小很多。
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 24 0 1.992GB 1.992GB (100%)
Containers 1 0 62.82MB 62.82MB (100%)
Local Volumes 9 0 652.2MB 652.2MB (100%)
Build Cache 0B 0B
与linux类似,删除使用rm命令
docker image rm [option] <$image1> [<$image2> <image3> ...]
如上述所示,rm可以同时删除多个镜像,并且可以接受其他命令的输出。rm可以通过指定image的id、名称等来删除镜像,只需要能够与其他镜像区分出即可。
删除分为两个阶段,分别是Untagged和Deleted。ID才是区分不同镜像的唯一标识,而一个ID可以派生出多个不同的镜像标签。Untagged就是删除这些标签的过程,在标签删除后,如果该image id还被其他标签或容器所使,那么该image便不会被删除。Deleted是实际删除一个镜像,只有当该镜像没有任何引用时才会自动执行。
在使用docker image ls之后,可能发现一些REPOSITORY和TAG均为none的镜像,这些镜像便被称为虚悬镜像。这种镜像可以理解为已经过期的镜像,如果一个TAG退出的新的版本,在TAG更新之后会被替换为一个新image id对应的镜像,此时原来的image id对应的镜像就会变成REPOSITORY和TAG均为none的虚悬镜像。
虚悬镜像通常已经没什么用了,建议清理。清理方式为
docker image prune
容器中的所有数据是会随着容器的销毁而被删除的,同时容器也无法直接与宿主机进行数据交互,数据卷(VOLUME)可以实现这些功能。
数据卷的功能包括:
实现容器之间的数据共享与通信
记录容器的操作
可以通过docker volume create 创建一个指定名称的数据卷,在创建完成之后可以通过docker volume ls查看创建的数据卷。在启动容器时,可以通过–mount source=
docker volume create <name>
docker volume ls
docker run --name web -itd --mount source=<volume_name>,target=/data/tools nginx
docker volume rm <name>
docker volume prune
除了使用数据卷,–mount命令还可以将本地目录或本地文件与容器中的目录或文件进行绑定。
docker run --name web -itd --mount type=bind,source=/data/tools,target=/data/tools nginx # 本地目录与容器目录绑定
docker run --name web -itd --mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history # 本地文件与容器文件绑定,可以实现bash操作记录的同步