docker-容器持久化
数据持久化
在做数据卷的时候有三种写入方式
1.往容器内写入数据 bind mount (物理机挂载到容器的权限有ro,rw)
2.从容器内获取数据 managed volume (容器持久化将数据存储到物理机)
3.把容器放到内存中 tmpfs (内存挂载)共享 volume container (专门为其他容器提供存储的功能卷) 也叫容器卷
volume nfs (通过nfs服务,共享容器之间的数据,并把容器的数据保存到nfs服务中)
data-packed volume container (镜像持久化,将数据存储到一个docker镜像中)
资源存储
- 容器的数据分为热数据和冷数据
- 冷数据 > 就是镜像层的数据
- 热数据 > 是容器层的数据 (热数据需要存储起来)
tmpfs内存挂载
- 通过 –tmpfs 将容器内的目录挂载到内存中
docker run -itd --name tmpfs-test --tmpfs /app busybox # 容器内的app目录就挂载到内存了,这时读写速度会非常快
bind mount (主机->容器)
- 将物理机的内容挂载到容器内
- 权限有 ro 和 rw
- 挂载的必须是目录或者文件,不可以是块设备
- 通过 –volume 或者 -v 进行挂载
[root@localhost ~]# mkdir htdocs [root@localhost ~]# echo 'lmk' > htdocs/index.html [root@localhost ~]# docker run -itd -p 80:80 --volume /root/htdocs/:/usr/local/apache2/htdocs httpd 2d57a0bd883aa4b93764305eb8a5f5ac27c844c95d2096296dd418242f2719cf # --volume /root/htdocs/:/usr/local/apache2/htdocs 这里是将 本地的 htdocs 挂载到容器的 /usr/local/apache2/htdocs内 [root@localhost ~]# curl 192.168.100.211 lmk [root@localhost ~]# echo 'kml' > htdocs/index.html [root@localhost ~]# curl 192.168.100.211 kml
- 可以看出已经将本地的目录挂载到容器内了,默认是容器和物理机都可以修改的,可以设置容器不能修改(把容器内的权限设置ro)
- 设置权限
[root@localhost ~]# docker run -itd --name httpd_1 -p 81:80 --volume /root/htdocs/:/usr/local/apache2/htdocs:ro httpd 87c465ca5613bbc3934b6330261c7ede1ef2fb598cd1325fce68254c7000652f # 在最后面添加 ro权限,现在容器就修改不了数据了 [root@localhost ~]# docker exec -it httpd_1 bash root@87c465ca5613:/usr/local/apache2# cd htdocs/ root@87c465ca5613:/usr/local/apache2/htdocs# echo 'kkk' > index.html bash: index.html: Read-only file system # Read-only 只读的
- 将文件挂载到容器内
[root@localhost ~]# docker run -it --name bbox1 --volume /root/htdocs/index.html:/data/index.html busybox / # cd /data/ /data # cat index.html kml /data # ls index.html # 将物理机的文件挂载到容器内
- 查看一下挂载的信息
[root@localhost ~]# docker inspect httpd_1 "Mounts": [ { "Type": "bind", # 挂载类型 "Source": "/root/htdocs", # 源地址目录(物理机的目录) "Destination": "/usr/local/apache2/htdocs", 被挂载目录(容器的目录) "Mode": "ro", # 权限 "RW": false, # 是否读写(如果设置了ro权限这里就是false) "Propagation": "rprivate" # 传播方向 这里是私有挂载 } ]
bind mount 长格式写法
--mount 挂载
type 挂载类型
source 源地址(物理机地址)
destination \target 挂载地址(容器地址) 在这里后面可以加权限 readonly(ro权限)
bind-propagation 传播方向
开启容器挂载目录
[root@localhost ~]# docker run -itd --name httpd_2 -p:82:80 --mount type=bind,source=/root/htdocs,target=/usr/share/nginx/html --mount type=bind,source=/root/htdocs,target=/usr/share/nginx/html2,readonly,bind-propagation=rslave nginx afd3a75b8e904fa52820d4ec8d73e940bd91a42f3223bea5b39e1725c9edd6e6 # 变量写法 # docker run -itd --name httpd --mount type=bind,source="$(pwd)"/htdocs,target=/usr/share/nginx/html --mount type=bind,source="$ (pwd)"/htdocs,target=/usr/share/nginx/html2,readonly,bind-propagation=rslave nginx # 将htdocs目录挂载到nginx的html目录 又将htdocs目录挂载到html2目录设置权限为只读,设置传播方向为rslave [root@localhost ~]# curl 192.168.100.211:82 kml
进入容器
[root@localhost ~]# docker exec -it httpd_2 bash root@4554a29ba882:/# cd /usr/share/nginx/html2/ root@4554a29ba882:/usr/share/nginx/html2# ls index.html root@4554a29ba882:/usr/share/nginx/html2# echo 'kkk' > index.html bash: index.html: Read-only file system # html2 目录不可读写
查看挂载信息
[root@localhost ~]# docker inspect httpd_2 "Mounts": [ { "Type": "bind", # 类型 "Source": "/root/htdocs", # 源目录 "Target": "/usr/share/nginx/html" # 挂载目录 }, { "Type": "bind", # 类型 "Source": "/root/htdocs", #源目录 "Target": "/usr/share/nginx/html2", #挂载目录 "ReadOnly": true, # 是否只读 "BindOptions": { "Propagation": "rslave" # 传播方向 } } ],
maneged volume (容器->主机)
- 和bind mount 最大的区别就是不需要指定源地址
容器映射出目录
[root@localhost ~]# docker run -itd --name httpd -p 80:80 --volume /usr/local/apache2/htdocs httpd 4805dd547134e0a6db1a431d11b7b3153a27feb040bfc134a56e163fd27801db [root@localhost ~]# curl 192.168.100.211 <html><body><h1>It works!</h1></body></html>
查看容器详细挂载信息
[root@localhost ~]# docker inspect httpd "Mounts": [ { "Type": "volume", # 挂载类型 "Name": "7b1a6dbcd4660cf545988020050d20f81476f1d6b883dfbabdeb7f0aaaa28524", # 卷的id "Source": "/var/lib/docker/volumes/7b1a6dbcd4660cf545988020050d20f81476f1d6b883dfbabdeb7f0aaaa28524/_data", # 映射到物理机的地址 "Destination": "/usr/local/apache2/htdocs", # 容器内的地址 "Driver": "local", # "Mode": "", "RW": true, "Propagation": "" } ]
查看映射目录
[root@localhost ~]# cd /var/lib/docker/volumes/7b1a6dbcd4660cf545988020050d20f81476f1d6b883dfbabdeb7f0aaaa28524/_data [root@localhost _data]# ls index.html [root@localhost _data]# echo 'lmk_hello' > index.html [root@localhost _data]# curl 192.168.100.211 lmk_hello
volume container 容器卷
- 通过创建一个容器来映射数据,其他容器只需要挂载这个容器映射的数据
- 通过 –volumes-from 来挂载容器卷
创建容器卷
# 查看容器卷
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
# 创建容器卷
[root@localhost ~]# docker create --name vc_data --volume /root/htdocs/:/usr/local/apache2/htdocs --volume /usr/local/apache2/logs busybox
84bd5d19bfad5dc447012ab4d4aa58523f0529bd32bb3745540eaf3c4b84a348
# 将本地的 htdocs目录挂载到容器内,又将容器内的logs目录映射出本机
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 954a38573384dfd5741744419d539f0079d5d4a5d1e64431518ba383ccc3b761
查看容器卷信息
[root@localhost ~]# docker inspect vc_data
"Mounts": [
{
"Type": "volume", # 类型
"Name": "954a38573384dfd5741744419d539f0079d5d4a5d1e64431518ba383ccc3b761", # 卷id
"Source": "/var/lib/docker/volumes/954a38573384dfd5741744419d539f0079d5d4a5d1e64431518ba383ccc3b761/_data", #映射出的目录
"Destination": "/usr/local/apache2/logs", # 将容器内的logs目录映射出,到本地的目录
"Driver": "local",
"Mode": "",
"RW": true, #读写
"Propagation": ""
},
{
"Type": "bind", # 类型
"Source": "/root/htdocs", # 本地目录
"Destination": "/usr/local/apache2/htdocs", #容器目录
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
创建容器挂载容器卷
[root@localhost ~]# docker run -itd --name httpd_1 -p 80:80 --volumes-from vc_data httpd
aa99f7a4b8e4367e69a333b67dc39e738ccfc47f655dbf39b7d832c8f12efb64
[root@localhost ~]# docker run -itd --name httpd_2 -p 81:80 --volumes-from vc_data httpd
52f01ce67bbfb4cf5f254132de25b36b6dfcf2f393e0b30bd07d4ce69698c7dc
[root@localhost ~]# curl 192.168.100.211
kml
[root@localhost ~]# curl 192.168.100.211:81
kml
# 查看映射出的数据
[root@localhost ~]# cd /var/lib/docker/volumes/954a38573384dfd5741744419d539f0079d5d4a5d1e64431518ba383ccc3b761/_data
[root@localhost _data]# ls
httpd.pid
data-packed volume container 镜像持久化
- 将数据存储到镜像中
- 可以做数据镜像迁移(如果数据较大就不推荐这样做)
编写Dockerfile
[root@localhost ~]# vim Dockerfile FROM centos ADD htdocs /usr/local/apache2/htdocs VOLUME /usr/local/apache2/htdocs
制作镜像
[root@localhost ~]# docker build -t data . Sending build context to Docker daemon 7.097MB Step 1/3 : FROM centos ---> 7e6257c9f8d8 Step 2/3 : ADD htdocs /usr/local/apache2/htdocs ---> 13e0d3329dc6 Step 3/3 : VOLUME /usr/local/apache2/htdocs ---> Running in f31b0a8a8842 Removing intermediate container f31b0a8a8842 ---> 31daf73594a4 Successfully built 31daf73594a4 Successfully tagged data:latest
将镜像创建成一个容器
[root@localhost ~]# docker create --name data data 6f8bfef0a3d3026bfccfc8f959bdeaaa589d7e71491f6b7ca59ebb522f935b1a
使用容器卷
[root@localhost ~]# docker run -d -p 8080:80 --volumes-from data httpd 1a4f18b2204850689553edf3a932d154e120be32649162b716645dc8a31f5b85 [root@localhost ~]# curl 192.168.100.211:8080 kkk
关于selinux标签在volume的使用
- 不能使用 –mount设置selinux标签,设置selinux标签后ro权限会被忽略
- z(小写) 表示挂载内容在多个容器之间共享
- Z(大写) 表示挂载内容是私有和非共享的
小写z
[root@localhost ~]# docker run --name web3 -d -p 80 --volume /root/htdocs:/usr/local/apache2/htdocs:z httpd cfeb66d718a3c57fd7b12c218b260654d5ce33508360ddfa6fda6dd846549b03 [root@localhost ~]# docker inspect web3 "Mounts": [ { "Type": "bind", "Source": "/root/htdocs", "Destination": "/usr/local/apache2/htdocs", "Mode": "z", "RW": true, "Propagation": "rprivate" } ] # 表示这个/root/htdocs 可以在多个容器内共享
大写z
[root@localhost ~]# docker run --name web4 -d -p 80 --volume /root/htdocs:/usr/local/apache2/htdocs:Z httpd f07661653f09aea204beb8cd673aaa92480690dba59f84b807b98d2b387468f1 [root@localhost ~]# docker inspect web4 "Mounts": [ { "Type": "bind", "Source": "/root/htdocs", "Destination": "/usr/local/apache2/htdocs", "Mode": "Z", "RW": true, "Propagation": "rprivate" } ] # 表示/root/htdocs 挂载到这个容器的数据时不可以在其他容器内共享的
- 这个一般不用
–mount 和 –volumes的区别
- –mount可以有 rw 和ro权限
- –volumes 只有一个rw权限
docker volume备份
创建一些目录
[root@localhost ~]# mkdir /values
[root@localhost ~]# mkdir /values/test1
[root@localhost ~]# mkdir /values/test2
创建容器卷将杠杆创建的目录挂载进去
# 将本地的values目录挂载到容器内的data目录下
[root@localhost ~]# docker create --name back --volume /values/:/data busybox
af2efdde81198c8e807a5156e82006a025db4065f57787d9eb551d17dec12097
创建容器挂载容器卷
# 创建容器挂载容器卷
# 并将本地目录的bakcup挂载到容器内的backup中 在容器中运行一个命令 打包 data目录下的数据放到 backup中
[root@localhost ~]# docker run --rm --volumes-from back --volume /root/backup/:/backup busybox tar zcvf /backup/backup.t
ar /data
tar: removing leading '/' from member names
data/
data/test1/
data/test2/
# 本地查看压缩包
[root@localhost ~]# cd backup/
[root@localhost backup]# ls
backup.tar
# 备份完毕
volume nfs 容器间目录共享
- 需要一台nfs服务器 和一台docker
192.168.100.211 nfs 192.168.100.212 docker
安装nfs
[root@localhost ~]# mkdir -p /data/nfs
[root@localhost ~]# yum -y install nfs-utils rpcbind
[root@localhost ~]# vim /etc/exports
/data/nfs *(rw,no_root_squash,sync)
[root@localhost ~]# exportfs -r
[root@localhost ~]# systemctl restart nfs-server
[root@localhost ~]# showmount -e 192.168.100.211
Export list for 192.168.100.211:
/data/nfs *
docker 创建nfs容器卷
[root@localhost ~]# docker volume create --driver local --opt type=nfs --opt o=addr=192.168.100.211,rw --opt device=:/data/nfs volume-nfs
volume-nfs
docker 将 nfs容器卷挂载到容器中
[root@localhost ~]# docker run -itd --name bbox1 --volume volume-nfs:/nfs busybox
2213cfd8aa7983cb2b05e6a5805112e31e22842dc6eeb964d96903123abf8111
修改nfs目录查看容器内是否有文件
# docker查看容器数据
[root@localhost ~]# docker exec -it bbox1 sh
/ # cd /nfs/
/nfs # ls
/nfs #
# nfs目录创建文件
[root@localhost ~]# cd /data/nfs/
[root@localhost nfs]# echo 'lmk_hello' > file
# 容器查看
/nfs # ls
file
/nfs # cat file
lmk_hello
# 所有数据在nfs服务器内,容器关闭也不会消失
本博客所有文章是以学习为目的,如果有不对的地方可以一起交流沟通共同学习 邮箱:1248287831@qq.com!