出自 Arch Linux 中文维基

本文或本節需要翻譯。要貢獻翻譯,請訪問簡體中文翻譯團隊

附註: 請完成翻譯。(在 Talk:Docker# 中討論)

Docker 是一種打包、傳輸和運行任何程序作為輕量級容器的實用工具.

安裝

要拉取Docker鏡像並運行Docker容器,你需要安裝Docker引擎,其包含包括一個守護進程來管理容器,以及一個docker命令行界面前端。安裝 docker 包 或者,對於開發版本,選擇docker-gitAUR 包. 下一步 啟動 docker.service 然後驗證操作:

# 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 組的用戶都和root用戶等價,因為他們可以通過# docker run --privileged來以root權限啟動容器。 查閱更多信息可訪問 這裡這裡.

Docker Compose

Docker Compose是另一種Docker引擎的CLI前端,它使用docker-compose.ymlYAML文件來指定容器的屬性,這樣就可以不使用附帶指令的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-compose。如果你想保留現有的軟體包,你也可以從AUR安裝docker-desktopAUR,它將不會與現有軟體包發生衝突。

此外,在運行Docker Desktop之前,你需要確保你已經安裝了所有的在Linux上運行的最小系統要求,包括使用KVM進行虛擬化技術支援。對於Gnome用戶,你還需要安裝gnome-shell-extension-appindicator以顯示托盤圖標。

最後,請注意文件共享功能是通過/etc/subuid/etc/subgid映射用戶和組ID完成的。詳細參見Docker Desktop的Linux文件共享說明

使用

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驅動具有良好的性能,並且它在現代的Linux內核與文件系統上運行良好。還有一些較老的驅動程序,例如devicemapperaufs,它們旨在與舊版本的Linux內核兼容,但是在Arch Linux上對比起overlay2沒有任何優勢。

如果你的文件系統使用的是btrfs或者ZFS,你可以使用對應的btrfs或者zfs驅動,它們可以利用這些文件系統獨有的功能,要使用這些驅動請參見btrfs驅動zfs驅動文檔。

啟用守護進程TCP套接字

默認情況下,Docker守護進程使用位於/var/run/docker.sockUnix套接字來提供Docker API。大部分情況下,這是一個合適的選擇。

你可以將設置守護進程設置為額外監聽TCP套接字,這樣就能使Docker API被遠程訪問了(參見允許遠程訪問Docker API)。如果你在Windows或macOS上使用Arch虛擬機,你可以在完成設置後使用宿主機上直接使用docker命令行訪問虛擬機中允許的Docker守護進程。

警告: Docker API默認情況下是沒有加密以及身份驗證的。對Docker守護進程的TCP訪問等同於不安全的遠程root訪問。除非同時啟用了 TLS 加密和授權(通過認證的 HTTP 反向代理或適當的 附加Docker配置。一般來說,啟用Docker API TCP套接字應視為高風險操作。

注意默認的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文檔:設置systemd的drop-in單元以配置HTTP代理

Docker容器代理設置

參見Docker文檔:如何配置代理,使用dockerCLI來自動為所有容器配置代理。

配置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以應用更改。

不安全的註冊

如果你想用自簽名的證書, docker會拒絕它直到你定義你相信它. 例如,要信任託管於myregistry.example.com:8443上的鏡像,在文件/etc/docker/daemon.json中配置insecure-registries的值:

{{hc|/etc/docker/daemon.json|2= {

 "insecure-registries": [
   "my.registry.example.com:8443"
 ]

}

IPv6

為了開啟Docker中的IPv6支持,參見[4][5]

首先,將/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來在特定的容器中禁用用戶命名空間隔離,參見[6]

無根模式運行Docker守護程序(Docker rootless)

注意: 無根模式下運行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

Enable native overlay diff engine

本文或本章節的事實準確性存在爭議。

原因: This may not be necessary on your system. Though metacopy=on redirect_dir=on is the default on Arch Linux kernels, some report those settings getting disabled during runtime.(在 Talk:Docker#Native overlay diff 中討論)


By default, Docker cannot use the native overlay diff engine on Arch Linux, which makes building Docker images slow. If you frequently build images, configure the native diff engine as described in [7]:

/etc/modprobe.d/disable-overlay-redirect-dir.conf
options overlay metacopy=off redirect_dir=off

Then stop docker.service, reload the overlay module as follows:

# modprobe -r overlay
# modprobe overlay

You can then start docker.service again.

To verify, run docker info and check that Native Overlay Diff is 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 maintains distroless images which are minimal images without OS components such as package managers or shells, resulting in very small images for packaging software.

See the GitHub README for a list of images and instructions on their use with various programming languages.

有用的建議

抓取運行容器的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

Run graphical programs inside a container

This section describes the necessary steps to allow graphical programs (including those that rely on OpenGL or Vulkan) to run on the host's X server.

First, the correct drivers, compatible with the host's graphics hardware, need to be installed inside the container. The installation procedure depends on the type of the container, but for containers based on Arch Linux images, refer to OpenGL#Installation and Vulkan#Installation for packages specific to your hardware.

Next, the container must be granted access to the host's X server. In a single-user environment, this can easily be done by running Xhost on the host system, which adds non-network local connections to the access control list:

$ xhost +local:

Lastly, the following parameters need to be passed to docker run:

  • -e "DISPLAY=$DISPLAY" sets the environment variable DISPLAY within the container to the host's display;
  • --mount type=bind,src=/tmp/.X11-unix,dst=/tmp/.X11-unix mounts the host's X server sockets inside the container under the same path;
  • --device=/dev/dri:/dev/dri gives the container access to Direct Rendering Infrastructure devices on the host.

To confirm that everything is set up correctly, run glxgears from the package mesa-utils, or vkcube from the package vulkan-tools in the container.

Start Docker Compose projects on boot

本文或本章節的事實準確性存在爭議。

原因: This is not necessary with restart: always in the compose.yml. [11](在 Talk:Docker#"Start Docker Compose projects on boot" Spurious? 中討論)


First, create a template unit for Docker Compose which is parameterized by the name of the service (see 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

Then, for each service you would like to run, set up a directory with the Compose file and any other required files (such as .env files) at /opt/project_name. [12]

Then, enable/start docker-compose@project_name.service.

Using buildx for cross-compiling

The buildx CLI plugin makes use of the new BuildKit building toolkit. Install the docker-buildx package. The buildx interface supports building multi-platform images, including architectures other than that of the host.

QEMU is required to cross-compile images. To setup the static build of QEMU within Docker, see the usage information for the multiarch/qemu-user-static image. Otherwise, to setup QEMU on the host system for use with Docker, see QEMU#Chrooting into arm/arm64 environment from x86_64. In either case, your system will be configured for user-mode emulation of the guest architecture.

$ 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容器

使用NVIDIA Container Toolkit (推薦)

從19.03版本開始,Docker原生支持NVIDIA GPU作為Docker設備。 推薦使用NVIDIA Container Toolkit來運行需要操作NVIDIA顯卡的容器。 安裝 nvidia-container-toolkitAUR 包並重啟Docker。之後可以用--gpus選項來運行使用NVIDIA顯卡的容器

# 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

本文或本章節的事實準確性存在爭議。

原因: More information on when the following error happens is needed. It should work, see [13][失效連結 2023-04-23 ⓘ].(在 Talk:Docker#GPU accelerated Docker Nvidia 中討論)


If, when using the above commands, you receive an error such as Failed to initialize NVML: Unknown Error, you can try being more specific in specifying the 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

參閱 README.mdWiki.

If you have VirtualGL installed and get the NVML error, replace

/etc/nvidia-container-runtime/config.toml
#user = "root:video"

with

user = "root:root"

For more information see the issue at NVIDIA/nvidia-docker at GitHub

使用 NVIDIA Container Runtime

安裝 nvidia-container-runtimeAUR 包. 之後,編輯/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.

使用 nvidia-docker (已廢棄)

nvidia-docker is a wrapper around NVIDIA Container Runtime which registers the NVIDIA runtime by default and provides the nvidia-docker command.

To use nvidia-docker, install the nvidia-dockerAUR package and then 重啟 docker. Containers with NVIDIA GPU support can then be run using any of the following methods:

# docker run --runtime=nvidia nvidia/cuda:9.0-base nvidia-smi
# nvidia-docker run nvidia/cuda:9.0-base nvidia-smi

or (required Docker version 19.03 or higher)

# docker run --gpus all nvidia/cuda:9.0-base nvidia-smi
注意: nvidia-docker 是直到Docker 19.03版本,運行 NVIDIA GPU加速的容器的遺留方法,已被廢棄。如果使用19.03版本或更高Docker,建議使用NVIDIA Container Toolkit 替代。

有CUDA的 Arch Linux 鏡像

可使用以下Dockerfile 構建自定義的有CUDA的 Arch Linux 鏡像。它使用 Dockerfile frontend syntax 1.2 在宿主機上緩存pacman包。DOCKER_BUILDKIT=1 environment variable 必須於構建鏡像之前設置。

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>

Delete all images, containers, volumes, and networks that are not associated with a container (dangling):

# docker system prune

To additionally remove any stopped containers and all unused images (not just dangling ones), add the -a flag to the command:

# docker system prune -a

刪除所有docker數據 (清除目錄):

本文或本章節的事實準確性存在爭議。

原因: 執行 # rm -R /var/lib/docker 將會留下已刪除容器的btrfs子卷(在 Talk:Docker 中討論)


# rm -R /var/lib/docker

故障排除

使用systemd-networkd時,docker0 網橋無法獲取 IP / internet 到容器

Docker會自己啟用IP轉發,但是默認 systemd-networkd 會覆蓋對應的sysctl設置. 在網絡配置文件裡設置 IPForward=yes . 查閱 Internet sharing#Enable packet forwarding 獲取細節.

When systemd-networkd tries to manage the network interfaces created by Docker, e.g. when you configured Name=* in the Match section, this can lead to connectivity issues. The problem should be solved by matching interfaces more specifically, i.e. avoid using Name=* or other wildcard that matches an interface managed by Docker. Verify that networkctl list reports unmanaged in the SETUP column for all networks created by Docker.

注意:
  • 你可能需要在每次 restart systemd-networkd.service 或者 iptables.service 之後手動重啟 docker.service.
  • Also be aware that nftables may block docker connections by default. Use nft list ruleset to check for blocking rules. nft flush chain inet filter forward removes all forwarding rules temporarily. Edit /etc/nftables.conf to make changes permanent. Remember to restart nftables.service to reload rules from the configuration file. See [14] for details about nftables support in Docker.

默認的允許的進程/線程數太少

如果你允許時得到下面的錯誤信息

# e.g. Java
java.lang.OutOfMemoryError: unable to create new native thread
# e.g. C, bash, ...
fork failed: Resource temporarily unavailable

那麼你可能需要調整被systemd允許的進程數. 默認的是 500 (see system.conf), 這對需要允許幾個容器的話太少了. Edit 並添加下面片段 docker.service :

# systemctl edit docker.service
[Service]
TasksMax=infinity

初始化顯卡驅動錯誤: 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 (/) 文件系統.
注意: XFS配額和標準LinuxDisk quota, [15] 是有區別的。這裡值得一讀.

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。

Starting Docker breaks KVM bridged networking

The issue is that Docker's scripts add some iptables rules to block forwarding on other interfaces other than its own. This is a known issue.

Adjust the solutions below to replace br0 with your own bridge name.

Quickest fix (but turns off all Docker's iptables self-added adjustments, which you may not want):

/etc/docker/daemon.json
{
  "iptables": false
}

If there is already a network bridge configured for KVM, this may be fixable by telling docker about it. See [16] where docker configuration is modified as:

/etc/docker/daemon.json
{
  "bridge": "br0"
}

If the above does not work, or you prefer to solve the issue through iptables directly, or through a manager like UFW, add this:

iptables -I FORWARD -i br0 -o br0 -j ACCEPT

Even more detailed solutions are here.

Image pulls from Docker Hub are rate limited

Beginning on November 1st 2020, rate limiting is enabled for downloads from Docker Hub from anonymous and free accounts. See the rate limit documentation for more information.

Unauthenticated rate limits are tracked by source IP. Authenticated rate limits are tracked by account.

If you need to exceed the rate limits, you can either sign up for a paid plan or mirror the images you need to a different image registry. You can host your own registry or use a cloud hosted registry such as Amazon ECR, Google Container Registry, Azure Container Registry or Quay Container Registry.

To mirror an image, use the pull, tag and push subcommands of the Docker CLI. For example, to mirror the 1.19.3 tag of the Nginx image to a registry hosted at 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

You can then pull or run the image from the mirror:

$ docker pull cr.example.com/nginx:1.19.3
$ docker run cr.example.com/nginx:1.19.3

iptables (legacy): unknown option "--dport"

本文或本章節的事實準確性存在爭議。

原因: Nftables#Working with Docker advises to not use iptables-nft.(在 Talk:Docker 中討論)


If you see this error when running a container, install iptables-nft instead of iptables (legacy) and reboot[17].

"Your password will be stored unencrypted" when running docker login

By default Docker will try to use the pass or secretservice binaries to store your registry passwords. If they are not found, it will store them in plain text (base64-encoded) in $HOME/.docker/config.json and print the following message after successfully logging in:

$ WARNING! Your password will be stored unencrypted in /home/username/.docker/config.json.

If you are using a password manager that implements the Secret Service Freedesktop DBUS API, like KDE's kwallet or GNOME's gnome-keyring, you can install the docker-credential-secretserviceAUR package to store your passwords in them.

"Could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network"

Sometimes if you use a lot of Docker projects (ex. using docker-compose) it can happens that you run out of available IPs for Docker containers triggering the error:

Could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

As found on this Docker issue, the defaults are:

Type Default Size Default Pool
local /16 172.17.0.0/12
local* /20 192.168.0.0/16

This can be easily fixed increasing the Docker IP space by configuring default-address-pools in /etc/docker/daemon.json increasing the size value from 16 to 24 on the first IP range, keeping the second one unaltered to avoid ip collision on the local network:

/etc/docker/daemon.json
{
  ...
  "default-address-pools" : [
    {
      "base" : "172.17.0.0/12",
      "size" : 24
    },
    {
      "base" : "192.168.0.0/16",
      "size" : 24
    }
  ]
}

Restart docker.service to apply changes.

More details and technical explanations can be found on the following excellent article: The definitive guide to docker's default-address-pools option.

查閱更多