003.Docker

特別說明: 本人平時混跡于 B 站,不咋回復這里的評論,有問題可以到 B 站視頻評論區(qū)留言找我
視頻地址: https://space.bilibili.com/31137138/favlist?fid=326428938
課件說明: 本次提供的課件是 Spring Cloud Netflix 版微服務架構(gòu)指南,如果有興趣想要學習 Spring Cloud Alibaba 版,可以前往 http://www.qfdmy.com 查看相關(guān)課程資源
案例代碼: https://github.com/topsale/hello-spring-cloud-netflix

什么是 Docker

官網(wǎng)地址:https://www.docker.com/

Docker 最初是 dotCloud 公司創(chuàng)始人 Solomon Hykes 在法國期間發(fā)起的一個公司內(nèi)部項目,它是基于 dotCloud 公司多年云服務技術(shù)的一次革新,并于 [2013 年 3 月以 Apache 2.0 授權(quán)協(xié)議開源][docker-soft],主要項目代碼在 GitHub 上進行維護。Docker 項目后來還加入了 Linux 基金會,并成立推動 開放容器聯(lián)盟(OCI)

Docker 自開源后受到廣泛的關(guān)注和討論,至今其 GitHub 項目已經(jīng)超過 4 萬 6 千個星標和一萬多個 fork。甚至由于 Docker 項目的火爆,在 2013 年底,dotCloud 公司決定改名為 Docker。Docker 最初是在 Ubuntu 12.04 上開發(fā)實現(xiàn)的;Red Hat 則從 RHEL 6.5 開始對 Docker 進行支持;Google 也在其 PaaS 產(chǎn)品中廣泛應用 Docker。

Docker 使用 Google 公司推出的 Go 語言 進行開發(fā)實現(xiàn),基于 Linux 內(nèi)核的 cgroup,namespace,以及 AUFS 類的 Union FS 等技術(shù),對進程進行封裝隔離,屬于 操作系統(tǒng)層面的虛擬化技術(shù)。由于隔離的進程獨立于宿主和其它的隔離的進程,因此也稱其為 容器 。最初實現(xiàn)是基于 LXC,從 0.7 版本以后開始去除 LXC,轉(zhuǎn)而使用自行開發(fā)的 libcontainer,從 1.11 開始,則進一步演進為使用 runCcontainerd

Docker 在容器的基礎上,進行了進一步的封裝,從文件系統(tǒng)、網(wǎng)絡互聯(lián)到進程隔離等等,極大的簡化了容器的創(chuàng)建和維護。使得 Docker 技術(shù)比虛擬機技術(shù)更為輕便、快捷。

下面的圖片比較了 Docker 和傳統(tǒng)虛擬化方式的不同之處。傳統(tǒng)虛擬機技術(shù)是虛擬出一套硬件后,在其上運行一個完整操作系統(tǒng),在該系統(tǒng)上再運行所需應用進程;而容器內(nèi)的應用進程直接運行于宿主的內(nèi)核,容器內(nèi)沒有自己的內(nèi)核,而且也沒有進行硬件虛擬。因此容器要比傳統(tǒng)虛擬機更為輕便。

Container@2x.png
VM@2x.png

為什么需要 Docker

作為一種新興的虛擬化方式,Docker 跟傳統(tǒng)的虛擬化方式相比具有眾多的優(yōu)勢。

更高效的利用系統(tǒng)資源

由于容器不需要進行硬件虛擬以及運行完整操作系統(tǒng)等額外開銷,Docker 對系統(tǒng)資源的利用率更高。無論是應用執(zhí)行速度、內(nèi)存損耗或者文件存儲速度,都要比傳統(tǒng)虛擬機技術(shù)更高效。因此,相比虛擬機技術(shù),一個相同配置的主機,往往可以運行更多數(shù)量的應用。

更快速的啟動時間

傳統(tǒng)的虛擬機技術(shù)啟動應用服務往往需要數(shù)分鐘,而 Docker 容器應用,由于直接運行于宿主內(nèi)核,無需啟動完整的操作系統(tǒng),因此可以做到秒級、甚至毫秒級的啟動時間。大大的節(jié)約了開發(fā)、測試、部署的時間。

一致的運行環(huán)境

開發(fā)過程中一個常見的問題是環(huán)境一致性問題。由于開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境不一致,導致有些 bug 并未在開發(fā)過程中被發(fā)現(xiàn)。而 Docker 的鏡像提供了除內(nèi)核外完整的運行時環(huán)境,確保了應用運行環(huán)境一致性,從而不會再出現(xiàn) 「這段代碼在我機器上沒問題啊」 這類問題。

持續(xù)交付和部署

對開發(fā)和運維(DevOps)人員來說,最希望的就是一次創(chuàng)建或配置,可以在任意地方正常運行。

使用 Docker 可以通過定制應用鏡像來實現(xiàn)持續(xù)集成、持續(xù)交付、部署。開發(fā)人員可以通過 Dockerfile 來進行鏡像構(gòu)建,并結(jié)合 持續(xù)集成(Continuous Integration) 系統(tǒng)進行集成測試,而運維人員則可以直接在生產(chǎn)環(huán)境中快速部署該鏡像,甚至結(jié)合 持續(xù)部署(Continuous Delivery/Deployment) 系統(tǒng)進行自動部署。

而且使用 Dockerfile 使鏡像構(gòu)建透明化,不僅僅開發(fā)團隊可以理解應用運行環(huán)境,也方便運維團隊理解應用運行所需條件,幫助更好的生產(chǎn)環(huán)境中部署該鏡像。

更輕松的遷移

由于 Docker 確保了執(zhí)行環(huán)境的一致性,使得應用的遷移更加容易。Docker 可以在很多平臺上運行,無論是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運行結(jié)果是一致的。因此用戶可以很輕易的將在一個平臺上運行的應用,遷移到另一個平臺上,而不用擔心運行環(huán)境的變化導致應用無法正常運行的情況。

更輕松的維護和擴展

Docker 使用的分層存儲以及鏡像的技術(shù),使得應用重復部分的復用更為容易,也使得應用的維護更新更加簡單,基于基礎鏡像進一步擴展鏡像也變得非常簡單。此外,Docker 團隊同各個開源項目團隊一起維護了一大批高質(zhì)量的 官方鏡像,既可以直接在生產(chǎn)環(huán)境使用,又可以作為基礎進一步定制,大大的降低了應用服務的鏡像制作成本。

對比傳統(tǒng)虛擬機總結(jié)

特性 容器 虛擬機
啟動 秒級 分鐘級
硬盤使用 一般為 MB 一般為 GB
性能 接近原生 弱于
系統(tǒng)支持量 單機支持上千個容器 一般幾十個

安裝 Docker

平臺支持

Docker CE 支持多種平臺,如下表所示

桌面

平臺 架構(gòu)
Docker Desktop for Mac (macOS) X64
Docker Desktop for Windows (Microsoft Windows 10) X64

服務器

平臺 x86_64 / amd64 ARM ARM64 / AARCH64 IBM Power (ppc64le) IBM Z (s390x)
CentOS ? ?
Debian ? ? ?
Fedora ? ?
Ubuntu ? ? ? ? ?

準備安裝

卸載舊版本

apt-get remove docker docker-engine docker.io containerd runc

使用 APT 安裝

# 更新數(shù)據(jù)源
apt-get update
# 安裝所需依賴
apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# 安裝 GPG 證書
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 新增數(shù)據(jù)源
add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# 更新并安裝 Docker CE
apt-get update && apt-get install -y docker-ce

apt install docker.io

驗證安裝是否成功

docker version

# 輸出如下
Client:
 Version:           18.09.6
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        481bc77
 Built:             Sat May  4 02:35:57 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.6
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       481bc77
  Built:            Sat May  4 01:59:36 2019
  OS/Arch:          linux/amd64
  Experimental:     false

配置 Docker 鏡像加速器

阿里云加速器(推薦)

點擊鏈接獲取

官方提供中國區(qū)鏡像

https://registry.docker-cn.com

配置加速器

以配置阿里云加速器為例,首先 登錄阿里云(沒有賬號請先注冊),搜索 容器鏡像服務

Lusifer_20190616094532.png

找到你的專屬加速器

Lusifer_20190616094722.png

通過修改 daemon 配置文件 /etc/docker/daemon.json 來使用加速器

tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF

# 重啟 Docker
systemctl daemon-reload
systemctl restart docker

驗證配置是否成功

docker info

# 輸出如下
Containers: 38
 Running: 18
 Paused: 0
 Stopped: 20
Images: 10
Server Version: 18.09.6
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: bb71b10fd8f58240ca47fbb579b9d1028eea7c84
runc version: 2b18fe1d885ee5083ef9f0838fee39b62d653e30
init version: fec3683
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.15.0-51-generic
Operating System: Ubuntu 18.04.2 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.924GiB
Name: kubernetes-master
ID: PJ4H:7AF2:P5UT:6FMR:W4DI:SSWR:IQQR:J6QO:ARES:BOAC:ZVMO:SV2Y
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
## 這里是你配置的鏡像加速器
Registry Mirrors:
 https://xxxxxxxx.mirror.aliyuncs.com/
Live Restore Enabled: false
Product License: Community Engine

WARNING: No swap limit support

運行第一個容器

我們以 Nginx 為例,體驗 Docker 是如何運行容器的

# 下載鏡像
docker pull nginx

# 運行容器
docker run --name nginx-container -p 80:80 -d nginx

瀏覽器輸入虛擬機地址即可訪問 Nginx

Lusifer_20190616095948.png

Docker 引擎

Docker 引擎是一個包含以下主要組件的客戶端服務器應用程序。

  • 一種服務器,它是一種稱為守護進程并且長時間運行的程序。
  • REST API 用于指定程序可以用來與守護進程通信的接口,并指示它做什么。
  • 一個有命令行界面 (CLI) 工具的客戶端。
engine-components-flow.png

Docker 架構(gòu)

  • Docker 使用客戶端 - 服務器 (C/S) 架構(gòu)模式,使用遠程 API 來管理和創(chuàng)建 Docker 容器。
  • Docker 容器通過 Docker 鏡像來創(chuàng)建。
  • 容器與鏡像的關(guān)系類似于面向?qū)ο缶幊讨械膶ο笈c類。
Docker 面向?qū)ο?/th>
容器 對象
鏡像
Lusifer_20191205005055.png
標題 說明
鏡像(Images) Docker 鏡像是用于創(chuàng)建 Docker 容器的模板。
容器(Container) 容器是獨立運行的一個或一組應用。
客戶端(Client) Docker 客戶端通過命令行或者其他工具使用 Docker API (https://docs.docker.com/reference/api/docker_remote_api) 與 Docker 的守護進程通信。
主機(Host) 一個物理或者虛擬的機器用于執(zhí)行 Docker 守護進程和容器。
倉庫(Registry) Docker 倉庫用來保存鏡像,可以理解為代碼控制中的代碼倉庫。Docker Hub(https://hub.docker.com) 提供了龐大的鏡像集合供使用。
Docker Machine Docker Machine是一個簡化Docker安裝的命令行工具,通過一個簡單的命令行即可在相應的平臺上安裝Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。

Docker 鏡像

獲取鏡像

之前提到過,Docker Hub 上有大量的高質(zhì)量的鏡像可以用,這里我們就說一下怎么獲取這些鏡像。

從 Docker 鏡像倉庫獲取鏡像的命令是 docker pull。其命令格式為:

docker pull [選項] [Docker Registry 地址[:端口號]/]倉庫名[:標簽]

具體的選項可以通過 docker pull --help 命令看到,這里我們說一下鏡像名稱的格式。

  • 鏡像倉庫地址: 地址的格式一般是 <域名/IP>[:端口號]。默認地址是 Docker Hub。
  • 倉庫名: 如之前所說,這里的倉庫名是兩段式名稱,即 <用戶名>/<軟件名>。對于 Docker Hub,如果不給出用戶名,則默認為 library,也就是官方鏡像。
docker pull nginx

# 輸出如下
Using default tag: latest
latest: Pulling from library/nginx
fc7181108d40: Pull complete 
c4277fc40ec2: Pull complete 
780053e98559: Pull complete 
Digest: sha256:bdbf36b7f1f77ffe7bd2a32e59235dff6ecf131e3b6b5b96061c652f30685f3a
Status: Downloaded newer image for nginx:latest

列出鏡像

要想列出已經(jīng)下載下來的鏡像,可以使用 docker image ls 命令。

docker image ls

# 輸出如下
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
redis                latest              5f515359c7f8        5 days ago          183 MB
nginx                latest              05a60462f8ba        5 days ago          181 MB
mongo                3.2                 fe9198c04d62        5 days ago          342 MB
<none>               <none>              00285df0df87        5 days ago          342 MB
ubuntu               16.04               f753707788c5        4 weeks ago         127 MB
ubuntu               latest              f753707788c5        4 weeks ago         127 MB
ubuntu               14.04               1e0c3dd64ccd        4 weeks ago         188 MB

列表包含了 倉庫名、標簽、鏡像 ID、創(chuàng)建時間 以及 所占用的空間

其中倉庫名、標簽在之前的基礎概念章節(jié)已經(jīng)介紹過了。鏡像 ID 則是鏡像的唯一標識,一個鏡像可以對應多個標簽。因此,在上面的例子中,我們可以看到 ubuntu:16.04ubuntu:latest 擁有相同的 ID,因為它們對應的是同一個鏡像。

鏡像體積

如果仔細觀察,會注意到,這里標識的所占用空間和在 Docker Hub 上看到的鏡像大小不同。比如,ubuntu:16.04 鏡像大小,在這里是 127 MB,但是在 Docker Hub 顯示的卻是 50 MB。這是因為 Docker Hub 中顯示的體積是壓縮后的體積。在鏡像下載和上傳過程中鏡像是保持著壓縮狀態(tài)的,因此 Docker Hub 所顯示的大小是網(wǎng)絡傳輸中更關(guān)心的流量大小。而 docker image ls 顯示的是鏡像下載到本地后,展開的大小,準確說,是展開后的各層所占空間的總和,因為鏡像到本地后,查看空間的時候,更關(guān)心的是本地磁盤空間占用的大小。

另外一個需要注意的問題是,docker image ls 列表中的鏡像體積總和并非是所有鏡像實際硬盤消耗。由于 Docker 鏡像是多層存儲結(jié)構(gòu),并且可以繼承、復用,因此不同鏡像可能會因為使用相同的基礎鏡像,從而擁有共同的層。由于 Docker 使用 Union FS,相同的層只需要保存一份即可,因此實際鏡像硬盤占用空間很可能要比這個列表鏡像大小的總和要小的多。

你可以通過以下命令來便捷的查看鏡像、容器、數(shù)據(jù)卷所占用的空間。

docker system df

# 輸出如下
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              24                  0                   1.992GB             1.992GB (100%)
Containers          1                   0                   62.82MB             62.82MB (100%)
Local Volumes       9                   0                   652.2MB             652.2MB (100%)
Build Cache                                                 0B                  0B

虛懸鏡像

上面的鏡像列表中,還可以看到一個特殊的鏡像,這個鏡像既沒有倉庫名,也沒有標簽,均為 <none>

<none>               <none>              00285df0df87        5 days ago          342 MB

這個鏡像原本是有鏡像名和標簽的,原來為 mongo:3.2,隨著官方鏡像維護,發(fā)布了新版本后,重新 docker pull mongo:3.2 時,mongo:3.2 這個鏡像名被轉(zhuǎn)移到了新下載的鏡像身上,而舊的鏡像上的這個名稱則被取消,從而成為了 <none>。除了 docker pull 可能導致這種情況,docker build 也同樣可以導致這種現(xiàn)象。由于新舊鏡像同名,舊鏡像名稱被取消,從而出現(xiàn)倉庫名、標簽均為 <none> 的鏡像。這類無標簽鏡像也被稱為 虛懸鏡像(dangling image) ,可以用下面的命令專門顯示這類鏡像:

docker image ls -f dangling=true

# 輸出如下
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              00285df0df87        5 days ago          342 MB

一般來說,虛懸鏡像已經(jīng)失去了存在的價值,是可以隨意刪除的,可以用下面的命令刪除。

docker image prune

中間層鏡像

為了加速鏡像構(gòu)建、重復利用資源,Docker 會利用 中間層鏡像。所以在使用一段時間后,可能會看到一些依賴的中間層鏡像。默認的 docker image ls 列表中只會顯示頂層鏡像,如果希望顯示包括中間層鏡像在內(nèi)的所有鏡像的話,需要加 -a 參數(shù)。

docker image ls -a

這樣會看到很多無標簽的鏡像,與之前的虛懸鏡像不同,這些無標簽的鏡像很多都是中間層鏡像,是其它鏡像所依賴的鏡像。這些無標簽鏡像不應該刪除,否則會導致上層鏡像因為依賴丟失而出錯。實際上,這些鏡像也沒必要刪除,因為之前說過,相同的層只會存一遍,而這些鏡像是別的鏡像的依賴,因此并不會因為它們被列出來而多存了一份,無論如何你也會需要它們。只要刪除那些依賴它們的鏡像后,這些依賴的中間層鏡像也會被連帶刪除。

刪除鏡像

如果要刪除本地的鏡像,可以使用 docker image rm 命令,其格式為:

docker image rm [選項] <鏡像1> [<鏡像2> ...]
  • 用 ID、鏡像名、摘要刪除鏡像

其中,<鏡像> 可以是 鏡像短 ID、鏡像長 ID鏡像名 或者 鏡像摘要。

比如我們有這么一些鏡像:

docker image ls

# 輸出如下
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
centos                      latest              0584b3d2cf6d        3 weeks ago         196.5 MB
redis                       alpine              501ad78535f0        3 weeks ago         21.03 MB
docker                      latest              cf693ec9b5c7        3 weeks ago         105.1 MB
nginx                       latest              e43d811ce2f4        5 weeks ago         181.5 MB

我們可以用鏡像的完整 ID,也稱為 長 ID,來刪除鏡像。使用腳本的時候可能會用長 ID,但是人工輸入就太累了,所以更多的時候是用 短 ID 來刪除鏡像。docker image ls 默認列出的就已經(jīng)是短 ID 了,一般取前 3 個字符以上,只要足夠區(qū)分于別的鏡像就可以了。

比如這里,如果我們要刪除 redis:alpine 鏡像,可以執(zhí)行:

docker image rm 501

# 輸出如下
Untagged: redis:alpine
Untagged: redis@sha256:f1ed3708f538b537eb9c2a7dd50dc90a706f7debd7e1196c9264edeea521a86d
Deleted: sha256:501ad78535f015d88872e13fa87a828425117e3d28075d0c117932b05bf189b7
Deleted: sha256:96167737e29ca8e9d74982ef2a0dda76ed7b430da55e321c071f0dbff8c2899b
Deleted: sha256:32770d1dcf835f192cafd6b9263b7b597a1778a403a109e2cc2ee866f74adf23
Deleted: sha256:127227698ad74a5846ff5153475e03439d96d4b1c7f2a449c7a826ef74a2d2fa
Deleted: sha256:1333ecc582459bac54e1437335c0816bc17634e131ea0cc48daa27d32c75eab3
Deleted: sha256:4fc455b921edf9c4aea207c51ab39b10b06540c8b4825ba57b3feed1668fa7c7

我們也可以用鏡像名,也就是 <倉庫名>:<標簽>,來刪除鏡像。

docker image rm centos

# 輸出如下
Untagged: centos:latest
Untagged: centos@sha256:b2f9d1c0ff5f87a4743104d099a3d561002ac500db1b9bfa02a783a46e0d366c
Deleted: sha256:0584b3d2cf6d235ee310cf14b54667d889887b838d3f3d3033acd70fc3c48b8a
Deleted: sha256:97ca462ad9eeae25941546209454496e1d66749d53dfa2ee32bf1faabd239d38

當然,更精確的是使用 鏡像摘要 刪除鏡像。

docker image ls --digests

# 輸出如下
REPOSITORY                  TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
node                        slim                sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228   6e0c4c8e3913        3 weeks ago         214 MB

docker image rm node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228

# 輸出如下
Untagged: node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228
  • 用 docker image ls 命令來配合

像其它可以承接多個實體的命令一樣,可以使用 docker image ls -q 來配合使用 docker image rm,這樣可以成批的刪除希望刪除的鏡像。我們在“鏡像列表”章節(jié)介紹過很多過濾鏡像列表的方式都可以拿過來使用。

比如,我們需要刪除所有倉庫名為 redis 的鏡像:

docker image rm $(docker image ls -q redis)

或者刪除所有在 mongo:3.2 之前的鏡像:

docker image rm $(docker image ls -q -f before=mongo:3.2)

充分利用你的想象力和 Linux 命令行的強大,你可以完成很多非常贊的功能。

列出部分鏡像

不加任何參數(shù)的情況下,docker image ls 會列出所有頂級鏡像,但是有時候我們只希望列出部分鏡像。docker image ls 有好幾個參數(shù)可以幫助做到這個事情。

根據(jù)倉庫名列出鏡像

docker image ls ubuntu

# 輸出如下
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               f753707788c5        4 weeks ago         127 MB
ubuntu              latest              f753707788c5        4 weeks ago         127 MB
ubuntu              14.04               1e0c3dd64ccd        4 weeks ago         188 MB

列出特定的某個鏡像,也就是說指定倉庫名和標簽

docker image ls ubuntu:16.04

# 輸出如下
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               f753707788c5        4 weeks ago         127 MB

除此以外,docker image ls 還支持強大的過濾器參數(shù) --filter,或者簡寫 -f。之前我們已經(jīng)看到了使用過濾器來列出虛懸鏡像的用法,它還有更多的用法。比如,我們希望看到在 mongo:3.2 之后建立的鏡像,可以用下面的命令:

docker image ls -f since=mongo:3.2

# 輸出如下
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
redis               latest              5f515359c7f8        5 days ago          183 MB
nginx               latest              05a60462f8ba        5 days ago          181 MB

想查看某個位置之前的鏡像也可以,只需要把 since 換成 before 即可。

此外,如果鏡像構(gòu)建時,定義了 LABEL,還可以通過 LABEL 來過濾。

docker image ls -f label=com.example.version=0.1

以特定格式顯示

默認情況下,docker image ls 會輸出一個完整的表格,但是我們并非所有時候都會需要這些內(nèi)容。比如,剛才刪除虛懸鏡像的時候,我們需要利用 docker image ls 把所有的虛懸鏡像的 ID 列出來,然后才可以交給 docker image rm 命令作為參數(shù)來刪除指定的這些鏡像,這個時候就用到了 -q 參數(shù)。

docker image ls -q

# 輸出如下
5f515359c7f8
05a60462f8ba
fe9198c04d62
00285df0df87
f753707788c5
f753707788c5
1e0c3dd64ccd

--filter 配合 -q 產(chǎn)生出指定范圍的 ID 列表,然后送給另一個 docker 命令作為參數(shù),從而針對這組實體成批的進行某種操作的做法在 Docker 命令行使用過程中非常常見,不僅僅是鏡像,將來我們會在各個命令中看到這類搭配以完成很強大的功能。因此每次在文檔看到過濾器后,可以多注意一下它們的用法。

另外一些時候,我們可能只是對表格的結(jié)構(gòu)不滿意,希望自己組織列;或者不希望有標題,這樣方便其它程序解析結(jié)果等,這就用到了 Go 的模板語法。

比如,下面的命令會直接列出鏡像結(jié)果,并且只包含鏡像 ID 和倉庫名:

docker image ls --format "{{.ID}}: {{.Repository}}"

# 輸出如下
5f515359c7f8: redis
05a60462f8ba: nginx
fe9198c04d62: mongo
00285df0df87: <none>
f753707788c5: ubuntu
f753707788c5: ubuntu
1e0c3dd64ccd: ubuntu

或者打算以表格等距顯示,并且有標題行,和默認一樣,不過自己定義列:

docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"

# 輸出如下
IMAGE ID            REPOSITORY          TAG
5f515359c7f8        redis               latest
05a60462f8ba        nginx               latest
fe9198c04d62        mongo               3.2
00285df0df87        <none>              <none>
f753707788c5        ubuntu              16.04
f753707788c5        ubuntu              latest
1e0c3dd64ccd        ubuntu              14.04

Docker 容器

啟動容器

所需要的命令主要為 docker run。例如,下面的命令輸出一個 “Hello World”,之后終止容器。

docker run ubuntu:16.04 /bin/echo 'Hello world'
Hello world

當利用 docker run 來創(chuàng)建容器時,Docker 在后臺運行的標準操作包括:

  • 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
  • 利用鏡像創(chuàng)建并啟動一個容器
  • 分配一個文件系統(tǒng),并在只讀的鏡像層外面掛載一層可讀寫層
  • 從宿主主機配置的網(wǎng)橋接口中橋接一個虛擬接口到容器中去
  • 從地址池配置一個 ip 地址給容器
  • 執(zhí)行用戶指定的應用程序
  • 執(zhí)行完畢后容器被終止

終止容器

可以使用 docker container stop 來終止一個運行中的容器。此外,當 Docker 容器中指定的應用終結(jié)時,容器也自動終止。

例如對于只啟動了一個終端的容器,用戶通過 exit 命令或 ctrl + d 來退出終端時,所創(chuàng)建的容器立刻終止。終止狀態(tài)的容器可以用 docker container ls -a 命令看到。例如

docker container ls -a

# 輸出如下
CONTAINER ID        IMAGE                    COMMAND                CREATED             STATUS                          PORTS               NAMES
ba267838cc1b        ubuntu:14.04             "/bin/bash"            30 minutes ago      Exited (0) About a minute ago                       trusting_newton
98e5efa7d997        training/webapp:latest   "python app.py"        About an hour ago   Exited (0) 34 minutes ago                           backstabbing_pike

啟動已終止容器

處于終止狀態(tài)的容器,可以通過 docker container start 命令來重新啟動。此外,docker container restart 命令會將一個運行態(tài)的容器終止,然后再重新啟動它。

docker container start [container ID or NAMES]

守護態(tài)運行

更多的時候,需要讓 Docker 在后臺運行而不是直接把執(zhí)行命令的結(jié)果輸出在當前宿主機下。此時,可以通過添加 -d 參數(shù)來實現(xiàn)。如果不使用 -d 參數(shù)運行容器。

docker run ubuntu:16.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"

# 輸出如下
hello world
hello world
hello world
hello world

容器會把輸出的結(jié)果 (STDOUT) 打印到宿主機上面,如果使用了 -d 參數(shù)運行容器。

docker run -d ubuntu:17.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"

# 輸出如下
77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a

此時容器會在后臺運行并不會把輸出的結(jié)果 (STDOUT) 打印到宿主機上面(輸出結(jié)果可以用 docker logs 查看)。

注意: 容器是否會長久運行,是和 docker run 指定的命令有關(guān),和 -d 參數(shù)無關(guān)。

容器日志

要獲取容器的輸出信息,可以通過 docker container logs 命令。

docker container logs [container ID or NAMES]

# 輸出如下
hello world
hello world
hello world

進入容器

在使用 -d 參數(shù)時,容器啟動后會進入后臺。某些時候需要進入容器進行操作,docker exec 命令能讓我們以交互的方式進入容器。

docker exec 后邊可以跟多個參數(shù),這里主要說明 -i -t 參數(shù)。只用 -i 參數(shù)時,由于沒有分配偽終端,界面沒有我們熟悉的 Linux 命令提示符,但命令執(zhí)行結(jié)果仍然可以返回。當 -i -t 參數(shù)一起使用時,則可以看到我們熟悉的 Linux 命令提示符。

docker exec -it 69d1 bash
root@69d137adef7a:/#

如果從這個 stdin 中 exit,不會導致容器的停止。更多參數(shù)說明請使用 docker exec --help 查看。

刪除容器

可以使用 docker container rm 來刪除一個處于終止狀態(tài)的容器。例如

docker container rm trusting_newton
trusting_newton

如果要刪除一個運行中的容器,可以添加 -f 參數(shù)。Docker 會發(fā)送 SIGKILL 信號給容器。

清理所有處于終止狀態(tài)的容器

docker container ls -a 命令可以查看所有已經(jīng)創(chuàng)建的包括終止狀態(tài)的容器,如果數(shù)量太多要一個個刪除可能會很麻煩,用下面的命令可以清理掉所有處于終止狀態(tài)的容器。

docker container prune

特別說明: 本人平時混跡于 B 站,不咋回復這里的評論,有問題可以到 B 站視頻評論區(qū)留言找我
視頻地址: https://space.bilibili.com/31137138/favlist?fid=326428938
課件說明: 本次提供的課件是 Spring Cloud Netflix 版微服務架構(gòu)指南,如果有興趣想要學習 Spring Cloud Alibaba 版,可以前往 http://www.qfdmy.com 查看相關(guān)課程資源
案例代碼: https://github.com/topsale/hello-spring-cloud-netflix

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容