《Docker:從入門到實踐》學習筆記(一):映像檔、容器、倉庫

前言

本文複習 Docker 相關概念與指令。

簡介

Docker 是一個開源專案,誕生於 2013 年初,它基於 Go 語言實作。Docker 專案的目標是實作輕量級的作業系統虛擬化解決方案。

映像檔

獲取

使用 docker pull 指令從倉庫取得所需要的映像檔。

1
docker pull ubuntu:12.04

列出

使用 docker images 顯示本機已有的映像檔。

1
2
3
4
5
6
7
docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 12.04 74fe38d11401 4 weeks ago 209.6 MB
ubuntu precise 74fe38d11401 4 weeks ago 209.6 MB
ubuntu 14.04 99ec81b80c55 4 weeks ago 266 MB
ubuntu latest 99ec81b80c55 4 weeks ago 266 MB
ubuntu trusty 99ec81b80c55 4 weeks ago 266 MB

在列出訊息中,可以看到幾段文字訊息:

  • 映像檔的倉庫,比如 ubuntu
  • 映像檔的標記,比如 14.04
  • 映像檔的 ID(唯一)。
  • 映像檔的建立時間。
  • 映像檔的大小。

其中映像檔的 ID 標識了唯一的映像檔,注意到 ubuntu:14.04ubuntu:trusty 具有相同的映像檔 ID,說明它們實際上是同一映像檔。

建立

修改既有映像檔

先使用下載的映像檔啟動容器。

1
docker run -t -i ubuntu bash

在容器中加入 git 指令。

1
2
root@43d32daf6984:/# apt-get update
root@43d32daf6984:/# apt-get install -y git

使用 exit 來退出容器,並使用 docker commit 指令來提交更新後的副本。

1
docker commit -m "Added git" -a "Memo Chou" 43d32daf6984 ubuntu:v2

其中,-m 指定提交的說明信息;-a 可以指定更新的使用者信息;之後是用來建立映像檔的容器的 ID;最後指定新映像檔的名稱和 tag 。建立成功後會印出新映像檔的 ID。

使用 docker images 查看新建立的映像檔。

1
2
3
4
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu v2 7c65cc4da023 2 seconds ago 208MB
ubuntu latest 54c9d81cbb44 3 weeks ago 72.8MB

之後,可以使用新的映像檔來啟動容器。

1
docker run -t -i ubuntu:v2 bash

利用 Dockerfile 建立

為了方便在一個團隊中分享,可以新增 Dockerfile 檔。

1
2
3
4
5
FROM ubuntu:14.04

RUN apt-get update

RUN apt-get install -y git

使用 docker build 建立映像檔。

1
docker build -t ubuntu:v2 ./

其中 -t 標記添加 tag,而 ./ 則是 Dockerfile 所在的目錄。

Dockfile 中的指令會被一條一條地執行。每一步都建立了一個新的容器,在容器中執行指令並提交修改(就跟 docker commit 一樣)。當所有的指令都執行完畢之後,返回了最終的映像檔 ID,所有的中間步驟所產生的容器都會被刪除和清理。注意,一個映像檔不能超過 127 層。

另外,還可以用 docker tag 指令修改映像檔的標籤。

1
docker tag 80c17d33abc6 ubuntu:v3

上傳映像檔

使用 docker push 指令,可以把建立的映像檔上傳到倉庫中來共享。

1
docker push ubuntu:v2

匯出與匯入

使用 docker save 指令,可以建立映像檔到本地檔案。

1
docker save -o ubuntu.tar ubuntu:latest

使用 docker load 指令,將本地檔案匯入到本地映像檔庫。

1
docker load --input ubuntu.tar

移除

使用 docker rmi 指令,移除映像檔。

1
docker rmi ubuntu:v2

注意,在刪除映像檔之前要先用 docker rm 指令刪除依賴於這個映像檔的所有容器。

容器

新建並啟動

以下使用 docker run 指令,會輸出字串後刪除容器。

1
docker run --rm ubuntu:latest /bin/echo 'Hello World!'

以下則啟動一個 bash 終端,允許使用者進行互動。

1
docker run -ti ubuntu:latest bash

其中,-t 讓 Docker 分配一個虛擬終端(pseudo-tty)並綁定到容器的標準輸入上,而 -i 則讓容器的標準輸入保持打開。

當利用 docker run 指令來建立容器時,Docker 在後台執行的標準操作包括:

  • 檢查本地是否存在指定的映像檔,不存在就從公有倉庫下載。
  • 利用映像檔建立並啟動一個容器。
  • 分配一個檔案系統,並在唯讀的映像檔層外面掛載一層可讀寫層。
  • 從宿主主機設定的網路橋界面中橋接一個虛擬埠到容器中去。
  • 從位址池中設定一個 IP 位址給容器。
  • 執行使用者指定的應用程式。
  • 執行完畢後容器被終止。

啟動已終止容器

先查看所有容器。

1
2
3
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5599107ea023 ubuntu:latest "bash" 2 minutes ago Exited (0) 4 seconds ago brave_gauss

啟動已終止容器。

1
docker start 5599107ea023

再次查看所有容器。

1
2
3
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5599107ea023 ubuntu:latest "bash" 2 minutes ago Up 1 second brave_gauss

守護態執行

更多時候,需要讓 Docker 容器在後台以守護態(Daemonized)形式執行。此時,可以透過新增 -d 參數來實作。下面的命令會在後台執行容器。

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

使用 docker ps 指令查看容器資訊。

1
2
3
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d0b55ef841a ubuntu:latest "/bin/sh -c 'while t…" 12 seconds ago Up 11 seconds condescending_bell

使用 docker logs 指令查看容器輸出訊息。

1
2
3
4
5
docker logs 7d0b55ef841a
hello world
hello world
hello world
...

終止

使用 docker stop 指令,來終止一個執行中的容器。

1
docker stop 7d0b55ef841a

終止狀態的容器可以使用 docker ps -a 命令看到。

1
2
3
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d0b55ef841a ubuntu:latest "/bin/sh -c 'while t…" 3 minutes ago Exited (137) 2 seconds ago condescending_bell

進入

使用 docker exec 指令,進入容器。

1
docker exec -ti 0a7468924086 bash

使用 docker attach 指令,也能進入容器。但是當多個窗口同時 attach 到同一個容器的時候,所有窗口都會同步顯示操作結果。

1
docker attach 0a7468924086

匯出與匯入

使用 docker export 指令,將本地容器匯出成容器快照檔案。

1
docker export 0a7468924086 > ubuntu.tar

使用 docker import 指令,將容器快照檔案中再匯入為映像檔。

1
docker import ubuntu.tar

注意,使用者既可以使用 docker load 來匯入映像檔儲存檔案到本地映像檔庫,也可以使用 docker import 來匯入一個容器快照到本地映像檔庫。區別在於,容器快照檔案將丟棄所有的歷史記錄和原始資料訊息(即僅保存容器當時的快照狀態),而映像檔儲存檔案將保存完整記錄,檔案體積也跟著變大。

刪除

使用 docker rm 指令,刪除一個處於終止狀態的容器。

1
docker rm 0a3b18c9f87a

倉庫

登入

可以透過執行 docker login 指令來輸入使用者名稱、密碼和電子信箱來完成註冊和登入。

搜尋

使用 docker search 指令,搜尋官方倉庫中的映像檔。

1
docker search centos

可以看到顯示了很多包含關鍵字的映像檔,其中包括映像檔名字、描述、星級(表示該映像檔的受歡迎程度)、是否官方建立、是否自動建立。官方的映像檔說明是官方專案組建立和維護的,自動建立的映像檔允許使用者驗證映像檔的來源和內容。

根據是否是官方提供,可將映像檔資源分為兩類。一種是類似 centos 這樣的基礎映像檔,被稱為基礎或根映像檔。這些基礎映像檔是由 Docker 公司建立、驗證、支援、提供。這樣的映像檔往往使用單個單詞作為名字。 還有一種類型,比如 tianon/centos 映像檔,它是由 Docker 的使用者建立並維護的,往往帶有使用者名稱前綴。可以透過前綴 user_name/ 來指定使用某個使用者提供的映像檔。

下載

使用 docker pull 指令,來將它下載到本地。

1
docker pull centos

自動建立

自動建立(Automated Builds)功能對於需要經常升級映像檔內程式來說,十分方便。

自動建立允許使用者透過 Docker Hub 指定跟蹤一個目標網站(像是 GitHub 或 BitBucket)上的專案,一旦專案發生新的提交,則自動執行建立。

要設定自動建立,包括以下的步驟:

  • 建立並登入 Docker Hub,以及目標網站;
  • 在目標網站中連接帳戶到 Docker Hub;
  • 在 Docker Hub 中 設定一個自動建立;
  • 選取一個目標網站中的專案(需要含 Dockerfile)和分支;
  • 指定 Dockerfile 的位置,並提交建立。

私有倉庫

建立

可以透過取得官方 registry 映像檔來建立一個本地倉庫供私人使用。

1
docker run -d -p 5000:5000 registry

使用者可以透過指定的參數來設定私有倉庫的位置,例如設定映像檔儲存到 Amazon S3 服務。

1
2
3
4
5
6
7
8
9
docker run \
-e SETTINGS_FLAVOR=s3 \
-e AWS_BUCKET=acme-docker \
-e STORAGE_PATH=/registry \
-e AWS_KEY=your-aws-key \
-e AWS_SECRET=your-aws-secret \
-e SEARCH_BACKEND=sqlalchemy \
-p 5000:5000 \
registry

還可以指定某個路徑下的設定檔案。

1
sudo docker run -d -p 5000:5000 -v /home/user/registry-conf:/registry-conf -e DOCKER_REGISTRY_CONFIG=/registry-conf/config.yml registry

預設情況下,倉庫會被建立在容器的 /tmp/registry 下。可以透過 -v 參數來將映像檔檔案存放在本地的指定路徑。

1
docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry

建立

使用 docker tag 指令,標記這個映像檔為遠端的映像檔,格式為 [REGISTRYHOST/][USERNAME/]NAME[:TAG]

1
docker tag ubuntu:latest localhost:5000/test

上傳與下載

使用 docker push 指令,上傳標記的映像檔。

1
docker push localhost:5000/test

使用 docker pull 指令,下載標記的映像檔。

1
docker pull localhost:5000/test

參考資料