Docker 数据卷管理及优化
Docker 数据卷是一个可供容器使用的特殊目录,它绕过了容器的文件系统,直接将数据存储在宿主机上。
这样可以实现以下几个重要的目的:
-
数据持久化:即使容器被删除或重新创建,数据卷中的数据仍然存在,不会丢失。
-
数据共享:多个容器可以同时挂载同一个数据卷,实现数据的共享和交互。
-
独立于容器生命周期:数据卷的生命周期独立于容器,不受容器的启动、停止和删除的影响。
为什么要用数据卷
docker分层文件系统
-
性能差
-
生命周期与容器相同
docker数据卷
-
mount到主机中,绕开分层文件系统
-
和主机磁盘性能相同,容器删除后依然保留
-
仅限本地磁盘,不能随容器迁移
docker提供了两种卷:
-
bind mount
-
docker managed volume
bind mount 数据卷
-
是将主机上的目录或文件mount到容器里。
-
使用直观高效,易于理解。
-
使用 -v 选项指定路径,格式 <host path>:<container path>
-
-v选项指定的路径,如果不存在,挂载时会自动创建
示例:
[root@Docker-node2 volumes]# docker run -it --rm -v /hjw/data1:/data1 -v /hjw/data1:/data2:ro -v /etc/passwd:/data/passwd:ro busybox:latest
/ # touch /data1/lee1
/ # touch /data2/lee2
touch: /data2/lee2: Read-only file system
/ # tail -n 3 /etc/passwd
www-data:x:33:33:www-data:/var/www:/bin/false
operator:x:37:37:Operator:/var:/bin/false
nobody:x:65534:65534:nobody:/home:/bin/false
/ # exit
[root@Docker-node2 volumes]# ll /hjw/
总用量 0
drwxr-xr-x 2 root root 18 3月 22 10:22 data1
docker managed 数据卷
-
bind mount必须指定host文件系统路径,限制了移植性
-
docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录
-
默认创建的数据卷目录都在 /var/lib/docker/volumes 中
-
如果挂载时指向容器内已有的目录,原有数据会被复制到volume中
示例:
[root@Docker-node1 ~]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='lee' mysql:8.0
2815796d5a09c6a85a7b037e50c6e8d35e0e3a5868a7163a515aef07f1ce0e28
[root@Docker-node1 volumes]# ls
backingFsBlockDev edb6b078d5d0a5e9492f4f09a92441af88990c7cd6c46b09d6afda660289d01e metadata.db
[root@Docker-node1 volumes]# touch edb6b078d5d0a5e9492f4f09a92441af88990c7cd6c46b09d6afda660289d01e/_data/lee1
[root@Docker-node1 ~]# docker exec -it mysql sh
sh-5.1# cd /var/lib/mysql
sh-5.1# ls
'#ib_16384_0.dblwr' binlog.000001 client-cert.pem lee1 private_key.pem undo_001
'#ib_16384_1.dblwr' binlog.000002 client-key.pem mysql public_key.pem undo_002
'#innodb_redo' binlog.index ib_buffer_pool mysql.ibd server-cert.pem
'#innodb_temp' ca-key.pem ibdata1 mysql.sock server-key.pem
auto.cnf ca.pem ibtmp1 performance_schema sys
sh-5.1# exit
清理未使用的 Docker 数据卷
[root@docker ~]# docker volume prune
!NOTE
在执行
docker volume prune命令之前,请确保你确实不再需要这些数据卷中的数据,因为该操作是不可逆的,一旦删除数据将无法恢复。如果有重要的数据存储在数据卷中,建议先进行备份,或者确保数据已经被妥善保存到其他地方。
建立数据卷
[root@Docker-node1 volumes]# docker volume create hjw1
hjw1
[root@Docker-node1 volumes]# ls
backingFsBlockDev edb6b078d5d0a5e9492f4f09a92441af88990c7cd6c46b09d6afda660289d01e hjw1 metadata.db
[root@Docker-node1 volumes]# cd hjw1/
查看卷
[root@Docker-node1 hjw1]# docker volume ls
DRIVER VOLUME NAME
local edb6b078d5d0a5e9492f4f09a92441af88990c7cd6c46b09d6afda660289d01e
local hjw1
使用建立的数据卷
[root@Docker-node1 volumes]# cd hjw1/
[root@Docker-node1 hjw1]# ls
_data
[root@Docker-node1 hjw1]# touch _data/leemysql
[root@Docker-node1 ~]# docker run -d -v hjw1:/var/lib/mysql --name mysql -e MYSQL_ROOT_PASSWORD='lee' mysql:8.0
bfa5a466e960b98ec77007f678822b4c2329ad5b327e54eb4017452c55927a29
[root@Docker-node1 ~]# docker exec -it mysql sh
sh-5.1# cd /var/lib/mysql
sh-5.1# ls leemysql
leemysql
数据卷容器(Data Volume Container)
数据卷容器(Data Volume Container)是 Docker 中一种特殊的容器,主要用于方便地在多个容器之间共享数据卷。
1.建立数据卷容器
[root@Docker-node2 ~]# docker run -it --rm -v /hjw/data1:/data1 -v /hjw/data1:/data2:ro -v /etc/hosts:/etc/hosts busybox:latest
/ # ls
bin data1 data2 dev etc home lib lib64 proc root sys tmp usr var
/ # ls /etc/
group hosts mtab nsswitch.conf resolv.conf
hostname localtime network passwd shadow
/ # cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.20 Docker-node2
172.25.254.10 reg.hjw.org
/ #
2.使用数据卷容器
[root@Docker-node2 ~]# docker run -it --name busybox --volumes-from crazy_lovelace busybox:latest
/ # ls
bin data1 data2 dev etc home lib lib64 proc root sys tmp usr var
/ # cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.20 Docker-node2
172.25.254.10 reg.hjw.org
/ #
bind mount 数据卷和docker managed 数据卷的对比
相同点:
- 两者都是 host 文件系统中的某个路径
不同点
备份与迁移数据卷
备份数据卷
#建立容器并指定使用卷到要备份的容器
[root@docker ~]# docker run --volumes-from datavol \
-v `pwd`:/backup busybox \ #把当前目录挂在到容器中用于和容器交互保存要备份的容器
tar zcf /backup/data1.tar.gz /data1 #备份数据到本地
数据恢复
docker run -it --name test -v leevol1:/data1 -v `pwd`:/backup busybox /bin/sh -c "tar zxf /backup/data1.tar.gz;/bin/sh"
/ # ls
backup data1 etc lib proc sys usr
bin dev home lib64 root tmp var
/ # cd data1/ #查看数据迁移情况
/data1 # ls
index.html leefile1
完整过程
[root@docker-node1 ~]# docker run -d --name web -p 80:80 -v /data:/usr/share/nginx/html nginx:1.23
[root@docker-node1 ~]# docker exec -it webserver bash
root@23951ce13871:/# cd /usr/share/nginx/html/
root@23951ce13871:/usr/share/nginx/html# ls
index.html hjw
root@a9bc2b7e70f6:/# ls usr/share/nginx/html/
hjw1 hjw10 hjw2 hjw3 hjw4 hjw5 hjw6 hjw7 hjw8 hjw9
#数据备份
[root@Docker-node1 ~]# docker run -it --rm --volumes-from web -v $(pwd):/backup busybox:latest
/ # tar zcf /backup/html.tar.gz /usr/share/nginx/
tar: removing leading '/' from member names
/ # ls
backup bin dev etc home lib lib64 proc root sys tmp usr var
/ # ls backup/
anaconda-ks.cfg harbor-offline-installer-v2.14.0.tgz
auth html.tar.gz
busy-latest.tar mysql-8.0.tar
busyboxplus.tar.gz new
certs nginx-1.23.tar.gz
docker phpmyadmin-latest.tar.gz
/ # exit
#数据恢复
[root@docker-node1 ~]# rm -fr /data/*
[root@docker-node1 ~]# docker exec -it web bash
root@23951ce13871:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
root@23951ce13871:/# cd /usr/share/nginx/html/
root@23951ce13871:/usr/share/nginx/html# ls
root@23951ce13871:/usr/share/nginx/html#
[root@docker-node1 ~]# docker run -d --name web -p 80:80 -v /hjw:/usr/share/nginx/html -v $(pwd):/backup nginx:1.23
83a26edb472ecda951e241dc207847111cd4a2712cb349c52205c3d0e2727238
[root@Docker-node1 ~]# docker exec -it web bash
root@a9bc2b7e70f6:/# ls
backup boot docker-entrypoint.d etc lib media opt root sbin sys usr
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
root@a9bc2b7e70f6:/# tar zxf backup/html.tar.gz
root@a9bc2b7e70f6:/# ls usr/share/nginx/html/
hjw1 hjw10 hjw2 hjw3 hjw4 hjw5 hjw6 hjw7 hjw8 hjw9