Docker技术入门之---Docker核心概念:镜像、容器、仓库(2)

  Docker的大部分操作都围绕着它的三大核心概念——镜像、容器和仓库而展开。因此,准确把握这三大核心概念对于掌握Docker技术尤为重要 。

 

docker命令结构图

根据命令用途本身对其进行了分类,帮助初学者尽快掌握Docker命令,如下图:

Docker子命令分类
子命令分类 子命令
Docker环境信息 info、version
容器生命周期管理 create、exec、kill、pause、restart、rm、run、start、stop、unpause
镜像仓库命令 login、logout、pull、push、search
镜像管理 build、images、import、load、rmi、save、tag、commit
容器运维操作 attach、export、inspect、port、ps、rename、stats、top、wait、cp、diff、update
容器资源管理 volume、network
系统日志信息 events、history、logs

1.Docker镜像

  Docker镜像类似于虚拟机镜像,可以将它理解为一个只读的模板。 镜像是创建Docker容器的基础。通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并直接使用。

  Docker运行容器前需要本地存在对应的镜像,如果镜像没保存在本地,Docker会尝试先从默认镜像仓库下载(默认使用Docker Hub公共注册服务器中的仓库),用户也可以通过配置,使用自定义的镜像仓库 。

 获取镜像

  使用docker pull命令直接从Docker Hub镜像源来下载镜像。

    该命令格式为docker pull NAME[:TAG],NAME是镜像仓库的名称,TAG是镜像的标签(通常表示版本信息)。

  pull子命令支持的选项主要包括:

  -a,--all-tags=true|false:是否获取仓库中的所有镜像,默认为否。

  注意:如果不显示指定TAG,则默认会选择latest标签,会下载仓库中最新版的镜像,但是latest通常是不稳定版本。生产环境最好指定TAG,下载稳定版本。

  大家可能有疑问,在使用不通的镜像仓库服务器的情况下,可能会出现镜像重名的情况。严格的讲,镜像的仓库名称还应该添加仓库地址(即registry,注册服务器)作为前缀,只是我们默认使用的是Docker Hub服务,该前缀可以忽略。

  例如:docker pull ubuntu:14.04命令相当于docker pull registry.hub.docker.com/ubuntu:14.04

  下载镜像到本地后,即可随时使用该镜像了,例如利用该镜像创建一个容器,在其中运行bash应用,执行ping localhost命令:

# docker run -it ubuntu:14.04 bash
root@9c74026df12a:/# ping localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.023 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.018 ms
root@9c74026df12a:/# exit
exit 

 查看镜像信息

  使用docker images命令列出镜像

  images子命令主要支持如下选项,用户可以自行进行尝试。

  -a --all=true|false:列出所有的镜像文件(包括临时文件),默认为否

  --digests=true|false:列出镜像的数字摘要值,默认为否

  -f --filter=[]:过滤列出的镜像,如dangling=true只显示没有被使用的镜像;也可指定带有特定标注的镜像等

  --format="TEMPLATE":控制输出格式

  --no-trunc=true|false:对输出结果中太长的部分是否进行截断,如镜像ID信息,默认为是

  -q,--quiet=true|false:仅输出 ID信息,默认为否

  更多子命令选项还可以通过man docker -images来查看

使用tag命令添加镜像标签
  为了方便在后续工作中使用特定镜像,还可以使用docker tag命令来为本地镜像任意添加新的标签。

  例如:添加一个新的myubuntu:latest镜像标签

# docker tag ubuntu:latest myubuntu:latest 

使用inspect命令查看详细信息

  使用docker inspect命令可以获取该镜像的详细信息,包括制作者、适应架构、各层的数字摘要等

 使用history命令查看镜像历史

  注意过长的命令被自动截断了,可以使用前面提到的-- no-trunc选项来输出完整命令

搜寻镜像

  使用docker search命令可以搜索远端仓库中␀享的镜像,默认搜索官方仓库中的镜像。用法为docker search TERM,支持的参数主要包括:
  --automated=true|false:仅显示自动创建的镜像,默认为否;
  --no-trunc=true|false:输出信息不截断显示,默认为否;
  -s,--stars=X:指定仅显示评价为指定星级以上的镜像,默认为0,即输出所有镜像。

 删除镜像

  使用docker rmi命令可以删除镜像,命令格式为docker rmi IMAGE[IMAGE...],其中IMAGE可以为标签或ID

  a.使用标签删除镜像

# docker rmi myubuntu:latest
Untagged: myubuntu:latest 

   b.使用镜像ID删除镜像

  当使用docker rmi命令,并且后面跟上镜像的ID(也可以是能进行区分的部分ID串前缀)时,会先尝试删除所有指向该镜像的标签,然后删除该镜像文件本身 。

  例如:批量删除镜像

# docker images -q |xargs docker rmi
Untagged: nginx:latest
Untagged: nginx@sha256:48cbeee0cb0a3b5e885e36222f969e0a2f41819a68e07aeb6631ca7cb356fed1
Deleted: sha256:f68d6e55e06520f152403e6d96d0de5c9790a89b4cfc99f4626f68146fa1dbdc
Deleted: sha256:1b0c768769e2bb66e74a205317ba531473781a78b77feef8ea6fd7be7f4044e1
Deleted: sha256:34138fb60020a180e512485fb96fd42e286fb0d86cf1fa2506b11ff6b945b03f
Deleted: sha256:cf5b3c6798f77b1f78bf4e297b27cfa5b6caa982f04caeb5de7d13c255fd7a1e
Untagged: centos:centos7.6.1810
Untagged: centos@sha256:62d9e1c2daa91166139b51577fe4f4f6b4cc41a3a2c7fc36bd895e2a17a3e4e6
Deleted: sha256:f1cb7c7d58b73eac859c395882eec49d50651244e342cd6c68a5c7809785f427
Deleted: sha256:89169d87dbe2b72ba42bfbb3579c957322baca28e03a1e558076542a1c1b2b4a
Error response from daemon: conflict: unable to delete 9f38484d220f (must be forced) - image is being used by stopped container 9b7ac48aa846

  注意,当有该镜像创建的容器存在时,镜像文件默认是无法被删除的,需先删除依赖该镜像的所有容器,再来删除镜像。

]# docker images -q |xargs docker rmi
Error response from daemon: conflict: unable to delete 9f38484d220f (must be forced) - image is being used by stopped container 9b7ac48aa846

   通过docker ps -a 查看是由于容器id 为9b7ac48aa846在占用镜像,需要先删除容器,在删除镜像。

  批量删除容器可以使用

[root@ecs-smc-windows ~]# docker ps -qa|xargs docker rm 
9b7ac48aa84

   接下来在删除镜像就可以了。

  
创建镜像

  创建镜像的方法主要有三种:基于已有镜像的容器创建、基于本地模板导入、基于Dockerfile创建。

  本节将重点介绍前两种方法。最后一种基于Dockerfile创建的方法将在后续章节专门予以详细介绍 。

  a.基于已有镜像的容器创建

   该方法主要是使用docker commit命令。命令格式为docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 。

  主要选项包括;

  -a,--author="":作者信息;
  -c,--change=[]:提交的时候执行 Dockerfile指令,包括CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR等;
  -m,--message="":提交消息;
  -p,--pause=true:提交时暂停容器运行。

  例如:

  启动一个镜像,并在其中进行修改操作,例如创建一个test文件,之后退出:

$ docker run -it ubuntu:14.04 /bin/bash
root@a925cb40b3f0:/# touch test  
root@a925cb40b3f0:/# exit 

  记住容器的ID为a925cb40b3f0

  此时该容器跟原ubuntu:14.04镜像相比,已经发生了改变,可以使用docker commit命令来提交为一个新的镜像。提交时可以使用ID或名称来指定容器

# docker commit -m "Added a new file" -a "Docker Newbee" a925cb40b3f0 test:0.1
9e9c814023bcffc3e67e892a235afe61b02f66a947d2747f724bd317dda02f27 

  b.基于本地模板导入

  用户也可以直接从一个操作系统模板文件导入一个镜像,主要使用docker import命令。命令格式为docker import [OPTIONS] file|URL| - [REPOSITORY[:TAG]]

  例如,下载了ubuntu-14.04的模板压缩包,之后使用以下命令导入:  

# cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - ubuntu:14.04 

存出和载入镜像

  用户可以使用docker savedocker load命令来存出和载入镜像

  a.存出镜像

  如果要导出镜像到本地文件,可以使用docker save命令 。

  例如:导出本地的ubuntu:14.40镜像为文件ubuntu_14.04.tar,如下所示:  

$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 14.04 8f1bd21bd25c 2 weeks ago 188 MB
...
$ docker save -o ubuntu_14.04.tar ubuntu:14.04 

 之后,用户就可以通过复制ubuntu_14.04.tar文件将该镜像分享给他人 。

  b.载入镜像

  可以使用docker load将导出的tar文件再导入到本地镜像库,例如从文件ubuntu_14.04.tar导入镜像到本地镜像列表,如下所示:  

$ docker load --input ubuntu_14.04.tar

   或:

$ docker load < ubuntu_14.04.tar


2.Docker容器

  Docker容器类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。容器是从镜像创建的应用运行实例

  镜像自身是只读的。容器从镜像启动的时候,会在镜像的最上层创建一个可写层

新建容器

  可以使用docker create命令新建一个容器。

$ docker create -it ubuntu:latest
af8f4f922dafee22c8fe6cd2ae11d16e25087d61f1b1fa55b36e94db7ef45178
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
af8f4f922daf ubuntu:latest "/bin/bash" 17 seconds ago Created silly_euler

   使用docker create命令新建的容器处于停止状态,可以使用docker start命令来启动它。

新建并启动容器

  除了创建容器后通过start命令来启动,也可以直接新建并启动容器。所需要的命令主要为docker run,等价于先执行docker create命令,再执行dockerstart命令 。

$ docker run -it ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#

  这跟在本地直接执行/ bin/echo'hello world'几乎感觉不出任何区别 。
守护态运行

  更多的时候,需要让Docker容器在后台以守护态(Daemonized)形式运行。此时,可以通过添加- d参数来实现。

  例如下面的命令会在后台运行容器:

$ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
ce554267d7a4c34eefc92c5517051dc37b918b588736d0823e4c846596b04d83

   此时,要获取容器的输出信息,可以如下使用docker logs命令:

$ docker logs -t -f --tail ce5
hello world
hello world
hello world
. . .

-t:加入时间戳
-f:持续追加
--tail:最后10行

查看容器内运行的进程

  docker top <容器ID>

查看容器的详细信息

  docker inspect <容器ID>

终止容器

  可以使用docker stop来终止一个运行中的容器。该命令的格式为docker stop [-t|--time[=10]] [CONTAINER...]。

$ docker stop ce5
ce5

   注意Docker容器中指定的应用终结时,容器也会自动终止。

进入容器 

  当使用-d参数启动容器,容器会在后台运行,用户无法看到容器中的信息,也无法进行操作。

  这个时候要进入容器进行操作,有多种方法,包括官方提供的attach或exec命令,以及第三方的nesnter工具等。

  这里主要讲一下exec命令使用:

  命令格式:

docker exec [-d|--detach] [--detach-keys[=[]]] [-i|--interactive] [--privileged]
[-t|--tty] [-u|--user[=USER]] CONTAINER COMMAND [ARG...]。

   比较重要的参数有;

   -i,--interactive=true|false:打开标准输入接受用户输入命令,默认为false;
  --privileged=true|false:是否给执行命令以高权限,默认为false;
  -t,--tty=true|false:分配伪终端,默认为false;
    -u,--user="":执行命令的用户名或ID。  

  例如进入到刚创建的容器中,并启动一个bash。

$ docker exec -it 243c32535da7 /bin/bash
root@243c32535da7:/#

删除容器

  使用docker rm命令来删除处于终止或退出状态的容器,命令格式为docker rm [-f|--force] [-l|--link] [-v|--volumes] CONTAINER [CONTAINER...]

  主要支持的选项包括:
  -f,--force=false:是否强行终止并删除一个运行中的容器;
  -l,--link=false:删除容器的连接,但保留容器;
  -v,--volumes=false:删除容器挂载的数据卷。

导出容器

   导出容器是指导出一个已经创建的容器到一个文件,不管此时这个容器是否处于运行状态,可以使用docker export命令,该命令的格式为docker export [-o|--output[=""]] CONTAINER。其中,可以通过-o选项来指定导出的tar文件名,也可以直接通过重定向来实现 。
   首先查看所有的容器,如下所示:

$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce554267d7a4 ubuntu:latest "/bin/sh -c 'while t" 3 minutes ago
Exited (-1) 13 seconds ago determined_pike
d58050081fe3 ubuntu:latest "/bin/bash" About an hour ago
Exited (0) About an hour ago berserk_brattain
e812617b41f6 ubuntu:latest "echo 'hello! I am h" 2 hours ago
Exited (0) 3 minutes ago silly_leakey

 分别导出ce554267d7a4容器和e812617b41f6容器到文件test_for_run.tar文件和test_for_stop.tar文件:

$ docker export -o test_for_run.tar ce5
$ ls
test_for_run.tar
$ docker export e81 >test_for_stop.tar
$ ls
test_for_run.tar test_for_stop.tar

 之后,可将导出的tar文件传输到其他机器上,然后再通过导入命令导入到系统中,从而实现容器的迁移。

导入容器

  导出的文件又可以使用docker import命令导入变成镜像,该命令格式为:

docker import [-c|--change[=[]]] [-m|--message[=MESSAGE]] file|URL|-[REPOSITORY][:TAG]

   用户可以通过-c,-- change=[]选项在导入的同时执行对容器进行修改的Dockerfile指令 .

  下面将导出的test_for_run.tar文件导入到系统中:

$ docker import test_for_run.tar - test/ubuntu:v1.0
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test/ubuntu v1.0 9d37a6082e97 About a minute ago 171.3 MB

   上文介绍过使用docker load命令来导入一个镜像文件,docker import命令十分类似。
  实际上,既可以使用docker load命令来导入镜像存储文件到本地镜像库,也可以使用docker import命令来导入一个容器快照到本地镜像库。
  这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也更大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。

3.Docker仓库

  Docker仓库类似于代码仓库,它是Docker集中存放镜像文件的场所。

  有时候会看到有资料将Docker仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器是存放仓库的地方,其上往往存放着多个仓库。

不积跬步,无以至千里;不积小流,无以成江海。
原文地址:https://www.cnblogs.com/weidongliu/p/11156371.html