Docker
Docker 是一種打包、傳輸和運行任何程序作為輕量級容器的實用工具.
安裝[編輯 | 編輯原始碼]
要拉取Docker鏡像並運行Docker容器,你需要安裝Docker引擎,其包含包括一個守護進程來管理容器,以及一個docker
命令行界面前端。安裝 docker包 包 或者,對於開發版本,選擇docker-gitAUR 包. 下一步啟動 docker.service
或者 docker.socket
。兩者的差距在於docker.service
將會在開機時啟動,而docker.socket
將會在第一次啟動Docker時啟動,使用後者可以減少開機啟動時間。然後驗證操作:
# docker info
注意, 如果你有一個活動的 VPN 連接, 那麼 docker 服務的啟動可能失敗, 因為 VPN 和 Docker 的網橋 IP 衝突以及網絡覆蓋. 如果發生了這種事, 嘗試在啟動 docker 服務之前斷開 VPN 連接. 你可以在之後立刻重連 VPN. 你也可以嘗試手動解決網絡衝突(也可參見[1]或[2])。
你也可以嘗試驗證是否可以運行容器。以下命令行將會下載一個最新的Arch Linux image,並使用其在這個容器中運行一個Hello World程序:
# docker run -it --rm archlinux bash -c "echo hello world"
如果你想以普通用戶身份運行docker的話,添加你自己到 docker
用戶組,重新登錄並重啟docker.service
如果你還要使用 Docker 構建容器鏡像,請安裝docker-buildx包以使用新版構建器(否則會使用已棄用的舊版構建器)。
Docker Compose[編輯 | 編輯原始碼]
Docker Compose是另一種Docker引擎的CLI前端,它使用compose.yaml
YAML文件來指定容器的屬性,這樣就可以不使用附帶指令的docker run
腳本了.如果你需要經常設置或者使用具有複雜選項的容器,可能使用docker-compose更為方便.你需要安裝 docker-compose包來使用.
Docker Desktop[編輯 | 編輯原始碼]
Docker Desktop是一個專有的桌面應用程式,它在一個Linux虛擬機中運行Docker。它還包括Kubernetes集群以及一個漏洞掃描器。這個應用程式對於在macOS或Windows上進行開發Docker容器的團隊非常友好。Docker Desktop適配的Linux版本相對較新,同時也保持了對Docker CLI的良好兼容[3]。
Docker直接為Arch Linux提供了一個實驗性的軟體包(參見其官方文檔手動安裝Docker一節)。需要注意其手動下載的軟體包會與docker-compose包以及docker-buildx包衝突,你需要在安裝前手動移除這兩個包。如果你想保留現有的軟體包,你也可以從AUR安裝docker-desktopAUR,它將不會與現有軟體包發生衝突。
此外,在運行Docker Desktop之前,你需要確保你已經安裝了所有的在Linux上運行的最小系統要求,包括使用KVM進行虛擬化技術支援。對於Gnome用戶,你還需要安裝gnome-shell-extension-appindicator包以顯示托盤圖標。
最後,請注意文件共享功能是通過/etc/subuid
和/etc/subgid
映射用戶和組ID完成的。詳細參見Docker Desktop的Linux文件共享說明。
desktop-linux
。
這意味著在安裝前,部署在Linux Docker引擎上的所有鏡像與容器都無法在Docker Desktop中使用。[4]此外,由於Docker Desktop是在VM上啟動的,相比直接使用Docker引擎,預期性能會下降並且 CPU 使用率會提高。
GUI 工具[編輯 | 編輯原始碼]
- ducker包 — 一個用於管理docker容器的終端應用程式。
- oxker-binAUR — 一個簡單的 TUI程序,用於查看和控制 Docker 容器。
- lazydockerAUR — 一個簡單的 docker 和 docker-compose 管理TUI程序,使用 Go 語言和 gocui 庫編寫。
- dokoAUR — 一個簡單的docker TUI程序。
- gomanagedockerAUR — 一款用於管理 Docker 對象的 TUI 程序。
- dockstationAUR — 輕鬆管理 Docker。
- whaler-gitAUR — 為 Pantheon 設計的 Docker 容器管理。
- podman-desktopAUR — 從單一的用戶界面和托盤管理 Podman以及其他容器引擎。
- portainer-binAUR — 一款輕量級的 Docker 管理用戶界面。
- kitematicAUR — 可視化Docker 容器管理。
使用[編輯 | 編輯原始碼]
Docker由多個部分組成:
- Docker守護進程(也稱Docker引擎),這是一個以
docker.service
形式運行的進程。其提供了Docker API接口並管理Docker容器。
docker
CLI命令,其允許用戶使用命令行來與Docker API交互,並控制 Docker 守護進程。
- Docker容器,這是一種命名進程,由Docker守護進程通過Docker API的請求進行管理。
一般來說,用戶通過使用docker
命令行來對Docker進行操作,命令行又通過Docker API對Docker守護進程發起請求以執行對容器的相關操作。掌握客戶端 (docker
), 服務端(docker.service
)和容器之間的關係是很必要的。
請注意,如果Docker守護進程停止/重啟,那麼當前運行的所有Docker容器也會停止/重啟。
你也可以不藉助docker
CLI來對Docker API發起請求來控制容器,參見Docker API開發指南。
更多使用文檔請參見Docker入門指南。
配置[編輯 | 編輯原始碼]
Docker守護進程可以通過修改配置文件/etc/docker/daemon.json
或者直接在docker.service
中添加命令行標誌來進行配置。根據Docker官方文檔, 推薦使用修改配置文件的方法進行配置。如果你想使用添加命令行標誌的方法進行配置,使用Systemd#附加配置片段覆蓋docker.service
中的ExecStart
部分。
對於daemon.json
中的選項,參見守護進程配置文件參考。
存儲驅動程序[編輯 | 編輯原始碼]
存儲驅動程序控制著Docker主機上的鏡像與容器的儲存與管理方式。默認的overlay2
驅動在大部分情況下都具有良好的性能。
如果你的文件系統使用的是btrfs或者ZFS,你可以使用對應的btrfs
或者zfs
驅動,它們可以利用這些文件系統獨有的功能,要使用這些驅動請參見btrfs驅動或zfs驅動文檔。
啟用守護進程TCP套接字[編輯 | 編輯原始碼]
默認情況下,Docker守護進程使用位於/var/run/docker.sock
的Unix套接字來提供Docker API。大部分情況下,這是一個合適的選擇。
你可以將設置守護進程設置為額外監聽TCP套接字,這樣就能使Docker API被遠程訪問了(參見允許遠程訪問Docker API)。如果你在Windows或macOS上使用Arch虛擬機,你可以在完成設置後使用宿主機上直接使用docker
命令行訪問虛擬機中允許的Docker守護進程。
注意默認的docker.service
設置了-H
標誌,如果選項同時存在於標誌與/etc/docker/daemon.json
文件中,Docker將不會啟動,因此最簡單的更改監聽TCP套接字設置的方法是使用一個附加文件。例如,如果你想在埠2376添加一個TCP套接字:
/etc/systemd/system/docker.service.d/docker.conf
[Service] ExecStart= ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376
重載systemd守護進程並重啟 docker.service
以應用更改。
HTTP代理[編輯 | 編輯原始碼]
要想在Docker中使用HTTP代理,你需要同時對Docker守護進程以及Docker容器進行配置。
Docker守護進程代理設置[編輯 | 編輯原始碼]
參見Docker文檔:配置Docker守護進程使用HTTP代理。
Docker容器代理設置[編輯 | 編輯原始碼]
參見Docker文檔:如何配置代理,使用docker
CLI來自動為所有容器配置代理。
配置DNS[編輯 | 編輯原始碼]
參見Docker中網絡配置了解Docker容器內部的DNS行為以及如何自定義Docker的DNS配置信息。一般來說,主機上的配置也會直接配置到容器中。
大部分託管在127.0.0.0/8
上的DNS解析器都是不被支持的(由於容器和主機網絡命名空間之間的衝突)。這些解析器會在容器中的/etc/resolv.conf中刪除。如果這導致了/etc/resolv.conf
為空文件,容器將會使用Google DNS。
此外,如果127.0.0.53
是唯一的名稱伺服器,在這種特定的情況下Docker會假設解析器是systemd-resolved並使用來自/run/systemd/resolve/resolv.conf
的上游DNS解析器。
如果你使用dnsmasq來提供一個本地解析器,考慮為dnsmasq添加一個虛擬接口(使用169.254.0.0/16
網段的鏈路本地IP位址來綁定,而不是127.0.0.1
)以避免網絡命名空間衝突。
鏡像位置[編輯 | 編輯原始碼]
默認,docker鏡像放置在 /var/lib/docker
。他們可以被移動到其他分區,例如你想將鏡像移動到別的磁碟上,在這個例子中,假設我們要將鏡像移動到/mnt/docker
。
首先, 停止docker.service
,注意,這也會停止所有當前運行的容器並卸載任何正在運行的鏡像。
如果你正在運行docker鏡像,你必須確定鏡像被完全解除掛載。一旦這個完成後,你就可以把鏡像從 /var/lib/docker
移動到你的目標地點。在這個例子中使用指令cp -r /var/lib/docker /mnt/docker
。
在/etc/docker/daemon.json
中配置data-root
:
/etc/docker/daemon.json
{ "data-root": "/mnt/docker" }
重啟docker.service
以應用更改。
不安全的自建倉庫[編輯 | 編輯原始碼]
如果您使用自簽名證書的倉庫(registries),或該自建倉庫未使用TLS加密(即:http), docker會拒絕它直到你定義你相信它.
例如,要信任託管於myregistry.example.com:8443
上的鏡像,在文件/etc/docker/daemon.json
中配置insecure-registries
的值:
/etc/docker/daemon.json
{ "insecure-registries": [ "my.registry.example.com:8443" ] }
隨後重新加載 docker.service
配置。
IPv6[編輯 | 編輯原始碼]
首先,將/etc/docker/daemon.json
中的ipv6
設置為啟用並設置一個特定的IPV6子網(即使用私有的fd00::/80
子網)。請確保至少使用80位的子網,因為這樣可以使容器的IPv6地址以容器的MAC地址結尾,這有助於解決NDP鄰居緩存失效的問題。
/etc/docker/daemon.json
{ "ipv6": true, "fixed-cidr-v6": "fd00::/80" }
重啟 docker.service
以應用更改。
最後,為了讓容器能夠訪問主機網絡,你需要添加IPv6 NAT以解決使用私有IPv6子網時出現的路由問題:
# ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADE
現在Docker應該已經開啟了IPv6支持,你可以使用以下指令來進行測試:
# docker run curlimages/curl curl -v -6 archlinux.org
如果你使用firewalld,你還需要添加防火牆規則,例如:
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv6" destination not address="fd00::1/80" source address="fd00::/80" masquerade'
如果你使用ufw,你還需要根據Uncomplicated Firewall#轉發策略創建Ipv6轉發。
首先,你需要編輯/etc/default/ufw
並取消以下幾行的注釋:
/etc/ufw/sysctl.conf
net/ipv6/conf/default/forwarding=1 net/ipv6/conf/all/forwarding=1
現在你可以使用以下命令添加iptables規則:
# ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADE
如果你使用docker-compose來創建的容器,你可能還需要在networks
中對應的部分設置enable_ipv6: true
。另外,你可能還需要手動指定IPv6子網,參見compose-file中的ipv6地址設置。
用戶命名空間隔離[編輯 | 編輯原始碼]
默認情況下,Docker中的進程和dockerd
主守護程序運行在同一用戶命名空間中,即容器不會通過用戶命名空間隔離(參見user_namespaces(7))。這將會允許進程根據用戶和用戶組#權限與屬主在主機上來訪問已配置的資源。這樣提升了容器運行的兼容性,但是一旦出現了一個允許容器中進程訪問非預期資源的漏洞,這會帶來很大的安全隱患。(一個這樣的漏洞在2019年2月發布並修補。)
啟用用戶命名空間隔離可以降低此類漏洞的影響。其將會在單獨的用戶命空間中運行每個容器,並將這個空間中的UIDs/GIDs映射到主機上不同的(通常情況下也是非特權的)UIDs/GIDs。
- 主
dockerd
守護程序依然是以root
身份在主機上運行的,在非root身份下運行docker(rootless mode)是另一個功能。 - 容器中的進程將會以Dockerfile中定義的USER指令定義的用戶身份啟動。
- 所有容器都會映射到相同的UID/GID範圍,這是為了讓容器之間的共享卷功能生效。
- 在一些情況下無法啟用用戶命名空間。
- 由於 Docker 需要調整這些資源的所有權,因此啟用用戶命名空間隔離會有效屏蔽現有的映像層和容器層,以及
/var/lib/docker/
中的其他 Docker 對象。上游文檔建議僅在新安裝的Docker上啟用此功能,而不是在現有的Docker上啟用。
在/etc/docker/daemon.json
中配置userns-remap
的值。default
是一個特殊值,其會自動創建名為dockremap
的用戶與用戶組用於重映射。
/etc/docker/daemon.json
{ "userns-remap": "default" }
在/etc/subuid
和/etc/subgid
中配置用戶名/組名,UID/GID的範圍。在這個例子中,dockremap
用戶/用戶組分配為從165536開始的65536個UIDs/GIDs。
/etc/subuid
dockremap:165536:65536
/etc/subgid
dockremap:165536:65536
重啟docker.service
以應用更改。
應用此更改後,默認情況下所有容器都將在隔離的用戶命名空間中運行。你也可以在docker
命令中加上添加標誌--userns=host
來在特定的容器中禁用用戶命名空間隔離,參見[7]。
無根模式運行Docker守護程序(Docker rootless)[編輯 | 編輯原始碼]
CONFIG_USER_NS_UNPRIVILEGED
)。在linux包, linux-lts包, 和linux-zen包內核中默認啟用這一功能。如果你使用其他版本的內核,你可能需要手動啟用這一功能。這可能帶來一些安全隱患,參見安全#沙盒程序。要將Docker守護程序作為普通用戶運行,安裝 docker-rootless-extrasAUR軟體包。
隨後在/etc/subuid
與/etc/subgid
中配置用戶名/用戶組名,起始 UID/GID 和 UID/GID 範圍大小,以分配重新映射的用戶和組。以下是一個示例:
/etc/subuid
your_username:165536:65536
/etc/subgid
your_username:165536:65536
啟用 docker.socket
systemd/用戶單元: 這將會使用systemd的套接字激活來啟動docker。
最後設置docker套接字的環境變量:
$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
啟用本地覆蓋差異引擎(native overlay diff engine)[編輯 | 編輯原始碼]
默認情況下Docker無法在Arch Linux上使用本地覆蓋差異引擎(native overlay diff engine),這會導致構建Docker鏡像很慢。如果你經常構建鏡像,請按照以下步驟配置:
/etc/modprobe.d/disable-overlay-redirect-dir.conf
options overlay metacopy=off redirect_dir=off
隨後停止docker.service
, 重新加載overlay
內核模塊:
# modprobe -r overlay # modprobe overlay
重載內核模塊後,啟動docker.service
。
要驗證是否成功啟用,你可以運行docker info
檢查Native Overlay Diff
值是否為true
。
鏡像[編輯 | 編輯原始碼]
Arch Linux[編輯 | 編輯原始碼]
下面的命令會拉取 archlinux x86_64 image.這是一個arch內核的剝離版本,沒有網絡等等.
# docker pull archlinux
也可查閱 README.md.
對於完整的arch基礎,可以從下面克隆鏡像並且建立你自己的鏡像.
$ git clone https://gitlab.archlinux.org/archlinux/archlinux-docker.git
請確保devtools包, fakechroot包以及fakeroot包軟體包已被安裝。
編輯包文件讓它只含有 '基礎'. 運行:
# make docker-image
Alpine Linux[編輯 | 編輯原始碼]
Alpine Linux是一個熱門的小型容器鏡像,其比較適合運行靜態二進位形式軟體。使用以下命令來拉取最新的Alpine Linux鏡像:
# docker pull alpine
Alpine Linux使用musl libc實現,這有區別與大部分的Linux發行版使用的glibc libc實現。 由於Arch Linux使用的glibc,因此Arch Linux主機與Alpine Linux容器之間存在有功能差異,這可能會影響軟體性能或正確性。你可以在此處查看存在的差異。
注意,在Arch Linux(或其他沒有使用musl libc實現的發行版)上編譯的動態連結軟體在Alpine Linux (或其他使用musl libc的鏡像)上可能會出現錯誤或性能問題。參見[8], [9]和[10]。
Debian[編輯 | 編輯原始碼]
下面的命令會拉取Debian鏡像 debian x86_64 image.
# docker pull debian
請參閱Docker Hub頁面查看可用標籤的完整列表,包括每個Debian版本的標準版與精簡版。
手動[編輯 | 編輯原始碼]
用 debootstrap包建立Debian鏡像:
# mkdir jessie-chroot # debootstrap jessie ./jessie-chroot http://http.debian.net/debian/ # cd jessie-chroot # tar cpf - . | docker import - debian # docker run -t -i --rm debian /bin/bash
Distroless[編輯 | 編輯原始碼]
Google 維護著distroless鏡像,這是沒有基本作業系統組件(例如shells和包管理器)的最小化鏡像。其最小鏡像gcr.io/distroless/static-debian11
僅有2MiB左右,可以用於打包軟體並生成非常小的鏡像。
請參閱GitHub中的README以獲得鏡像列表以及在不同程式語言中的使用方法。
有用的建議[編輯 | 編輯原始碼]
抓取運行容器的IP位址[編輯 | 編輯原始碼]
抓取運行容器的IP位址:
$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container-name OR id>
172.17.0.37
每個正在運行的容器,它們的名字和相關IP位址都能被列出來在 /etc/hosts
裡用:
#!/usr/bin/env sh for ID in $(docker ps -q | awk '{print $1}'); do IP=$(docker inspect --format="{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" "$ID") NAME=$(docker ps | grep "$ID" | awk '{print $NF}') printf "%s %s\n" "$IP" "$NAME" done
運行容器中的圖像程序[編輯 | 編輯原始碼]
本節介紹了允許在主機的X伺服器上運行圖形程序(包括依賴於OpenGL或Vulkan的程序)所需的步驟。
首先,需要在容器內安裝與主機圖形硬體兼容的正確驅動程序。如果容器使用的Arch Linux鏡像,請參見OpenGL#安裝或 Vulkan#安裝來安裝對應的驅動。
接下來,你需要授予容器訪問主機上X服務的權限。在單用戶環境中,你可以通過在主機中運行Xhost來完成這一操作。該命令將非網絡本地連接添加到訪問控制列表:
$ xhost +local:
最後,你需要在docker run
中傳遞以下參數:
-e "DISPLAY=$DISPLAY"
將環境變量DISPLAY
設置為主機顯示器;--mount type=bind,src=/tmp/.X11-unix,dst=/tmp/.X11-unix
將主機X伺服器套接字掛載到相同路徑下的容器內;--device=/dev/dri:/dev/dri
允許容器直接訪問主機上的直接渲染(DRI) 設備。
為了驗證設置是否生效,請在容器中運行mesa-utils包中的glxgears
命令(或者vulkan-tools包中的vkcube
命令)。
開機啟動 Docker Compose 項目[編輯 | 編輯原始碼]
首先,創建一個用於Docker Compose的Systemed單元,並通過服務名稱進行參數化(參見systemd.service(5) § SERVICE TEMPLATES):
/etc/systemd/system/docker-compose@.service
[Unit] Description=%i service with docker compose Requires=docker.service After=docker.service [Service] WorkingDirectory=/opt/%i ExecStartPre=-/usr/bin/docker compose pull ExecStart=/usr/bin/docker compose up --remove-orphans ExecStop=/usr/bin/docker compose down ExecReload=/usr/bin/docker compose pull ExecReload=/usr/bin/docker compose up --remove-orphans [Install] WantedBy=multi-user.target
隨後,對於你想運行的每一個服務,在/opt/project_name
目錄下新建一個包含Compose文件以及其他所需文件(例如.env
文件)[13]。
最後, 啟用/啟動 docker-compose@project_name.service
。
使用buildx進行交叉編譯[編輯 | 編輯原始碼]
buildx CLI 插件使用了新的BuildKit構建工具包。安裝docker-buildx包,buildx接口支持構建多平台鏡像(包括與主機不同的框架)。
交叉編譯鏡像也需要QEMU。如果你想在Docker中設置靜態版本的QEMU,請參見multiarch/qemu-user-static 鏡像。否則請在主機上設置QEMU與Docker共同使用(參見QEMU#從 x86_64 環境中 Chroot 至 arm/arm64 環境)。無論哪種情況,你的系統都將配置為對客戶端架構進行用戶模式模擬。
$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS default * docker default default running linux/amd64, linux/386, linux/arm64, linux/riscv64, linux/s390x, linux/arm/v7, linux/arm/v6
用NVIDIA GPU運行GPU加速的Docker容器[編輯 | 編輯原始碼]
從19.03版本開始,Docker原生支持NVIDIA GPU作為Docker設備。 推薦使用NVIDIA Container Toolkit來運行需要操作NVIDIA顯卡的容器。
安裝 nvidia-container-toolkit包 包並重啟Docker。之後可以用--gpus
選項來運行使用NVIDIA顯卡的容器
使用 --gpus 選項(推薦)[編輯 | 編輯原始碼]
# docker run --gpus all nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
指定容器內可使用多少GPU:
# docker run --gpus 2 nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
指定使用哪一個GPU:
# docker run --gpus '"device=1,2"' nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
或
# docker run --gpus '"device=UUID-ABCDEF,1"' nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
如果在執行指令時收到錯誤Failed to initialize NVML: Unknown Error
,你可以嘗試詳細指定GPU來解決這個問題:
# docker run --gpus all --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm --device /dev/nvidia0:/dev/nvidia0 nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
指定需要的具體功能(圖像、計算等)
# docker run --gpus all,capabilities=utility nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
使用 NVIDIA Container Runtime[編輯 | 編輯原始碼]
編輯/etc/docker/daemon.json
以註冊NVIDIA運行時環境。
/etc/docker/daemon.json
{ "runtimes": { "nvidia": { "path": "/usr/bin/nvidia-container-runtime", "runtimeArgs": [] } } }
之後重啟 Docker。
運行時也可以通過dockerd的一個命令行選項來註冊。
# /usr/bin/dockerd --add-runtime=nvidia=/usr/bin/nvidia-container-runtime
完成後可通過命令啟動GPU加速的容器:
# docker run --runtime=nvidia nvidia/cuda:9.0-base nvidia-smi
或 (要求 Docker 版本19.03或更高)
# docker run --gpus all nvidia/cuda:9.0-base nvidia-smi
參閱 README.md。
有CUDA的 Arch Linux 鏡像[編輯 | 編輯原始碼]
可使用以下Dockerfile
構建自定義的有CUDA的 Arch Linux 鏡像。它使用 Dockerfile frontend syntax 1.2 在宿主機上緩存pacman包。請注意,你必須在構建鏡像之前設置環境變量DOCKER_BUILDKIT=1
。
Dockerfile
# syntax = docker/dockerfile:1.2 FROM archlinux # 使用更快的镜像 RUN echo 'Server = https://mirror.pkgbuild.com/$repo/os/$arch' > /etc/pacman.d/mirrorlist # 安装包 RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman \ pacman -Syu --noconfirm --needed base base-devel cuda # 配置 nvidia container runtime # https://github.com/NVIDIA/nvidia-container-runtime#environment-variables-oci-spec ENV NVIDIA_VISIBLE_DEVICES all ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
移除docker和鏡像[編輯 | 編輯原始碼]
如果你想完全移除Docker,你可以通過下面的步驟完成:
檢查正在運行的容器:
# docker ps
列出在主機運行的所有容器,為刪除做準備:
# docker ps -a
停止一個運行的容器:
# docker stop <CONTAINER ID>
殺死還在運行的容器:
# docker kill <CONTAINER ID>
通過ID刪除列出的所有容器:
# docker rm <CONTAINER ID>
列出所有的docker鏡像:
# docker images
通過ID刪除所有鏡像:
# docker rmi <IMAGE ID>
刪除所有與容器沒有關聯的鏡像,容器,卷與網絡(懸空):
# docker system prune
要刪除所有停止的容器和所有未使用的鏡像(而不只是懸空鏡像),添加-a
標誌:
# docker system prune -a
刪除所有docker數據 (清除目錄):
# rm -R /var/lib/docker
故障排除[編輯 | 編輯原始碼]
使用systemd-networkd時,docker0 網橋無法獲取 IP / Internet 到容器[編輯 | 編輯原始碼]
Docker會自己啟用IP轉發,但是默認 systemd-networkd 會覆蓋對應的sysctl設置,在網絡配置文件裡設置 IPForward=yes
。查閱網絡分享#啟用包轉發獲取細節。
當systemd-networkd嘗試管理由Docker創建的網絡時,如果你在Match
部分設置了Name=*
或Type=ether
,這可能會導致網絡連接出現問題。請更為具體地配置接口,即儘可能避免使用Name=*
,Type=ether
等通配符來匹配Docker管理的接口。你可以驗證 networkctl list
是否在 Docker 創建的所有網絡的 SETUP 欄中設置為 unmanaged
。
默認的允許的進程/線程數太少[編輯 | 編輯原始碼]
如果你允許時得到下面的錯誤信息
# e.g. Java java.lang.OutOfMemoryError: unable to create new native thread # e.g. C, bash, ... fork failed: Resource temporarily unavailable
那麼你可能需要調整被systemd允許的進程數, 編輯並添加下面片段 docker.service
:
# systemctl edit docker.service
[Service] TasksMax=infinity
對於更多參數,例如 DefaultLimitNPROC
,請參閱 systemd-system.conf(5) § OPTIONS。對於 TasksMax
請參閱 systemd.resource-control(5) § OPTIONS。
初始化顯卡驅動錯誤: devmapper[編輯 | 編輯原始碼]
如果 systemctl 不能開啟docker並提供了以下信息:
Error starting daemon: error initializing graphdriver: devmapper: Device docker-8:2-915035-pool is not a thin pool
那麼嘗試以下步驟來解決錯誤。停止docker服務,備份 /var/lib/docker/
(如果需要的話), 移除/var/lib/docker/
的內容, 嘗試重啟docker服務. 查閱 GitHub issue 獲取更多細節.
無法創建到某文件的路徑: 設備沒有多餘的空間了[編輯 | 編輯原始碼]
如果你獲取到的錯誤信息是像這樣的話:
ERROR: Failed to create some/path/to/file: No space left on device
當創建或者運行Docker鏡像時,儘管磁碟還有多餘的空間。所以請確保:
- Tmpfs 被禁用了並且有足夠的內存分配. Docker可能會嘗試寫入文件到
/tmp
但是失敗了因為內存使用的限制和磁碟空間不足. - 如果你在使用 XFS, 你可能得從相關入口移除
noquota
掛載選項在/etc/fstab
裡 (通常是/tmp
和/或/var/lib/docker
在的地方). 查閱 Disk quota 獲取更多信息, 特別是你計劃使用和調整overlay2
Docker 存儲驅動. - XFS 的配額掛載選項在文件系統重新掛載時 (
uquota
,gquota
,prjquota
, 等等.) 失敗了. 為了為root文件系統啟用配額掛載選項必須作為內核參數rootflags=
傳遞到initramfs. 之後, 它就不應該在/etc/fstab
中的掛載選項中列出root (/
) 文件系統.
Docker-machine無法使用virtualbox驅動程序創建虛擬機[編輯 | 編輯原始碼]
如果docker-machine 無法使用 virtualbox 驅動程序創建虛擬機並提供了以下信息:
VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
嘗試在CLI中使用vboxreload
重啟virtualbox。
啟動Docker後會破壞KVM的橋接網絡[編輯 | 編輯原始碼]
這是因為啟動Docker的腳本會添加一些iptables規則,其會阻止除自身外的其他接口進行轉發。這是一個已知問題。
您可以嘗試以下的解決方案(請將br0替換為您自己的橋接網絡名稱):
- 最快的解決方案(但是這會關閉所有Docker自動添加的iptables規則):
/etc/docker/daemon.json
{ "iptables": false }
- 如果您已經配置好了用於KVM的橋接網絡,您也可以通過修改Docker的配置文件來解決這個問題,參見[17]將配置文件修改為:
/etc/docker/daemon.json
{ "bridge": "br0" }
- 如果上述方法無效,或者您希望直接通過iptables或者類似於UFW的管理器來解決問題,請添加以下內容:
iptables -I FORWARD -i br0 -o br0 -j ACCEPT
更詳細的解決方案可以參見此處。
從Docker Hub拉取的鏡像受到速率限制[編輯 | 編輯原始碼]
從2020年11月1日開始,Docker Hub限制了匿名用戶以及免費帳戶用戶的下載速率,詳細請參見速率限制文檔。
匿名用戶的速率限制通過IP進行跟蹤,免費帳戶用戶的速率限制通過帳戶進行跟蹤。
如果你需要更高的下載速率,你可以註冊付費計劃或者將你需要的鏡像拉取到不同的鏡像倉庫。你可以自建鏡像倉庫或者使用雲託管的鏡像站點,例如 Amazon ECR, Google Container Registry, Azure Container Registry 或 Quay Container Registry。
使用Docker CLI 中的 pull
, tag
以及 push
命令來鏡像一個鏡像。例如,將 Nginx 標籤(tag)為 1.19.3
的鏡像鏡像到託管於 cr.example.com
上的倉庫:
$ docker pull nginx:1.19.3 $ docker tag nginx:1.19.3 cr.example.com/nginx:1.19.3 $ docker push cr.example.com/nginx:1.19.3
隨後你可以從鏡像倉庫中拉取並運行鏡像:
$ docker pull cr.example.com/nginx:1.19.3 $ docker run cr.example.com/nginx:1.19.3
錯誤提示:iptables (舊版): 未知選項 "--dport"[編輯 | 編輯原始碼]
如果你在運行容器時收到了這樣的錯誤:
iptables (legacy): unknown option "--dport"
安裝 iptables-nft包 而不是 iptables包 (舊版) 然後重啟[18]。
運行docker login時提示"密碼以非加密形式儲存"[編輯 | 編輯原始碼]
默認情況下 Docker 會嘗試使用 pass
或者 secretservice
的二進位形式文件來儲存你的註冊表密碼。如未能找到這些文件,註冊表秘密將以明文形式(base64編碼)儲存在 $HOME/.docker/config.json
,並在登錄成功後提示:
$ WARNING! Your password will be stored unencrypted in /home/username/.docker/config.json.
如果你在使用支持 Secret Service Freedesktop DBUS API 的密碼管理器,例如KDE的 kwallet包 或著 GNOME的 gnome-keyring包,你可以安裝 docker-credential-secretserviceAUR 來讓你的註冊表密碼儲存在密碼管理器中。
"無法在默認選項中找到可用的,不重疊的IPv4地址池進行分配"[編輯 | 編輯原始碼]
如果你在使用大量的 Docker 項目 (例如使用 docker-compose),可能會出現Docker容器的可用IP位址不足的情況:
Could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
參見這個 Docker issue, 默認選項是:
Type | Default Size | Default Pool |
---|---|---|
local | /16 | 172.17.0.0/12 |
local* | /20 | 192.168.0.0/16 |
你可以在 /etc/docker/daemon.json
文件中修改 default-address-pools
,將其中第一個IP範圍的值從16改為24解決這個問題。為了避免本地網絡發生IP衝突,請不要修改第二個IP範圍的值。
/etc/docker/daemon.json
{ ... "default-address-pools" : [ { "base" : "172.17.0.0/12", "size" : 24 }, { "base" : "192.168.0.0/16", "size" : 24 } ] }
重啟 docker.service
以應用更改。
更多詳細信息和技術解釋請參見文章: Docker默認地址池選項的權威指南。
Golang編譯速度過慢[編輯 | 編輯原始碼]
由於ulimit配置的原因,使用makepkg構建docker鏡像以及其依賴時會非常緩慢(會在"Entering fakeroot environment..."處卡住)。
這是因為[19] [20],你可以嘗試將 --ulimit "nofile=1024:524288"
添加到你的docker構建選項中來解決問題:
/etc/docker/daemon.json
{ "default-ulimits": { "nofile": { "Name": "nofile", "Soft": 1024, "Hard": 524288 } } }