1. 程式人生 > >Docker 鏡像與容器管理(2)

Docker 鏡像與容器管理(2)

.... label ace ansi linu 條件 cat 制作 net


title: Docker 鏡像與容器管理(2)
date: 2018-12-14 17:04:05
tags:

  • Docker
    categories: Docker
    copyright: true
    ---

Docker是基於Go語言實現的開源容器項目,Docker讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後發布到任何流行的 Linux 機器上,也可以實現虛擬化.容器是完全使用沙箱機制,相互之間不會有任何接口,Docker誕生於2013年年初,最初發起者是dotCloud公司.Docker自開源後受到廣泛的關註和討論,目前已有多個相關項目(包括Docker三劍客、Kubernetes等),逐漸形成了圍繞Docker容器的生態體系,由於Docker在業界造成的影響力實在太大,dotCloud公司後來也直接改名為Docker Inc,並專註於Docker相關技術和產品的開發.



鏡像與容器簡介

Docker的大部分操作都圍繞著它的三大核心概念:鏡像、容器、倉庫而展開.因此,準確把握這三大核心概念對於掌握Docker技術尤為重要,在docker中,我們重點關註的就是鏡像和容器了.因為在實際應用中,我們封裝好鏡像,然後通過鏡像來創建容器,在容器運行我們的應用就好了.而server端掌控網絡和磁盤,我們不用去關心,啟動docker sever 和 docker client都是一條命令的事情.

鏡像(Image): Docker鏡像類似於虛擬機鏡像,可以將它理解為一個只讀的模板.例如,一個鏡像可以包含一個基本的操作系統環境,裏面僅安裝了一個應用程序,可以把它稱為一個鏡像,鏡像是創建Docker容器的基礎.通過版本管理和增量的文件系統,Docker提供了一套十分簡單的機制來創建和更新現有的鏡像,用戶甚至可以從網上下載一個已經做好的應用鏡像,並直接使用.

容器(Container): Docker容器類似於一個輕量級的沙箱,Docker利用容器來運行和隔離應用.容器是從鏡像創建的應用運行實例.可以將其啟動、開始、停止、刪除,而這些容器都是彼此相互隔離的、互不可見的.可以把容器看做是一個簡易版的Linux系統環境,以及運行在其中的應用程序打包而成的盒子.

鏡像啟動後,都是一堆layer的統一視角,唯一的卻別是鏡像最上面那一層是只讀的,不可以修改,但是容器最上面一層是rw的,提供給用戶操作.

倉庫(repository): Docker倉庫類似於代碼倉庫,它是Docker集中存放鏡像文件的場所.根據所存儲的鏡像公開分享與否,Docker倉庫可以分為公開倉庫(Public)和私有倉庫(Private)兩種形式.目前,最大的公開倉庫是官方提供的Docker Hub,其中存放了數量龐大的鏡像供用戶下載.國內不少雲服務提供商(如網易雲、阿裏雲等)也提供了倉庫的本地源,可以提供穩定的國內訪問.


管理Docker鏡像

鏡像是Docker三大核心概念中最為重要的,自Docker誕生之日起,鏡像就是相關社區最為熱門的關鍵詞,Docker運行容器前需要本地存在對應的鏡像,如果鏡像沒保存在本地,Docker會嘗試先從默認Docker Hub倉庫下載,用戶也可以通過配置,使用自定義的鏡像倉庫.

下面例子將圍繞鏡像這一核心概念的具體操作,包括如何使用pull命令從Docker Hub倉庫中下載鏡像到本地,如何查看本地已有的鏡像信息和管理鏡像標簽,如何在遠端倉庫使用search命令進行搜索和過濾,如何刪除鏡像標簽和鏡像文件,如何創建用戶定制的鏡像並且保存為外部文件.最後,還介紹如何往Docker Hub倉庫中推送自己的鏡像.

◆查詢本地鏡像◆

使用docker images命令可以列出本地主機上已有鏡像的基本信息,還可以使用條件過濾出你想要看得到的相關鏡像文件的信息.

[[email protected] ~]# docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

上面信息的參數解釋,在列出的信息中可以看到以下幾個字段信息:

REPOSITORY=來自於哪個倉庫,比如hello-world倉庫.
TAG=鏡像標簽信息,latest表示不同版本信息.
IMAGE ID=鏡像唯一ID號,此處唯一.
CREATED=創建時間信息,鏡像最後的更新時間.
SIZE=鏡像大小,優秀的鏡像往往體積都較小,hello-world很優秀.

其中鏡像的ID信息十分重要,它唯一標識了鏡像.在使用鏡像ID的時候,一般可以使用該ID的前若幹個字符組成的可區分串來替代完整的ID,比如後期我們要刪除一個鏡像時無需寫出全部鏡像ID.

TAG信息用來標記來自同一個倉庫的不同鏡像,例如ubuntu倉庫中有多個鏡像,通過TAG信息來區分發行版本,包括13.04、14.04、16.04等標簽.

鏡像大小信息只是表示該鏡像的邏輯體積大小,實際上由於相同的鏡像層本地只會存儲一份,物理上占用的存儲空間會小於各鏡像的邏輯體積之和.

實例1: 通過使用-a --all=true|false參數,列出所有的鏡像文件(包括臨時文件),默認為否.因為我這裏只有一個鏡像所以只有這一個啦.

[[email protected] ~]# docker images --all=true

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

實例2: 通過使用--digests=true|false,列出鏡像的數字摘要值,默認為否.

[[email protected] ~]# docker images --digests=true

REPOSITORY          TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
hello-world         latest              sha256:0add3ace90ecb4adbf7777e9a   4ab4c602aa5e        3 months ago        1.84kB

實例3: 通過使用--quiet=true|false,僅輸出ID信息,默認為否.

[[email protected] ~]# docker images -q
4ab4c602aa5e

[[email protected] ~]# docker images --quiet=false

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

◆查詢網絡鏡像◆

使用docker search命令可以搜索遠端倉庫中共享的鏡像,默認搜索官方倉庫中的鏡像.用法為docker search TERM.

實例1: 使用search搜索一個Centos鏡像文件.

[[email protected] ~]# docker search centos

NAME                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
centos                             The official build of CentOS.                   5048                [OK]            
ansible/centos7-ansible            Ansible on Centos7                              119                                     [OK]
jdeathe/centos-ssh                 CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86…   102                
......

實例2: 僅顯示自動創建的鏡像,默認為否.

[[email protected] ~]# docker search --automated=true centos
Flag --automated has been deprecated, use --filter=is-automated=true instead
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
ansible/centos7-ansible           Ansible on Centos7                              119                                     [OK]
jdeathe/centos-ssh                CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86…   102                                     [OK]
consol/centos-xfce-vnc            Centos container with "headless" VNC session…   73                                      [OK]
imagine10255/centos6-lnmp-php56   centos6-lnmp-php56                              48                                      [OK]

實例3: 搜索所有自動創建的評價為1+的帶nginx關鍵字的鏡像.

[[email protected] ~]# docker search --automated -s 3 nginx

Flag --automated has been deprecated, use --filter=is-automated=true instead
Flag --stars has been deprecated, use --filter=stars=3 instead
NAME                                                   DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
jwilder/nginx-proxy                                    Automated Nginx reverse proxy for docker con…   1488                                    [OK]
richarvey/nginx-php-fpm                                Container running Nginx + PHP-FPM capable of…   663    

◆拉鏡像到本地◆

可以使用docker pull命令直接從Docker Hub鏡像源來下載鏡像,該命令的格式為docker pull NAME[:TAG].其中NAME是鏡像倉庫的名稱,TAG是鏡像的標簽,通常情況下,描述一個鏡像需要包括"名稱+標簽".

實例: 通過pull命令獲取一個Centos系統鏡像.

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[[email protected] ~]# docker pull centos

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

◆給鏡像加標簽◆

為了方便在後續工作中使用特定鏡像,還可以使用docker tag命令來為本地鏡像任意添加新的標簽.

實例: 為Centos鏡像添加一個新的mycentos:latest鏡像標簽.

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[[email protected] ~]# docker tag centos:latest mycentos:latest

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
mycentos            latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

上圖可看到,當再次使用docker images列出本地主機上鏡像信息,可以看到多了一個擁有mycentos:latest標簽的鏡像,細心的你可能註意到,這些mycentos:latest鏡像的ID跟centos:latest完全一致,它們實際上指向同一個鏡像文件,只是別名不同而已.docker tag命令添加的標簽實際上起到了類似鏈接的作用.

◆查詢鏡像詳情◆

使用docker inspect命令可以獲取該鏡像的詳細信息,包括制作者、適應架構、各層的數字摘要等.

[[email protected] ~]# docker inspect hello-world

[
    {
        "Id": "sha256:4ab4c602aa5eed5528a6620ff18a1dc4faef0e1ab3a5eddeddb410714478c67f",
        "RepoTags": [
            "hello-world:latest"
        ],
        "RepoDigests": [
            "[email protected]:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788"
        ],
.....

上面的輸出有很多,只不過我這裏簡單顯示了,如果我們只要其中一項內容時,可以使用參數-f來指定你要打印的數據,例如下面我們來演示一下獲取當前鏡像的Id這個字段的數據.

[[email protected] ~]# docker inspect -f {{".Id"}} hello-world

sha256:4ab4c602aa5eed5528a6620ff18a1dc4faef0e1ab3a5eddeddb410714478c67f

◆查詢鏡像分層◆

既然鏡像文件由多個層組成,那麽怎麽知道各個層的內容具體是什麽呢?這時候可以使用history子命令,該命令將列出各層的創建信息.註意過長的命令被自動截斷了,可以使用前面提到的--no-trunc選項來輸出完整命令.

[[email protected] ~]# docker history centos:latest

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
1e1148e4cc2c        8 days ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           8 days ago          /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
<missing>           8 days ago          /bin/sh -c #(nop) ADD file:6f877549795f4798a…   202MB

◆刪除指定鏡像◆

使用docker rmi命令可以刪除鏡像,其中IMAGE可以為標簽或ID,如果要強制刪除可加-f這個選項.

刪除鏡像: 通過rmi命令刪除mycentos這個標簽.

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
mycentos            latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[[email protected] ~]# docker rmi mycentos:latest
Untagged: mycentos:latest

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

強制刪除: 強制刪除系統全部鏡像.

[[email protected] ~]# docker rmi -f $(docker images -q)

Deleted: sha256:1e1148e4cc2c148c6890a18e3b2d2dde41a6745ceb4e5fe94a923d811bf82ddb
Deleted: sha256:071d8bd765171080d01682844524be57ac9883e53079b6ac66707e192ea25956
Untagged: hello-world:latest
Untagged: [email protected]:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
Deleted: sha256:4ab4c602aa5eed5528a6620ff18a1dc4faef0e1ab3a5eddeddb410714478c67f

◆鏡像導入導出◆

導出操作: 通過save 鏡像ID >導出centos鏡像.

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[[email protected] ~]# docker save 1e1148e4cc2c > /root/centos.tar

[[email protected] ~]# ls
centos.tar

導入操作: 通過load < 文件名導入centos鏡像.

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[[email protected] ~]# docker load < centos.tar

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

◆鏡像命令速查◆

[[email protected] ~]# docker info                       #查詢守護進程的系統資源設置
[[email protected] ~]# docker search                     #倉庫鏡像的查詢
[[email protected] ~]# docker pull                       #倉庫鏡像的下載
[[email protected] ~]# docker images                     #本地鏡像的查詢
[[email protected] ~]# docker rmi                        #本地鏡像的刪除
[[email protected] ~]# docker rmi -f $(docker images -q) #強制刪除全部鏡像(Image)
[[email protected] ~]# docker rmi -f <image id>          #強制刪除指定鏡像(Image)
[[email protected] ~]# docker history 鏡像名              #查詢鏡像的分層
[[email protected] ~]# docker save 鏡像ID > /root/*.tar  #鏡像的導出
[[email protected] ~]# docker load < /root/*.tar         #鏡像的導入


管理Docker容器

容器是Docker的另一個核心概念,簡單來說,容器是鏡像的一個運行實例.所不同的是,鏡像是靜態的只讀文件,而容器帶有運行時需要的可寫文件層.如果認為虛擬機是模擬運行的一整套操作系統和跑在上面的應用,那麽Docker容器就是獨立運行的一個應用,以及它們必需的運行環境.

下面的例子將具體介紹圍繞容器的重要操作,包括創建一個容器、啟動容器、終止一個容器、進入容器內執行操作、刪除容器和通過導入導出容器來實現容器遷移等.

◆創建容器◆

從現在開始,忘掉臃腫的虛擬機吧,對容器進行操作就跟直接操作應用一樣簡單、快速.Docker容器實在太輕量級了,用戶可以隨時創建或刪除容器.

新建容器: 可以使用docker create命令新建一個容器,使用docker create命令新建的容器處於停止狀態,可以使用docker start命令來啟動它.

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        9 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[[email protected] ~]# docker create -it centos:latest
23c881ac33c526e60811978a418be92c6a022c106e6d59d989fb7b932dc3473a

[[email protected] ~]# docker start 23c881ac33c5
23c881ac33c5

新建並啟動: 除了創建容器後通過start命令來啟動,也可以直接新建並啟動容器.所需要的命令主要為docker run,等價於先執行docker create命令,再執行docker start命令.

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        9 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[[email protected] ~]# docker run centos:latest

守護態運行: 更多的時候,需要讓Docker容器在後臺以守護態Daemonized形式運行.此時,可以通過添加-d參數來實現.

[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        9 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[[email protected] ~]# docker run -itd ubuntu:latest
540fd59ee8899a38c4302d83549bd113ad159064ec41c9475a773cbc0fd2dfb8

[[email protected] ~]# docker run -d centos:latest /bin/sh
505a728a2bed9e96b3e4615c4e528bd55285a856dc201bb50d4ed5c9e0a52566

[[email protected] ~]# docker run -d centos:latest /bin/sh -c "echo hello"
6c8fc14a6637928442b768bee0b2d3af800464192e7fce295f39ccdd91b73572

◆終止容器◆

可以使用docker stop來終止一個運行中的容器,也可以使用docker kill命令幹掉一個容器.

stop終止容器: 指定通過stop終止一個容器.

[[email protected] ~]# docker stop 540fd59ee889
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
540fd59ee889        ubuntu:latest       "/bin/bash"         6 minutes ago       Up 6 minutes                            festive_liskov

[[email protected] ~]# docker stop 540fd59ee889
540fd59ee889

kill終止容器:docker kill命令會直接發送SIGKILL信號來強行終止容器.

[[email protected] ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
84da1ad9f06c        centos:latest       "/bin/bash"         33 seconds ago      Up 32 seconds                           hungry_bhabha

[[email protected] ~]# docker kill 84da1ad9f06c
84da1ad9f06c

◆進入容器◆

在使用-d參數時,容器啟動後會進入後臺,用戶無法看到容器中的信息,也無法進行操作.
這個時候如果需要進入容器進行操作,有多種方法,包括使用官方的attach或exec命令,以及第三方的nsenter工具等.下面分別介紹一下.

attach進入容器: attach是Docker自帶的命令,下面我們使用它來進入容器的內部吧.

[[email protected] ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
540fd59ee889        ubuntu:latest       "/bin/bash"         About a minute ago   Up About a minute                       festive_liskov
300560ca1c88        centos:latest       "/bin/bash"         3 minutes ago        Up 3 minutes                            ecstatic_raman

[[email protected] ~]# docker attach 300560ca1c88
[[email protected] /]#

但是使用attach命令有時候並不方便,當多個窗口同時用attach命令連到同一個容器的時候,所有窗口都會同步顯示.當某個窗口因命令阻塞時,其他窗口也無法執行操作了,接著下面的命令就更好一些了.

exec進入容器: Docker從1.3.0版本起提供了一個更加方便的exec命令,可以在容器內直接執行任意命令.

[[email protected] ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
540fd59ee889        ubuntu:latest       "/bin/bash"         3 minutes ago       Up 3 minutes                            festive_liskov

[[email protected] ~]# docker exec -it 540fd59ee889 /bin/bash
[email protected]:/#

可以看到,一個bash終端打開了,在不影響容器內其他應用的前提下,用戶可以很容易與容器進行交互,通過指定-it參數來保持標準輸入打開,並且分配一個偽終端.通過exec命令對容器執行操作是最為推薦的方式.

◆刪除容器◆

可以使用docker rm命令來刪除處於終止或退出狀態的容器.

rm 刪除容器: 通過rm -f命令強制刪除一個容器.

[[email protected] ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
fa6110bdb3df        centos:latest       "/bin/bash"         3 seconds ago       Up 2 seconds                            eager_mirzakhani

[[email protected] ~]# docker rm -f fa6110bdb3df
fa6110bdb3df

◆命令速查◆

[[email protected] ~]# docker run                      #容器的創建或啟動
[[email protected] ~]# docker run --restart=always     #設置容器的自啟動

[[email protected] ~]# docker ps                       #運行中的容器的查詢
[[email protected] ~]# docker ps --no-trunc            #查看容器狀態
[[email protected] ~]# docker start/stop               #容器啟動/關閉
[[email protected] ~]# docker stop $(docker ps -a -q)  #停止所有運行中的容器(Container)
[[email protected] ~]# docker rm $(docker ps -a -q)    #刪除全部容器(Container)

[[email protected] ~]# docker start/stop 鏡像名         #通過容器別名啟動/停止
[[email protected] ~]# docker inspect 鏡像名            #查看容器所有基本信息
[[email protected] ~]# docker logs 鏡像名               #查看容器日誌
[[email protected] ~]# docker stats 鏡像名              #查看容器所占用的系統資源

[[email protected] ~]# docker exec 容器名 容器內執行的命令#容器執行命令
[[email protected] ~]# docker exec -it 容器名 /bin/bash  #登入容器的bash
[[email protected] ~]# docker run -it 容器名 /bin/bash   #進入一個鏡像


Docker 鏡像與容器管理(2)