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.