Docker 是仍依賴核心、CPU 指令集架構及其 x86-64 syscall 的容器系統。
在 Docker 容器中執行的應用程式稱為容器化應用程式。
元件概覽 #
Docker Engine:dockerd
#
dockerd 是管理本機系統已安裝容器的 CLI 常駐程式。
其品牌名稱為 Docker Engine 或 Docker CE(Community Edition),而且是開放原始碼的免費軟體。
dockerd 常駐程式會在 UNIX 網域通訊端 /var/run/docker.sock 上監聽傳入的用戶端。
執行 Docker 用戶端的使用者必須能夠讀取此通訊端檔案,才能建立通訊端連線(以傳送 HTTP 請求)。
若透過 Linux 發行版的套件管理員安裝 Docker Engine,此通訊端檔案可能只允許 root 或 Docker 專用的特殊使用者群組(例如 docker)讀取。
你可以選擇將自己加入該使用者群組,或在每次使用 docker 用戶端時直接切換為 root。
使用 docker info 檢查 dockerd 是否正在執行,以及用戶端是否具備權限。
dockerd 常駐程式公開管理容器的 HTTP API,任何程式都能使用。
官方用戶端程式是 docker CLI 程式。
Docker Desktop #
Docker Desktop 是專有的 GUI 用戶端程式,會與 dockerd 通訊並執行容器維護作業。
不一定要使用 Docker Desktop 應用程式。
Docker Compose #
https://docs.docker.com/compose/
Docker Compose 是另一個與 dockerd 通訊的 CLI 用戶端,其執行檔為 docker-compose。
它使用 docker-compose.yml 檔案指定容器屬性,無須反覆輸入 docker run 選項。
此方式適合設定經常使用及/或設定複雜的週期性服務。
映像檔 #
Docker 映像檔由多層檔案系統內容組成,每一層都會在上一層加入一些檔案。 若某個映像檔的第一層依賴另一個映像檔的所有層,就稱此前者以後者為基礎。
映像檔具有易讀的名稱 REPOSITORY 與易讀的 TAG(通常是版本號,但並非必要)。
稱為 IMAGE ID 的 SHA256 雜湊值可唯一識別映像檔。
若要建置自己的映像檔,請建立 Dockerfile,以簡單語法定義建立映像檔所需的步驟。
Dockerfile 中的每項指令都會在映像檔中建立一層。
修改 Dockerfile 並需要重新建置映像檔時,只會重新建置已變更的層。
例如,esolang/vim:latest 映像檔包含 10 層。
# $ Docker Pull Esolang/vim
Using default tag: latest
latest: Pulling from esolang/vim
4abcf2066143: Downloading 2.951MB/3.409MB
e7609a7fad9e: Download complete
a891a2921638: Download complete
6ea6322cdcb0: Download complete
729f825b6ae6: Download complete
e6cb43f5f474: Downloading 2.618MB/31.24MB
c12ed1c2e19b: Download complete
6928286dd6f6: Download complete
05de04103836: Download complete
b5a8264627eb: Download completeDocker 不會將 Dockerfile 儲存在建置完成的映像檔中,因此要檢查映像檔的建置方式會稍微困難。
原因在於,也可以透過執行容器、進行修改,再提交結果來建立映像檔。
事實上,可以將 Dockerfile 視為將「執行、修改、提交」流程自動化的指令碼。
最小映像檔 #
建置一個沒有基礎映像檔,也不含任何檔案系統內容(除了一個最小的 hello world 執行檔)的最小 Docker 映像檔:
; linux_syscall call_no, arg0, arg1, arg2, arg3, arg4, arg5
%macro linux_syscall 1-7 0,0,0,0,0,0
mov rax, %1
mov rdi, %2
mov rsi, %3
mov rdx, %4
mov r10, %5
mov r8, %6
mov r9, %7
syscall
%endmacro
SECTION .data
msg: db `hello world\n`
msglen: equ $-msg
GLOBAL main
SECTION .text
main:
; write to stdout a string
linux_syscall 1,1,msg,msglen
; exit the process with code 42
linux_syscall 0x3c, 42使用 make 建置執行檔:
main: main.o
# -N: don't align data segment on a new memory page, thus makes the executable as small as possible
ld -N -e manbaout -omain main.o
main.o: main.asm
nasm -f elf64 -o main.o main.asm
clean:
rm *.o main
使用下列 Dockerfile 建置映像檔:
FROM scratch
ADD main /docker build -t foo .在我的電腦上,這會產生僅 904 位元組的 Docker 映像檔(由 docker image ls 回報)。從該映像檔執行容器:
docker run foo ./main容器 #
容器是映像檔的執行中執行個體。容器的生命週期從 docker container create <image> 命令開始,接著執行 docker start <container>。docker run <image> 是同時執行兩者的簡寫;若本機不存在 <image>,它還會從設定的登錄檔(預設為 Docker Hub)下載映像檔。docker run 一律會從指定映像檔建立全新容器,然後啟動該容器。
若要使用既有但未啟用(已退出或暫停)的容器,請再次使用 docker start。
在任一特定時間點,Docker 容器會處於下列 6 種可能狀態之一。
- created:完整;容器建立後從未啟動。
- running:ENTRYPOINT 程序正在執行(精確而言,對它執行
wait(2)會阻塞)。 - Restarting:
- Exited(num):ENTRYPOINT 程序以 num 退出。
- Paused:
- Dead:
Dockerfile #
Dockerfile 僅定義了 17 項指令:
| 名稱 | |
|---|---|
| ADD | 加入本機或遠端檔案與目錄。 |
| ARG | 使用建置階段變數。 |
| CMD | 指定預設命令。 |
| COPY | 複製檔案與目錄。 |
| ENTRYPOINT | 指定預設執行檔。 |
| ENV | 設定環境變數。 |
| EXPOSE | 說明應用程式監聽的連接埠。 |
| FROM | 從基礎映像檔建立新的建置階段。 |
| HEALTHCHECK | 在啟動時檢查容器的健康狀態。 |
| LABEL | 為映像檔加入中繼資料。 |
| MAINTAINER | 指定映像檔作者。 |
| ONBUILD | 指定映像檔用於建置時所執行的指令。 |
| RUN | 執行建置命令。 |
| SHELL | 設定映像檔的預設 shell。 |
| STOPSIGNAL | 指定退出容器所用的系統呼叫訊號。 |
| USER | 設定使用者與群組 ID。 |
| VOLUME | 建立磁碟區掛載。 |
| WORKDIR | 變更工作目錄。 |
只有 RUN、COPY 與 ADD 指令會建立並保留在結果映像檔中的層。
多數指令會指示 docker image build 命令如何在結果的靜態映像檔中加入新的一層。
RUN命令是例外,它會在建置時立即執行外部命令。
務必區分在 docker image build 執行時立即執行的指令,以及指示 Docker 在從所建立映像檔實例化容器後應如何運作的指令。
CLI 速查表 #
# Show Active Container
docker container ls
# Show All Container Includes Dead One
docker container ls -a
# Stop Certain Containers
docker stop <cid1> <cid2> ...
# Stop All Active Containers
docker stop $(docker container ls –aq)
評論
在 GitHub 上閱讀或評論(發表評論需要登入)