Docker 鏡像與容器管理(2)
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)