Docker 鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建以後也不會被改變。php
由於鏡像包含操做系統完整的 root
文件系統,其體積每每是龐大的,所以在 Docker 設計時,就充分利用 Union FS 的技術,將其設計爲分層存儲的架構。因此嚴格來講,鏡像並不是是像一個 ISO 那樣的打包文件,鏡像只是一個虛擬的概念,其實際體現並不是由一個文件組成,而是由一組文件系統組成,或者說,由多層文件系統聯合組成。nginx
鏡像構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在本身這一層。好比,刪除前一層文件的操做,實際不是真的刪除前一層的文件,而是僅在當前層標記爲該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,可是實際上該文件會一直跟隨鏡像。所以,在構建鏡像的時候,須要額外當心,每一層儘可能只包含該層須要添加的東西,任何額外的東西應該在該層構建結束前清理掉。web
分層存儲的特徵還使得鏡像的複用、定製變的更爲容易。甚至能夠用以前構建好的鏡像做爲基礎層,而後進一步添加新的層,以定製本身所需的內容,構建新的鏡像。docker
Docker 運行容器前須要本地存在對應的鏡像,若是本地不存在該鏡像,Docker 會從鏡像倉庫下載該鏡像。shell
docker images :ubuntu
[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
同一倉庫源能夠有多個 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 search:app
[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 的位置
上面的流程爲:
從上面的輸出能夠看出,從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參數強制刪除。不過沒有傻缺會這麼作,結果很明顯:中止的容器都會起不來的