获取镜像:

docker pull [选项] [Docker Registry地址]<仓库名>:<标签>						

Docker Registry地址:  地址的格式一般是 <域名/IP>[:端口号] 。默认地址是 Docker Hub。

仓库名:如之前所说,这里的仓库名是两段式名称,既<用户名>/<软件名> 。 对于 Docker Hub,如果不给出用户名,则默认为library,也就是官方镜像。


例如:

docker pull redis

默认是拉取最新版本的ubuntu镜像,也可以用TAG来拉取指定版本的镜像,例如:

docker pull redis:3.2


查看本地镜像

docker images
dockerREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
redis                     3.2                 e97b1f10d81a        4 weeks ago         99.7MB
ubuntu                    latest              452a96d81c30        5 weeks ago         79.6MB

第一个字段是指镜像来自于哪个仓库,

TAG:标签信息,通常用版本来定义

IMAGE ID:镜像唯一ID号

CREATED:镜像创建时间

SIZE:镜像大小



搜索镜像:默认是从官方的源中搜索镜像信息

docker search TERM

例如:

 ~ docker search mysql
dockerNAME                                                   DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql                                                  MySQL is a widely used, open-source relation…   6327                [OK]                
mariadb                                                MariaDB is a community-developed fork of MyS…   1987                [OK]                
mysql/mysql-server                                     Optimized MySQL Server Docker images. Create…   453                                     [OK]
percona                                                Percona Server is a fork of the MySQL relati…   342                 [OK]                
zabbix/zabbix-server-mysql                             Zabbix Server with MySQL database support       99                                      [OK]
hypriot/rpi-mysql                                      RPi-compatible Docker Image with Mysql          85                                      
centurylink/mysql                                      Image containing mysql. Optimized to be link…   60                                      [OK]
zabbix/zabbix-web-nginx-mysql                          Zabbix frontend based on Nginx web-server wi…   52                                      [OK]
1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5   ubuntu-16-nginx-php-phpmyadmin-mysql-5          35                                      [OK]
tutum/mysql                                            Base docker image to run a MySQL database se…   32                                      
centos/mysql-57-centos7                                MySQL 5.7 SQL database server                   28                                      
mysql/mysql-cluster                                    Experimental MySQL Cluster Docker images. Cr…   25                                      
schickling/mysql-backup-s3                             Backup MySQL to S3 (supports periodic backup…   19                                      [OK]
bitnami/mysql                                          Bitnami MySQL Docker Image                      15                                      [OK]
linuxserver/mysql                                      A Mysql container, brought to you by LinuxSe…   14                                      
zabbix/zabbix-proxy-mysql                              Zabbix proxy with MySQL database support        13                                      [OK]
centos/mysql-56-centos7                                MySQL 5.6 SQL database server                   8                                       
openshift/mysql-55-centos7                             DEPRECATED: A Centos7 based MySQL v5.5 image…   6                                       
circleci/mysql                                         MySQL is a widely used, open-source relation…   5                                       
dsteinkopf/backup-all-mysql                            backup all DBs in a mysql server                3                                       [OK]
mysql/mysql-router                                     MySQL Router provides transparent routing be…   2                                       
openzipkin/zipkin-mysql                                Mirror of https://quay.io/repository/openzip…   1                                       
cloudposse/mysql                                       Improved `mysql` service with support for `m…   0                                       [OK]
ansibleplaybookbundle/mysql-apb                        An APB which deploys RHSCL MySQL                0                                       [OK]
cloudfoundry/cf-mysql-ci                               Image used in CI of cf-mysql-release            0

星级越高,排名越靠前,official字段为OK的,表示为官方镜像。


删除镜像

docker rmi IMAGE [IMAGE...]

参数:

-f:强制删除镜像,一般不建议这么做。


使用Tag删除镜像

删除一个或者多个镜像。IMAGE可以为镜像Tag或者镜像ID。例如

# docker rmi myip:v2
Untagged: myip:v2
Deleted: sha256:1faed945e9b83ac507736931bc5560dd560ac320f82a844d3bd8f864625c54c4

注意:当同一个镜像有多个标签时,docker rmi只会删除该镜像标签中的多个标签而已。并不影响镜像文件。当镜像只剩下一个标签时,此时删除镜像会彻底删除镜像。


使用镜像ID删除镜像

当使用镜像ID删除镜像时,会先尝试删除所有指向该镜像的标签,然后删除该镜像文件本身

但是,当镜像创建的容器存在时,需要先删除容器才能删除镜像,否则报错。

# docker rmi myip
Error response from daemon: conflict: unable to remove repository reference "myip" (must force) - container 2990105ab563 is using its referenced image b84408411f93

使用docker ps -a查看所有容器

# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                   PORTS               NAMES
6306512c14f0        ubuntu:latest       "bash"                   3 hours ago         Exited (0) 3 hours ago                       loving_engelbart
cab48a8a6d10        myip                "bash"                   3 hours ago         Exited (0) 3 hours ago                       vibrant_bohr
0262d2bc48b4        myip                "-i"                     3 hours ago         Created                                      inspiring_brattain
2990105ab563        myip                "curl -s http://ip.cn"   3 hours ago         Exited (0) 3 hours ago                       xenodochial_lamport

使用docker rm 删除容器

 #docker rm 0262d2bc48b4 2990105ab563 
cab48a8a6d10
0262d2bc48b4
2990105ab563

删除镜像:

# docker rmi myip
Untagged: myip:latest
Deleted: sha256:b84408411f933b1603328fc584a98b1c847d74a10908ae79adedb4c88cb83f35
Deleted: sha256:a45349740712b04c4b87f75bb9ee998cdff10f309f88f52771a295bd0185cbb4
Deleted: sha256:43d1aec07e38576af5b4eb906c0e62c389cf6bad63d50ed22db5faa985fa9f4f
Deleted: sha256:0eb9547c59e758021c6ec4e519574ef615d89c6711333f06a80b957760ec5c8e
Deleted: sha256:db2a6ad5636f2fb7f392af22fc561d808da37d5e47b97cebe0a568f740fed138


存出和载入镜像:

存出镜像:

docker  save -o image_name IMAGE:TAG

用户可以使用docker save将本地的镜像存出,然后分享给他人,例如:

# docker save -o ubuntu_14.04.tar ubuntu:14.04
[root@OPS01-LINTEST02 ~]# ls
ubuntu_14.04.tar


载入镜像:

docker load --inpput image_name 
或者
docker load < image_name


上传镜像

用户可以使用docker push命令上传镜像,默认是上传到官方Dock Hub仓库(需要注册账号)。

例如:用户user上传本地的test:latest的镜像使用以下命令

docker push user/test:latest


使用镜像启动一个容器

docker run -it --rm ubuntu bash
  • -it:这是两个参数,

  • -i:交互式操作,-t:表示这是个终端

  • --rm:容器退出后随即将其删除,默认情况下,退出的容器不会随即删除,除非手动docker rm,我们这里只是随便 执行个命令,看看结果,不需要排障和保留结果,因此使用 --rm 可以避免 浪费空间。


查看本机上存在的容器

 docker ps -a
dockerCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
3b00082711a9        ubuntu              "/bin/bash"         21 hours ago        Exited (255) 20 hours ago                       nostalgic_minsky
969a66036c68        ubuntu              "/bin/bash"         21 hours ago        Exited (127) 21 hours ago                       epic_banach

 


虚悬镜像

<none>           <none>      00285df0df87        5 d
ays ago          342 MB

上面的镜像列表中,还可以看到一个特殊的镜像,这个镜像既没有仓库名,也没有标签,均为 <none>,

这类镜像叫做虚悬镜像

这个镜像原本是有镜像名和标签的,原来为 ,随着官方镜像维护,发 布了新版本后,重新 时, 这个镜像名被 转移到了新下载的镜像身上,而旧的镜像上的这个名称则被取消,从而成为了

<none> 。除了 docker pull 可能导致这种情况, docker build 也同样可 以导致这种现象。由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签 均为 <none> 的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image) ,可 以用下面的命令专门显示这类镜像

 docker images -f dangling=true					
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              00285df0df87        5 days ago          342 MB		

一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除。

 $ docker rmi $(docker images -q -f dangling=true)


列出包括中间层在内的所有镜像:

docker images -a


列出部分(指定)镜像:

docker iamges ubuntu


过滤镜像:--filter 或 -f

例如:查看nginx之后建立的镜像

# docker images -f since=nginx
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              14.04               578c3e61a98c        6 days ago          223MB


查看nginx之前建立的镜像

# docker images -f before=nginx:latest
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              7                   49f7960eb7e4        7 days ago          200MB
centos              latest              49f7960eb7e4        7 days ago          200MB
centos              6                   70b5d81549ec        2 months ago        195MB


定制表格的输出格式,这是使用了GO的语法:https://gohugo.io/templates/introduction/

# docker images --format "{{.ID}}: {{.Repository}}"
578c3e61a98c: ubuntu
cd5239a0906a: nginx
49f7960eb7e4: centos
49f7960eb7e4: centos
70b5d81549ec: centos


以表格等距显示

# docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID            REPOSITORY          TAG
578c3e61a98c        ubuntu              14.04
cd5239a0906a        nginx               latest
49f7960eb7e4        centos              7
49f7960eb7e4        centos              latest
70b5d81549ec        centos              6



利用commit理解镜像构成

我们用nginx镜像启动一个webserver

docker run --name webserver -d -p 80:80 nginx

run=create容器 + start容器

这条命令会用nginx容器启动一个容器,名字为webserver,并映射了80端口,我们可以通过访问http://localhost来访问这个站点,

image.png



假设我们不喜欢这个页面要改成我们定制的页面,执行下面的命令,

 docker exec -it webserver bash

 我们以交互式终端方式进入 webserver 容器,并执行了 bash 命令,也就是获 得一个可操作的 Shell。

然后修改了nginx的index页面,并退出

#echo '<h1>Hello, Docker!</h1>' >/usr/share/nginx/html/index.
#exit

再次访问nginx的站点

image.png





我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过 docker diff 命令看到具体的改动。

# docker diff webserver
C /run
A /run/nginx.pid
C /usr
C /usr/share
C /usr/share/nginx
C /usr/share/nginx/html
C /usr/share/nginx/html/index.html
C /var
C /var/cache
C /var/cache/nginx
A /var/cache/nginx/client_temp
A /var/cache/nginx/fastcgi_temp
A /var/cache/nginx/proxy_temp
A /var/cache/nginx/scgi_temp
A /var/cache/nginx/uwsgi_temp
C /root
A /root/.bash_history


当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修 改都会被记录于容器存储层里。

而 Docker 提供了一个 docker commit 命令,可以将容器的存储层保存下来成为镜像。

换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。

以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。


 docker commit 的语法格式为:

 docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

参数:

  • -a, --author="":指定作者

  • -m, --message="": 记录修改的内容

  • -c, --change=[ ]:提交的时候执行Dockfile指令,包括 CMD | ENTRYPOINT | ENV | EXPOSE | LABLE | ONBUILD | USER | VOLUME | WORKDIR等

  • -p, --pause=true:提交时暂停容器运行


这里我们使用下面的命令来保存镜像

# docker commit --author "cpzeng <451345726@qq.com>"  --message "修改了index页面" webserver nginx:v2 
sha256:f270f6bb87140e2d9b84566b75d1b45443d9a7b3aba981ec414f24f38cdae7fb



查看nginx镜像

# docker images nginx
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
nginx               v2                  f270f6bb8714        About a minute ago   109MB
nginx               latest              cd5239a0906a        6 days ago           109MB


使用docker history 查看修改历史,可以看到新增了我们修改的这一层,验证了docker是分层存储的说法

# docker history nginx:v2
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
f270f6bb8714        2 minutes ago       nginx -g daemon off;                            97B                 修改了index页面
cd5239a0906a        6 days ago          /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B                  
<missing>           6 days ago          /bin/sh -c #(nop)  STOPSIGNAL [SIGTERM]         0B                  
<missing>           6 days ago          /bin/sh -c #(nop)  EXPOSE 80/tcp                0B                  
<missing>           6 days ago          /bin/sh -c ln -sf /dev/stdout /var/log/nginx…   0B                  
<missing>           6 days ago          /bin/sh -c set -x  && apt-get update  && apt…   53.7MB              
<missing>           6 days ago          /bin/sh -c #(nop)  ENV NJS_VERSION=1.15.0.0.…   0B                  
<missing>           6 days ago          /bin/sh -c #(nop)  ENV NGINX_VERSION=1.15.0-…   0B                  
<missing>           6 weeks ago         /bin/sh -c #(nop)  LABEL maintainer=NGINX Do…   0B                  
<missing>           6 weeks ago         /bin/sh -c #(nop)  CMD ["bash"]                 0B                  
<missing>           6 weeks ago         /bin/sh -c #(nop) ADD file:ec5be7eec56a74975…   55.3MB


慎用docker commit


使用 docker commit 命令虽然可以比较直观的帮助理解镜像分层存储的概念, 但是实际环境中并不会这样使用。

首先,如果仔细观察之前的docker diff webserver的结果,你会发现除了真正想要修改的/usr/share/nginx/html/index.html文件外,由于命令的执行,还有很多文件被改动或添加了。这还仅仅是最简单的操作,如果是安装软件包、编译构建,那会有大量的无关内容被添加进来,如果不小心清理,将会导致镜 像极为臃肿。

此外,使用 docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑箱镜像,换句话说,就是除了制作镜像的人知道执行过什么命令,怎么生成的镜像,别人根本无从得知。而且,即使是这个制作镜像的人,过一段时间 后也无法记清具体在操作的。虽然 docker diff 或许可以告诉得到一些线索, 但是远远不到可以确保生成一致镜像的地步。这种黑箱镜像的维护工作是非常痛苦 的。

而且,回顾之前提及的镜像所使用的分层存储的概念,除当前层外,之前的每一层 都是不会发生改变的,换句话说,任何修改的结果仅仅是在当前层进行标记、添 加、修改,而不会改动上一层。如果使用 docker commit 制作镜像,以及后期 修改的话,每一次修改都会让镜像更加臃肿一次,所删除的上一层的东西并不会丢 失,会一直如影随形的跟着这个镜像,即使根本无法访问到TM。这会让镜像更加臃 肿。

docker commit 命令除了学习之外,还有一些特殊的应用场合,比如被***后保 存现场等。但是,不要使用 docker commit 定制镜像,定制行为应该使用Dockerfile 来完成。


使用dockerfile定制镜像

从刚才的 docker commit 的学习中,我们可以了解到,镜像的定制实际上就是 定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作 的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复 的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令 构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

还以之前定制 nginx 镜像为例,这次我们使用 Dockerfile 来定制。 在一个空白目录中,建立一个文本文件,并命名为 Dockerfile

#mkdir mynginx

# cd mynginx/

# vim Dockerfile

其内容为

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

FROM:指定基础镜像,FROM为必备指令,并且必须为第一条指令

除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch 。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。

RUN:该指令用来执行命令行命令,是常用的指令之一。格式:

shell格式:RUN <command>

例如:

RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html


exec格式:RUN ["可执行文件", "参数1", "参数2"]


注意:每一个RUN都会在原有的镜像基础上新建立一层,所以不要每一个命令使用一个RUN,因为这会产生非常臃肿、非常多层的镜像,不仅仅增加了构建时间,而且容易出错。

nion FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是 不得超过 127 层

多个命令的dockerfile可以这样写

image.png

这里为了格式化还进行了换行。Dockerfile 支持 Shell 类的行尾添加 \ 的 命令换行方式,以及行首 # 进行注释的格式。

良好的格式,比如换行、缩进、注 释等,会让维护、排障更为容易,这是一个比较好的习惯。此外,还可以看到这一组命令的最后添加了清理工作的命令,删除了为了编译构建 所需要的软件,清理了所有下载、展开的文件,

并且还清理了 apt 缓存文件。这是很重要的一步,我们之前说过,镜像是多层存储,每一层的东西并不会在下一层 被删除,会一直跟随着镜像。因此镜像构建时,一定要确保每一层只添加真正需要 添加的东西,任何无关的东西都应该清理掉


构建之前的nginx镜像

[root@OPS01-LINTEST02 mynginx]# pwd
/root/mynginx
[root@OPS01-LINTEST02 mynginx]# ls
Dockerfile
# docker build -t nginx:v3 .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM nginx
 ---> cd5239a0906a
Step 2/2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Running in 2d5502331097
Removing intermediate container 2d5502331097
 ---> ea06a30dbec1
Successfully built ea06a30dbec1
Successfully tagged nginx:v3


可以看到,先启动一个容器,然后执行命令,完成后删除了容器,可以看到目前有以下镜像

# docker images nginx
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v3                  ea06a30dbec1        2 minutes ago       109MB
nginx               v2                  f270f6bb8714        42 minutes ago      109MB
nginx               latest              cd5239a0906a        6 days ago          109MB


docker构建上下文

上面的命令

docker build -t nginx:v3 .

这个点表示当前目录,而dockerfile就在当前目录。这个点其实是在指定上下文路径。

注意:如果把当前目录当成上下文路径,则写一个点,如果不是当前目录,在使用完整路径或者相对路径代替,但这个路径一定不能少



还可以使用完整路径这样写:

docker build -t nginx:v7 -f /root/mynginx/test /root/mynginx

/root/mynginx 是指上下文路径, /root/mynginx/test是指dockerfile的文件名


下面是官网的例子

$ docker build -f Dockerfile.debug .

This will use a file called Dockerfile.debug for the build instructions instead of Dockerfile.

$ curl example.com/remote/Dockerfile | docker build -f - .

The above command will use the current directory as the build context and read a Dockerfile from stdin.

$ docker build -f dockerfiles/Dockerfile.debug -t myapp_debug .$ docker build -f dockerfiles/Dockerfile.prod  -t myapp_prod .

The above commands will build the current build context (as specified by the .) twice, once using a debug version of a Dockerfileand once using a production version.

$ cd /home/me/myapp/some/dir/really/deep$ docker build -f /home/me/myapp/dockerfiles/debug /home/me/myapp$ docker build -f ../../../../dockerfiles/debug /home/me/myapp

These two docker build commands do the exact same thing. They both use the contents of the debug file instead of looking for a Dockerfile and will use /home/me/myapp as the root of the build context. Note that debug is in the directory structure of the build context, regardless of how you refer to it on the command line.


官网参考连接:https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f