Khi chạy docker trong thời gian dài các bạn sẽ gặp phải tình huống đầy ổ đĩa, nguyên nhân sẽ có nhiều: log của app, kích thước ổ nhỏ quá, ... Hôm nay mình xin chia sẻ quá trình debug khi hết ổ đĩa và sau đó là cách dọn dẹp Docker định kì.
Mình có tự mua một con server ở nhà cấu hình: dual xeon, ram 128GB, disk 2TB, (mình mua cấu hình này ~13tr) để chạy máy ảo, nghịch ngợm các thứ. Các máy ảo cấu hình cũng ổn phèn cũng 4cpu, 8GB RAM, 128GB disk. Cứ nghĩ chả phải monitor, đặt cảnh báo alert thì một ngày, bạn mình dùng chung với mình bảo backend chết, lúc này các bạn sẽ thấy một vài dấu hiệu như: chỉ get được dữ liệu chứ không ghi thêm dữ liệu được, ...
Sau đó mình ssh ngay vào con vm để kiểm tra, dấu hiệu đầu tiên các bạn có thể thấy ngay là khi ấn TAB
để gợi ý lệnh sẽ có lỗi như sau:
vagrant@tuana9a-dev ~ $ cd /etc/ng [TAB]
bash: No space left on device
(trên là ví dụ minh họa, mình không nhớ chính xác message)
Khi biết là hết disk ngay lập tức mình chạy lệnh df
để kiểm tra disk còn trống bao nhiêu.
vagrant@tuana9a-dev ~ $ df -h Filesystem Size Used Avail Use% Mounted on
udev 3.9G 0 3.9G 0% /dev
tmpfs 798M 9.3M 789M 2% /run
/dev/sda3 124G 84G 34G 72% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda1 462M 222M 212M 52% /boot
tmpfs 798M 0 798M 0% /run/user/1000
vagrant@tuana9a-dev ~ $
Ở trên hình thì /dev/sda3
chưa đầy mà trong quá khứ thì nó đã bị đầy một lần rùi 95%, khi đầy thì cột Used
sẽ cao và Avail
sẽ thấp.
Lúc này các bạn đừng hoảng, ngày xưa mình cũng thắc mắc là OS khi hoạt động sẽ cần không gian bộ nhớ để cho các file tạm, các chương trình khi thực thi khả năng cao sẽ tương tác với các file tạm này để có thể hoạt động bình thường, đặc biệt với Linux thì mọi thứ đều là file, giờ hết disk rồi thì OS chết hả, không fix được nữa hả?
Vẫn fix được, mình có tìm từ khóa Reserved Disk Space On Linux
thì tìm được cái này https://unix.stackexchange.com/questions/7950/reserved-space-for-root-on-a-filesystem-why, đại loại linux sẽ "chừa" khoảng 5%
con số chính xác có thể khác nhau tùy theo format disk, tùy theo loại filesystem hoặc tùy theo OS nên là vẫn thở được các bạn nhé.
Tiếp tục kiểm tra kích thước của từng thư mục từ thư mục root
vagrant@tuana9a-dev ~ $ sudo du -h --max-depth 1 / 45G /var
1.2G /lib
2.4G /opt
16K /lost+found
9.3M /run
0 /sys
1.3M /tmp
4.0K /srv
0 /dev
4.0K /mnt
8.0K /snap
4.0K /lib64
20K /exports
13G /usr
6.7M /etc
27G /home
8.0K /media
15M /sbin
222M /boot
4.0K /yourpath
16M /bin
268K /root
du: cannot access '/proc/10305/task/10305/fd/3': No such file or directory
du: cannot access '/proc/10305/task/10305/fdinfo/3': No such file or directory
du: cannot access '/proc/10305/fd/4': No such file or directory
du: cannot access '/proc/10305/fdinfo/4': No such file or directory
0 /proc
86G /
vagrant@tuana9a-dev ~ $
Thấy thư mục /var
lớn nhất, check tiếp bên trong thư mục đó.
vagrant@tuana9a-dev ~ $ sudo du -h --max-depth 1 /var
40G /var/lib
4.0K /var/opt
3.6M /var/crash
28K /var/tmp
4.0K /var/snap
12K /var/www
842M /var/cache
4.0K /var/local
36K /var/spool
2.7M /var/backups
3.4G /var/log
4.0K /var/mail
45G /var
Tiếp tục với thư mục /var/lib
thì tôi tìm ra thư mục /var/lib/docker
nặng nhất, cụ thể lúc đấy khoảng 80GB.
vagrant@tuana9a-dev ~ $ sudo du -h --max-depth 1 /var/lib/docker
4.0K /var/lib/docker/runtimes
40G /var/lib/docker/overlay2
148K /var/lib/docker/volumes
4.9M /var/lib/docker/containers
4.0K /var/lib/docker/tmp
4.0K /var/lib/docker/swarm
152K /var/lib/docker/network
56M /var/lib/docker/image
39M /var/lib/docker/buildkit
16K /var/lib/docker/plugins
40G /var/lib/docker
Nhìn vào cấu trúc thư mục này tôi cũng đoán được docker hoạt động như nào:
volumes
để chứa các thông tin liên quan tới volumes: metadata, có thể chứa cả dữ liệu luôn, chính xác thì các bạn tự kiểm tra nhé.containers
chứa các thông tin liên quan tới container: metadata, có cả log, ...network
chứa thông tin liên quan tới network: metadata, cấu hình network, ...- ...
Thằng overlay2
là gì mà sao ăn lắm disk thế nhỉ? Các bạn tự google để xem chi tiết nhé - spoiler: data structure này rất hay nhé.
Ok vậy đã tìm được nguyên nhân là do docker, bước tiếp theo là xem cái gì dọn dẹp đươc thì dọn dẹp. Các thứ mình nghĩ có thể dọn dẹp được bao gồm:
- Log của các container
- Các volume không còn được sử dụng
- Các container đã stopped
- Các image mà không được sử dụng
- Build cache
Tìm được các thứ cần dọn dẹp rồi thì bắt đầu dọn.
clear container log
Dọn dẹp log của container, đơn giản là làm nó trống trơn.
for f in /var/lib/docker/containers/*/*-json.log
do cat /dev/null > $f
done
Tích hợp nó vào crontab.
# daily
sudo -s
cat <<EOF > /etc/cron.daily/clear-container-logs
#!/bin/sh
for f in /var/lib/docker/containers/*/*-json.log
do cat /dev/null > \$f
done
EOF
chmod +x /etc/cron.daily/clear-container-logs
# weekly
sudo -s
cat <<EOF > /etc/cron.weekly/clear-container-logs
#!/bin/sh
for f in /var/lib/docker/containers/*/*-json.log
do cat /dev/null > \$f
done
EOF
chmod +x /etc/cron.weekly/clear-container-logs
clear volume
Dọn volume mà không được sử dụng nữa.
docker volume prune -a
clear image
Dọn các docker image mà không được sử dụng nữa.
docker image prune -a
clear container
Dọn các container không còn chạy nữa.
docker container prune
clear build cache
Các bạn để ý khi build lại container thì lần sau thường nhanh hơn lần trước, nhanh như vậy chắc chẳn là do cache ròi.
docker builder prune
docker system prune
Phiên bản sau này của docker có lệnh docker system prune
sẽ tự động làm kha khá các việc dọn dẹp cho chúng ta.
root@tuana9a-dev:/var/lib/docker# docker system prune
WARNING! This will remove: - all stopped containers - all networks not used by at least one container - all dangling images - all dangling build cache Are you sure you want to continue? [y/N] y
Deleted Networks:
docker-registry_default
Deleted build cache objects:
98jlfzkgw1hjfdk22sd5460x5
3o8xbgqhl6e49n3illj8fenid
o692cdjs4pm8ni4l4rg8v4hpw
pobyjug26w7kddhf68st2sj5t
p3imtyiehrh0pqfptsyfyftaj
...
Total reclaimed space: 25.17GB
root@tuana9a-dev:/var/lib/docker#
next step
Đây là ý nghĩa của việc đẻ ra "monitor", sau vụ này mình đã triển khai combo monitor: prometheus + node_exporter + grafana + alertmanager. Set ở mức 80% disk là cảnh báo, triển khai hệ thống monitor nằm ngoài bài viết này, các bạn cần thì mình sẽ gửi link.
Hết.