Docker 镜像

个人学习笔记,谢绝转载!!!
原文:https://www.cnblogs.com/wshenjin/p/9323013.html


Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

因为镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像。

查看本地镜像

docker images

[root@docker-machine_192.168.31.129 ~]# docker images         
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              latest              88ec626ba223        5 weeks ago         199.7 MB
centos              7                   88ec626ba223        5 weeks ago         199.7 MB

各项目说明:

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签,默认latest
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • VIRTUAL SIZE:镜像大小

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如ubuntu仓库源里,有15.10、14.04等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。例如,运行一个centos7容器:

[root@docker-machine_192.168.31.129 ~]# docker run -t -i centos:7 /bin/bash 
[root@eb92e9fee2c6 /]# 

如上,如果不指定TAG,则默认使用latest。

搜索镜像

docker search

[root@docker-machine_192.168.31.129 ~]# docker search  nginx       
NAME                                                   DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                                                  Official build of Nginx.                        9029                [OK]       
jwilder/nginx-proxy                                    Automated Nginx reverse proxy for docker c...   1361                 [OK]
richarvey/nginx-php-fpm                                Container running Nginx + PHP-FPM capable ...   589                  [OK]
jrcs/letsencrypt-nginx-proxy-companion                 LetsEncrypt container to use with nginx as...   390                  [OK]
kong                                                   Open-source Microservice & API Management ...   204                [OK]       
webdevops/php-nginx                                    Nginx with PHP-FPM                              106                  [OK]

各项目说明:

NAME:镜像仓库源的名称

DESCRIPTION:镜像的描述

OFFICIAL:是否docker官方发布

获取镜像

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]:
  • Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。

  • 仓库名:仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。

    例如:

[root@docker-machine_192.168.31.129 ~]# docker pull training/webapp
latest: Pulling from training/webapp

e9e06b06e14c: Downloading [======>                                            ] 8.256 MB/65.77 MB
e9e06b06e14c: Download complete 
a82efea989f9: Download complete 
37bea4ee0c81: Download complete 
07f8e8c5e660: Download complete 
23f0158a1fbe: Download complete 
0a4852b23749: Download complete 
7d0ff9745632: Download complete 
99b0d955e85d: Download complete 
33e109f2ff13: Download complete 
cc06fd877d54: Download complete 
b1ae241d644a: Download complete 
b37deb56df95: Download complete 
02a8815912ca: Download complete 
Status: Downloaded newer image for training/webapp:latest

提交镜像

docker commit

如果没有满足我们需要的镜像时,我们可以自己制作镜像,也可以从已有的镜像中更新提交一个合适自己的镜像

更新镜像之前,先用centos7创建一个容器:

[root@docker-machine_192.168.31.129 ~]# docker run -t -i centos:7 /bin/bash 
[root@eb92e9fee2c6 /]# 

这时,我们已经进入了容器了

我们在容器内执行我们需要的操作,例如,新建一个admin用户:

[root@ba03649e5f96 /]# id admin 
id: admin: no such user
[root@ba03649e5f96 /]# useradd admin 
[root@ba03649e5f96 /]# id admin 
uid=1000(admin) gid=1000(admin) groups=1000(admin)

退出容器,用docker commit进行提交:

[root@docker-machine_192.168.31.129 ~]# docker commit -m="with a user named admin" -a="root" ba03649e5f96 centos:v7.1                
461de5c9b34eb31ef35047fff8038342a658ab1808ecf568904401570b84ce35

各项目说明:

  • -m:提交的描述信息

  • -a:指定镜像作者

  • ba03649e5f96:容器ID

  • centos:v7.1:指定要创建的目标镜像名

查看一下本地镜像:

[root@docker-machine_192.168.31.129 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              v7.1                461de5c9b34e        10 minutes ago      200 MB
centos              7                   88ec626ba223        6 weeks ago         199.7 MB
centos              latest              88ec626ba223        6 weeks ago         199.7 MB
training/webapp     latest              02a8815912ca        3 years ago         348.8 MB

使用新提交的镜像运行容器:

[root@docker-machine_192.168.31.129 ~]# docker run -t -i centos:v7.1 /bin/bash 
[root@7b4e7cd30e88 /]# id admin 
uid=1000(admin) gid=1000(admin) groups=1000(admin)

构建镜像

docker build

使用命令 docker build , 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像

找个空目录,新建一个Dockerfile 文件,我们让新建的镜像拥有admin用户:

FROM centos   
RUN useradd admin
CMD ["/bin/bash"]

Dockerfile 文件的命令及其具体含义这里先不解析

使用命令 docker build 来创建我们想要的镜像:

[root@docker-machine_192.168.31.129 docker]# ll
total 4
-rw-r--r-- 1 root root 49 Jul 17 19:28 Dockerfile
[root@docker-machine_192.168.31.129 docker]# docker build -t centos:v1 .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM centos
 ---> 88ec626ba223
Step 1 : RUN useradd admin
 ---> Running in a85096739c0f
 ---> c1020ec616a9
Removing intermediate container a85096739c0f
Step 2 : CMD /bin/bash
 ---> Running in 4fb1f7b019aa
 ---> f24c4c696e23
Removing intermediate container 4fb1f7b019aa
Successfully built f24c4c696e23
[root@docker-machine_192.168.31.129 docker]# 

命令末尾的 . 指明 build context 为当前目录。Docker 默认会从 build context 中查找 Dockerfile 文件,我们也可以通过 -f 参数指定 Dockerfile 的位置

上面的流程为:

  1. 从ID为88ec626ba223的centos 作为base镜像
  2. 执行RUN,添加admin用户
  3. 执行CMD
  4. 保存到镜像ID为f24c4c696e23

从上面的输出可以看出,从base镜像之后的每一步其实都是保存到临时容器中的,最后保存的镜像ID就是:Successfully built f24c4c696e23

让我们来看看本地的镜像:

[root@docker-machine_192.168.31.129 docker]# docker  images 
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              v1                  f24c4c696e23        6 minutes ago       200 MB
hello-world         latest              3535063d9957        6 days ago          1.848 kB
centos              7                   88ec626ba223        6 weeks ago         199.7 MB
centos              latest              88ec626ba223        6 weeks ago         199.7 MB
training/webapp     latest              02a8815912ca        3 years ago         348.8 MB

用新建的镜像来启动一个容器:

[root@docker-machine_192.168.31.129 docker]# docker run -i -t --rm centos:v1
[root@a52b97b4aac8 /]# id admin 
uid=1000(admin) gid=1000(admin) groups=1000(admin)
[root@a52b97b4aac8 /]# exit
exit
[root@docker-machine_192.168.31.129 docker]# 

新构建的镜像中有了admin用户了,这里docker run命令后面跟上--rm参数是为了使这个容器为临时容器,退出时自动被删除

在centos:v1的基础上再构建一个新镜像:

FROM centos:v1
RUN groupadd www
RUN useradd -g www,admin -s /sbin/nologin www
CMD ["/bin/bash"]
[root@docker-machine_192.168.31.129 docker]# docker build -t centos:v2 . 
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM centos:v1
 ---> f24c4c696e23
Step 1 : RUN groupadd www
 ---> Using cache
 ---> db90442b2ffb
Step 2 : RUN useradd -g www -s /sbin/nologin www
 ---> Running in a006bee63c63
 ---> c7c01f1b0dd2
Removing intermediate container a006bee63c63
Step 3 : CMD /bin/bash
 ---> Running in 37a9e708bd9a
 ---> ecf3512fa6e6
Removing intermediate container 37a9e708bd9a
Successfully built ecf3512fa6e6
[root@docker-machine_192.168.31.129 docker]# 

从上面的构建流程来看,centos:v2是在centos:v1的基础上进行构建的。这就是docker镜像的分层结构,具体这里先不说。

我们用history命令来查看一下centos:v2的构建过程:

[root@docker-machine_192.168.31.129 docker]# docker  history centos:v2
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
ecf3512fa6e6        2 minutes ago       /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B                 
c7c01f1b0dd2        2 minutes ago       /bin/sh -c useradd -g www -s /sbin/nologin ww   295.3 kB            
db90442b2ffb        2 minutes ago       /bin/sh -c groupadd www                         1.34 kB             
f24c4c696e23        15 minutes ago      /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B                 
c1020ec616a9        15 minutes ago      /bin/sh -c useradd admin                        296.2 kB            
88ec626ba223        6 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0 B                 
b298d692482d        6 weeks ago         /bin/sh -c #(nop)  LABEL org.label-schema.sch   0 B                 
29466d114cd8        6 weeks ago         /bin/sh -c #(nop) ADD file:8f4b3be0c1427b158f   199.7 MB      

从上面可以看出,centos:v2是在centos:v1的上面进行构建的

删除镜像

dockr rmi

删除镜像前,必须先删除由该镜像创建的容器,哪怕该容器没在运行,如下:

[root@docker-machine_192.168.31.129 docker]# docker  ps -a          
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
4b43371be7bd        centos:v2           "/bin/bash"         About a minute ago   Up About a minute                       ecstatic_wilson     
[root@docker-machine_192.168.31.129 docker]# docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              v2                  ecf3512fa6e6        7 minutes ago       200.3 MB
centos              v1                  f24c4c696e23        19 minutes ago      200 MB
hello-world         latest              3535063d9957        6 days ago          1.848 kB
centos              7                   88ec626ba223        6 weeks ago         199.7 MB
centos              latest              88ec626ba223        6 weeks ago         199.7 MB
training/webapp     latest              02a8815912ca        3 years ago         348.8 MB
[root@docker-machine_192.168.31.129 docker]# docker rmi ecf3512fa6e6
Error response from daemon: Conflict, cannot delete ecf3512fa6e6 because the running container 4b43371be7bd is using it, stop it and use -f to force
Error: failed to remove images: [ecf3512fa6e6]
[root@docker-machine_192.168.31.129 docker]# docker  stop 4b43371be7bd
4b43371be7bd
[root@docker-machine_192.168.31.129 docker]# docker rmi ecf3512fa6e6  
Error response from daemon: Conflict, cannot delete ecf3512fa6e6 because the container 4b43371be7bd is using it, use -f to force
Error: failed to remove images: [ecf3512fa6e6]
[root@docker-machine_192.168.31.129 docker]# docker rm 4b43371be7bd   
4b43371be7bd
[root@docker-machine_192.168.31.129 docker]# docker rmi ecf3512fa6e6
Untagged: centos:v2
Deleted: ecf3512fa6e6f5bfbea3937f6cc4849bf7c5597b4f57365cab67e1359457a5f9
Deleted: c7c01f1b0dd2309613a3430d826bd5be9bbab1d5ccc978b2ecbb86e93600c2b0
Deleted: db90442b2ffbf4b9025cd21cf0f58dba147e71de0c5153d9903d10ad0970b926
[root@docker-machine_192.168.31.129 docker]# docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              v1                  f24c4c696e23        20 minutes ago      200 MB
hello-world         latest              3535063d9957        6 days ago          1.848 kB
centos              7                   88ec626ba223        6 weeks ago         199.7 MB
centos              latest              88ec626ba223        6 weeks ago         199.7 MB
training/webapp     latest              02a8815912ca        3 years ago         348.8 MB

删除镜像:docker rmi [img_name|img_id]

删除容器:docker rm [container _name|container _id]

不过,容器都停止的情况下,docker rmi可以加个-f参数强制删除。不过没有傻缺会这么做,结果很明显:停止的容器都会起不来的

posted @ 2018-07-17 14:00  wshenJin  阅读(486)  评论(0编辑  收藏  举报