Docker 鏡像

Docker 鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建以後也不會被改變。php

由於鏡像包含操做系統完整的 root 文件系統,其體積每每是龐大的,所以在 Docker 設計時,就充分利用 Union FS 的技術,將其設計爲分層存儲的架構。因此嚴格來講,鏡像並不是是像一個 ISO 那樣的打包文件,鏡像只是一個虛擬的概念,其實際體現並不是由一個文件組成,而是由一組文件系統組成,或者說,由多層文件系統聯合組成。nginx

鏡像構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在本身這一層。好比,刪除前一層文件的操做,實際不是真的刪除前一層的文件,而是僅在當前層標記爲該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,可是實際上該文件會一直跟隨鏡像。所以,在構建鏡像的時候,須要額外當心,每一層儘可能只包含該層須要添加的東西,任何額外的東西應該在該層構建結束前清理掉。web

分層存儲的特徵還使得鏡像的複用、定製變的更爲容易。甚至能夠用以前構建好的鏡像做爲基礎層,而後進一步添加新的層,以定製本身所需的內容,構建新的鏡像。docker

Docker 運行容器前須要本地存在對應的鏡像,若是本地不存在該鏡像,Docker 會從鏡像倉庫下載該鏡像。shell

查看本地鏡像

docker imagesubuntu

[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

各項目說明:centos

  • REPOSITORY:表示鏡像的倉庫源
  • TAG:鏡像的標籤,默認latest
  • IMAGE ID:鏡像ID
  • CREATED:鏡像建立時間
  • VIRTUAL SIZE:鏡像大小

同一倉庫源能夠有多個 TAG,表明這個倉庫源的不一樣個版本,如ubuntu倉庫源裏,有15.十、14.04等多個不一樣的版本,咱們使用 REPOSITORY:TAG 來定義不一樣的鏡像。例如,運行一個centos7容器:bash

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

如上,若是不指定TAG,則默認使用latest。架構

搜索鏡像

docker searchapp

[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參數強制刪除。不過沒有傻缺會這麼作,結果很明顯:中止的容器都會起不來的

相關文章
相關標籤/搜索