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 Compose
Docker Compose是另一種Docker引擎的CLI前端,它使用docker-compose.yml
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-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內核與文件系統上運行良好。還有一些較老的驅動程序,例如devicemapper
與aufs
,它們旨在與舊版本的Linux內核兼容,但是在Arch Linux上對比起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文檔:設置systemd的drop-in單元以配置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
以應用更改。
不安全的註冊
如果你想用自簽名的證書, 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
首先,將/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)
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
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 variableDISPLAY
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
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
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
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
有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
故障排除
使用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 restartnftables.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 (/
) 文件系統.
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"
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.