1. Giới thiệu
Device mapper là một khung làm việc dựa trên nhân hạt nhân Linux hỗ trợ nhiều kỹ thuật quản lý volume nâng cao. Trong Docker, driver lưu trữ devicemapper tận dụng các tính năng cấu hình mỏ và chụp ảnh của khung này để quản lý hình ảnh và container.
Driver devicemapper sử dụng thiết bị khối chuyên dụng cho Docker và hoạt động ở cấp độ khối thay vì cấp tệp tin. Các thiết bị này mở rộng thông qua việc thêm bộ nhớ vật lý vào máy chủ Docker. So với việc sử dụng hệ thống tập tin ở cấp I/O, chúng có hiệu suất tốt hơn.
2. Môi trường Cấu hình
Phiên bản hệ điều hành: CentOS 7.1
Phiên bản nhân: được nâng cấp từ 3.10.0-229 lên 4.20
Phiên bản Docker: docker-ce 18.09.2
Vấn đề: Khi cài đặt mặc định, hệ thống CentOS 7.1 sử dụng hệ thống tập tin xfs cho phân vùng gốc và không hỗ trợ d_type. Trong Docker, cả overlay và overlay2 đều sử dụng hệ thống tập tin overlayfs làm nền tảng. Overlayfs yêu cầu tính năng d_type. Do đó, nếu muốn sử dụng overlay2 với hệ thống tập tin xfs, cần kích hoạt d_type.
[root@k8s001 ~]# xfs_info /
meta-data=/dev/mapper/centos-root isize=256 agcount=4, agsize=3276800 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0 spinodes=0
data = bsize=4096 blocks=13107200, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal bsize=4096 blocks=6400, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
Từ đầu ra trên thấy rằng ftype=0, tức là hệ thống tập tin xfs không hỗ trợ d_type (nếu ftype=1 thì hỗ trợ).
d_type là thuật ngữ trong nhân Linux chỉ "kiểu mục nhập thư mục". Mục nhập thư mục là cấu trúc dữ liệu chứa thông tin thư mục trên hệ thống tập tin. d_type là trường trong cấu trúc này dùng để xác định loại tệp tin: tệp tin, ống dẫn, thư mục hay socket...
Tính năng d_type đã được hỗ trợ từ kernel Linux 2.6 nhưng không phải tất cả các hệ thống tập tin đều thực hiện nó. Người dùng cần bật chức năng này bằng cách sử dụng tham số tùy chỉnh.
Giải pháp: Vì hệ thống đã cài đặt và không hỗ trợ d_type, cần hoặc cài đặt lại CentOS 7.5 trở lên để hỗ trợ d_type hoặc chọn driver lưu trữ devicemapper.
3. Devicemapper
Khi chọn devicemapper, có thể cấu hình:
- Chế độ loop-lvm
- Chế độ direct-lvm
3.1 Chế độ loop-lvm
Mặc định trên CentOS 7, Docker sử dụng chế độ loop-lvm. Phần backend là các tệp sparse tự động tạo:
[root@k8s001 ~]# ls -lsh /var/lib/docker/devicemapper/devicemapper/
total 3.5G
3.5G -rw------- 1 root root 100G Nov 13 11:00 data
4.6M -rw------- 1 root root 2.0G Nov 13 11:00 metadata
Trong đó data (lưu trữ dữ liệu) và metadata (lưu trữ siêu dữ liệu). Theo đầu ra, kích thước mặc định là 100G và 2G, đều là tệp sparse, chỉ chiếm dung lượng khi sử dụng.
Quá trình khởi tạo Docker sẽ tạo hai tệp sparse data và metadata, gắn vào các thiết bị vòng /dev/loop0 và /dev/loop1, sau đó tạo thin pool mặc định, mỗi container tối đa 10G.
[root@k8s001 ~]# docker info
Client:
Debug Mode: false
Server:
Containers: 16
Running: 6
Paused: 0
Stopped: 10
Images: 22
Server Version: 18.09.2
Storage Driver: devicemapper
Pool Name: docker-253:0-67339311-pool
Pool Blocksize: 65.54kB
Base Device Size: 10.74GB
Backing Filesystem: xfs
Udev Sync Supported: true
Data file: /dev/loop0
Metadata file: /dev/loop1
Data loop file: /var/lib/docker/devicemapper/devicemapper/data
Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
Data Space Used: 3.777GB
Data Space Total: 107.4GB
Data Space Available: 42.06GB
Metadata Space Used: 21.28MB
Metadata Space Total: 2.147GB
Metadata Space Available: 2.126GB
Thin Pool Minimum Free Space: 10.74GB
Deferred Removal Enabled: true
Deferred Deletion Enabled: true
Deferred Deleted Device Count: 0
Library Version: 1.02.149-RHEL7 (2018-07-20)
Xem thiết bị khối của hệ thống:
[root@k8s001 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop1 7:1 0 2G 0 loop
└─docker-253:0-67339311-pool 253:3 0 100G 0 dm
├─docker-253:0-67339311-03563554f7c7b1ca35c0023fbe6c4f67c62dcf6b5a45ef9a39dc693baff1b24e 253:8 0 10G 0 dm /var/lib/docker/devicemapper/mnt/03563554f7c7b1ca35c002
├─docker-253:0-67339311-c3321ce74e90d9df08793b808c79e1c637cfbfd7e70a74f55933b3f41a56e49a 253:6 0 10G 0 dm /var/lib/docker/devicemapper/mnt/c3321ce74e90d9df08793b
├─docker-253:0-67339311-216e260231a30f484a10a28288509819cf0c7492b27c3bf03394b1932cb637b3 253:4 0 10G 0 dm /var/lib/docker/devicemapper/mnt/216e260231a30f484a10a2
├─docker-253:0-67339311-379abc2c8d2e1f163592595b102fafef869e48c440f7da7b6591d55742640531 253:9 0 10G 0 dm /var/lib/docker/devicemapper/mnt/379abc2c8d2e1f16359259
├─docker-253:0-67339311-24229ad0cba2615ed61273d19673659483018bf7c674c0002f04c7492bf5b720 253:7 0 10G 0 dm /var/lib/docker/devicemapper/mnt/24229ad0cba2615ed61273
└─docker-253:0-67339311-fa5c09702c932d386cc618d54a90c261b4aac5d3e593dac7d60545957cee85e2 253:5 0 10G 0 dm /var/lib/docker/devicemapper/mnt/fa5c09702c932d386cc618
sr0 11:0 1 1024M 0 rom
loop0 7:0 0 100G 0 loop
└─docker-253:0-67339311-pool 253:3 0 100G 0 dm
├─docker-253:0-67339311-03563554f7c7b1ca35c0023fbe6c4f67c62dcf6b5a45ef9a39dc693baff1b24e 253:8 0 10G 0 dm /var/lib/docker/devicemapper/mnt/03563554f7c7b1ca35c002
├─docker-253:0-67339311-c3321ce74e90d9df08793b808c79e1c637cfbfd7e70a74f55933b3f41a56e49a 253:6 0 10G 0 dm /var/lib/docker/devicemapper/mnt/c3321ce74e90d9df08793b
├─docker-253:0-67339311-216e260231a30f484a10a28288509819cf0c7492b27c3bf03394b1932cb637b3 253:4 0 10G 0 dm /var/lib/docker/devicemapper/mnt/216e260231a30f484a10a2
├─docker-253:0-67339311-379abc2c8d2e1f163592595b102fafef869e48c440f7da7b6591d55742640531 253:9 0 10G 0 dm /var/lib/docker/devicemapper/mnt/379abc2c8d2e1f16359259
├─docker-253:0-67339311-24229ad0cba2615ed61273d19673659483018bf7c674c0002f04c7492bf5b720 253:7 0 10G 0 dm /var/lib/docker/devicemapper/mnt/24229ad0cba2615ed61273
└─docker-253:0-67339311-fa5c09702c932d386cc618d54a90c261b4aac5d3e593dac7d60545957cee85e2 253:5 0 10G 0 dm /var/lib/docker/devicemapper/mnt/fa5c09702c932d386cc618
sda 8:0 0 300G 0 disk
├─sda2 8:2 0 299.5G 0 part
│ ├─centos-swap 253:1 0 7.9G 0 lvm
│ ├─centos-home 253:2 0 241.6G 0 lvm /home
│ └─centos-root 253:0 0 50G 0 lvm /
└─sda1 8:1 0 500M 0 part /boot
Do chế độ loop-lvm kém về hiệu năng và độ ổn định, chỉ nên dùng trong môi trường thử nghiệm, không khuyến nghị sử dụng trong sản xuất.
3.2 Chế độ direct-lvm
Trong môi trường sản xuất, máy chủ sử dụng driver lưu trữ devicemapper phải sử dụng chế độ direct-lvm, nơi tạo pool mỏ bằng thiết bị khối. Chế độ này sử dụng tài nguyên hệ thống hiệu quả hơn so với loop-lvm và có thể mở rộng thiết bị khối theo nhu cầu.
3.2.1 Cấu hình chế độ direct-lvm
Cần thêm một ổ đĩa mới, ví dụ 500G.
- Dừng dịch vụ Docker
[root@k8s001 ~]# systemctl stop docker
- Tạo volume vật lý từ toàn bộ ổ đĩa
[root@k8s001 ~]# pvcreate /dev/sdb
- Tạo nhóm volume dockervg
[root@k8s001 ~]# vgcreate dockervg /dev/sdb
- Tạo logical volume thinpool
[root@k8s001 ~]# lvcreate --wipesignatures y -n thinpool -l 70%VG dockervg
[root@k8s001 ~]# lvcreate --wipesignatures y -n thinpoolmeta -l 5%VG dockervg
[root@k8s001 ~]# lvscan
ACTIVE '/dev/dockervg/thinpool' [<300.00 GiB] inherit
ACTIVE '/dev/centos/swap' [<7.88 GiB] inherit
ACTIVE '/dev/centos/home' [241.57 GiB] inherit
ACTIVE '/dev/centos/root' [50.00 GiB] inherit
- Chuyển đổi thành thinpool
[root@k8s001 ~]# lvconvert -y --zero n -c 512K --thinpool dockervg/thinpool --poolmetadata dockervg/thinpoolmeta
- Kiểm tra trạng thái thinpool
[root@k8s001 ~]# lvs -o lv_name,data_percent,metadata_percent,lv_size,lv_metadata_size,data_lv,metadata_lv
LV Data% Meta% LSize MSize Data Meta
home 241.57g
root 50.00g
swap <7.88g
thinpool 1.63 0.29 <300.00g <6.00g [thinpool_tdata] [thinpool_tmeta]
Ghi chú: LSize là dung lượng dữ liệu, MSize là dung lượng siêu dữ liệu, Data là logical volume tương ứng cho dữ liệu, Meta là logical volume cho siêu dữ liệu.
Mở rộng thinpool (tùy theo nhu cầu):
Ổ sdb chưa sử dụng hết dung lượng, khi không đủ không gian cho Metadata hoặc Data, có thể mở rộng:
# Mở rộng Metadata
[root@k8s001 ~]# lvresize -L +1G /dev/mapper/dockervg-thinpool_tmeta
# Mở rộng Data
[root@k8s001 ~]# lvresize -L +5G /dev/mapper/dockervg-thinpool
- Sao lưu và di chuyển thư mục Docker cũ
[root@k8s001 ~]# mkdir /var/lib/docker_bak
[root@k8s001 ~]# mv /var/lib/docker/* /var/lib/docker_bak
- Chỉnh sửa tham số khởi động Docker
[root@k8s001 ~]# cat /etc/docker/daemon.json
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.thinpooldev=/dev/mapper/dockervg-thinpool",
"dm.use_deferred_removal=true",
"dm.use_deferred_deletion=true"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "1m",
"max-file": "10"
}
}
- Khởi động lại dịch vụ Docker
[root@k8s001 ~]# systemctl daemon-reload
[root@k8s001 ~]# systemctl start docker
- Xác nhận
[root@k8s001 ~]# docker info
Client:
Debug Mode: false
Server:
Containers: 33
Running: 32
Paused: 0
Stopped: 1
Images: 22
Server Version: 18.09.2
Storage Driver: devicemapper
Pool Name: dockervg-thinpool
Pool Blocksize: 524.3kB
Base Device Size: 10.74GB
Backing Filesystem: xfs
Udev Sync Supported: true
Data Space Used: 5.244GB
Data Space Total: 322.1GB
Data Space Available: 316.9GB
Metadata Space Used: 18.67MB
Metadata Space Total: 6.438GB
Metadata Space Available: 6.42GB
Thin Pool Minimum Free Space: 32.21GB
Deferred Removal Enabled: true
Deferred Deletion Enabled: true
Deferred Deleted Device Count: 0
Library Version: 1.02.149-RHEL7 (2018-07-20)