Docker-解決空間不足的問題以及修改預設配置
問題
dpkg: error processing archive /var/cache/apt/archives/libc6-dev-i386_2.23-0ubuntu10_amd64.deb (--unpack): cannot copy extracted data for './usr/lib32/libresolv.a' to '/usr/lib32/libresolv.a.dpkg-new': failed to write (No space left on device)
Google了一圈之後,大多人的解決方案是刪除所有不用的VOLUME、容器以及映象等等。本質上只是騰出位置而已。但是如果業務需要所有的這些東西必不可刪除的的話。這個問題還是無解。
定位問題
- 檢視磁碟資訊
pi@raspberrypi:~$ df -lh FilesystemSizeUsed Avail Use% Mounted on udev32G032G0% /dev tmpfs6.3G599M5.8G10% /run /dev/mapper/vg00-root19G1.7G17G10% / tmpfs32G032G0% /dev/shm tmpfs5.0M05.0M0% /run/lock tmpfs32G032G0% /sys/fs/cgroup /dev/sda1180M54M113M33% /boot /dev/mapper/vg00-tmp945M56M825M7% /tmp /dev/mapper/vg00-var3.7G3.1G462M88% /var /dev/mapper/vg00-data1.6T631G882G42% /data tmpfs6.3G06.3G0% /run/user/25439
我是在/data分割槽上面掛載的VOLUME。一開始以為是硬碟儲存不夠導致的問題,後來發現不是這個問題(很明顯我的空間剩餘非常大)。
再想,其實這個是映象內部在下載依賴的時候導致的空間不足,並沒有對VOLUME進行任何IO操作。也就是說應當是docker本身的映象/容器掛載點出現了問題。
- 檢視 docker資訊
pi@raspberrypi:~$ docker info Containers: 2 Running: 0 Paused: 0 Stopped: 2 Images: 3 Server Version: 18.09.1 Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: 9754871865f7fe2f4e74d43e2fc7ccd237edcbce runc version: 96ec2177ae841256168fcf76954f7177af9446eb init version: fec3683 Security Options: apparmor seccomp Profile: default Kernel Version: 4.4.0-87-generic Operating System: Ubuntu 16.04.5 LTS OSType: linux Architecture: x86_64 CPUs: 24 Total Memory: 62.89GiB Name: raspberrypi ID: 2MO2:4Z6P:X2RQ:RPW7:PGWL:AJXZ:NX7M:66FR:GSUH:5PBC:2QFK:WH4O Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false Product License: Community Engine WARNING: No swap limit support
注意上面的一句Docker Root Dir: /var/lib/docker
, 這應該是跟Docker儲存映象等有關。於是做了幾個小實驗:刪除和建立容器/映象並觀察/var
分割槽。發現此分割槽同步改變體積,於是我的思路就是修改Docker Root Dir
。後來問詢得知可以通過修改DOCKER_OPTS
(新增-g /xxx)可以修改掛載點。
修改 /etc/default/docker
pi@raspberrypi:~$ dosu ls -l /etc/default/docker -rw-r--r-- 1 root root 685 Jan 18 10:49 /etc/default/docker pi@raspberrypi:~$ dosu cat /etc/default/docker # Docker Upstart and SysVinit configuration file # # THIS FILE DOES NOT APPLY TO SYSTEMD # #Please see the documentation for "systemd drop-ins": #https://docs.docker.com/engine/admin/systemd/ # # Customize location of Docker binary (especially for development testing). #DOCKERD="/usr/local/bin/dockerd" # Use DOCKER_OPTS to modify the daemon startup options. #DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4" # 新增路徑 DOCKER_OPTS="-g /data/docker/" # If you need Docker to use an HTTP proxy, it can also be specified here. #export http_proxy="http://127.0.0.1:3128/" # This is also a handy place to tweak where Docker's temporary files go. #export DOCKER_TMPDIR="/mnt/bigdrive/docker-tmp" pi@raspberrypi:~$
重啟
sudo service docker restart
操作。不管用。
後於https://github.com/moby/moby/issues/9889#issuecomment-109778351 發現這種修改是有限制的。
Correct, the /etc/default/docker file is only used on systems using “upstart” and “SysVInit”, not on systems using systemd. This is also mentioned at the top of the file; https://github.com/docker/docker/blob/44fe8cbbd174b5d85d4a063ed270f6b9d2279b70/contrib/init/sysvinit-debian/docker.default#L1
修改 /lib/systemd/system/docker.service
pi@raspberrypi:~/docker-config$ dosu cat /lib/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com BindsTo=containerd.service After=network-online.target firewalld.service Wants=network-online.target Requires=docker.socket [Service] Type=notify # the default is not to use systemd for cgroups because the delegate issues still # exists and systemd currently does not support the cgroup feature set required # for containers run by docker ExecStart=/usr/bin/dockerd -g /data/docker/ -H fd:// ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always # Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229. # Both the old, and new location are accepted by systemd 229 and up, so using the old location # to make them work for either version of systemd. StartLimitBurst=3 # Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230. # Both the old, and new name are accepted by systemd 230 and up, so using the old name to make # this option work for either version of systemd. StartLimitInterval=60s # Having non-zero Limit*s causes performance problems due to accounting overhead # in the kernel. We recommend using cgroups to do container-local accounting. LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity # Comment TasksMax if your systemd version does not supports it. # Only systemd 226 and above support this option. TasksMax=infinity # set delegate yes so that systemd does not reset the cgroups of docker containers Delegate=yes # kill only the docker process, not all processes in the cgroup KillMode=process [Install] WantedBy=multi-user.target
直接在ExecStart的啟動命令中新增-g /xxx
修改Docker Root Dir
。
# ExecStart=/usr/bin/dockerd -H fd:// ExecStart=/usr/bin/dockerd -g /data/docker/ -H fd://
重啟。
pi@raspberrypi:~/docker-config$ dosu service docker restart Warning: docker.service changed on disk. Run 'systemctl daemon-reload' to reload units. pi@raspberrypi:~/docker-config$ dosu systemctl daemon-reload pi@raspberrypi:~$ docker images; docker ps -a REPOSITORYTAGIMAGE IDCREATEDSIZE CONTAINER IDIMAGECOMMANDCREATEDSTATUS
什麼東西沒有了。 繼續檢視:
pi@raspberrypi:~$ docker info | grep -i root Docker Root Dir: /data/docker pi@raspberrypi:~$
所以操作生效了。
注意:記得將原路徑的檔案(使用root)拷貝到新的目錄。這樣docker才能找到原先的映象和容器以及相關快取(Layer)等。
其實也可以在/etc/docker/daemon.json
中修改做修改。
本文連結