docker容器的存储资源(volume)
目录
docker容器的存储资源(volume)
/var/lib/docker/image # 存储镜像层的资源
/var/lib/docker/overlay2 # 存储容器层的资源
容器资源挂载方式又两种思考方向:
1. bind mount:将宿主机中目录挂载到容器中
1) docker run -d -p 80:80 --name web -v ~/htdocs:/usr/local/apache/htdocs httpd # 宿主机htdocs目录挂载到容器内,默认默认为rw权限,而且是双向读写(宿主机和容器内都可以对其目录读写)
2) docker run -d -p 80:80 --name web -v ~/htdocs:/usr/local/apache/htdocs:ro httpd # 挂载宿主机目录htdocs到容器内为ro的权限,在登录到容器内,usr/local/apache/htdocs目录的权限为只读;
docker inspect web # 如图1
docker exec -it web bash
cd /usr/local/apache/htdocs
echo "123" > index.html # 提示此目录是只读的文件系统 如下图2
3) 权限的另外一种修正方法:selinux标签
如果使用--mount选项挂载了-Z或z,会忽略rw的权限
selinux:-Z,表示挂载内容是私有的,不能在其它容器之间共享
selinux:-z,挂载目录内的多个容器之间可以共享这个数据内容
docker run -itd --name devtest -v "$(pwd)"/htdoc:/usr/share/nginx/html:z nginx:latest
ls -Zd htdoc # 如下图3
docker exec -it devtest bash
cd /usr/share/nginx/
ls -Zd html/ # 如下图3
docker inspect devtest # 如下图4
2. tmpfs mounts: 将容器中的目录存放到宿主机内存中
docker run -itd --name tmpfs --tmpfs /app busybox
docker exec -it tmpfs sh
3. managed volume: 将容器内的某个目录持久化到宿主机指定目录
docker run -d --name web -p 80:80 --volume /usr/local/apache2/htdocs httpd # 挂载的时候不指定挂载的源地址(宿主机地址),默认挂载在/var/lib/docker/volumes/...随机字符串.../_data,随机字符串是容器挂载到宿主机的卷名(VOLUME NAME) 如下图5
curl 192.168.31.168:80
'''
<html><body><h1>It works!</h1></body></html>
'''
docker inspect web # 如下图5
cd /var/lib/docker/volumes/...随机字符串.../_data
ls
'''
index.html
'''
echo "Hello,Sir." > index.html
curl 192.168.31.168:80
'''
Hello,Sir.
'''
docker volume ls
'''
...VOLUME NAME...
'''
docker volume inspect VOLUME-NAME # 下图6
docker rm -f web # 删除容器web,这时只要/var/lib/docker/volumes/...随机字符串.../_data的这个卷的数据还在,那这个被删除的容器的持久化到本地的数据就永远在 下图7
docker volume ls
docker volume inspect VOLUME-NAME # 下图7
cat /var/lib/docker/volumes/...随机字符串.../_data/index.html # 下图7
图1:
图2:
图3:
图4:
图5:
图6:
图7:
docker -v 选项配置详细的细节信息(--mount)
docker run -d --name webtest --mount type=bind,source=/root/htdocs,destination=/usr/local/apache2/htdocs httpd
docker run -d --name devtest --mount type=bind source="$(pwd)/htdocs",target=/usr/share/nginx/html nginx:latest
docker rm -f devtest
docker run -d --name devtest --mount type=bind source="$(pwd)/htdocs",target=/usr/share/nginx/html,readonly nginx:latest
docker inspect devtest # 如下图1
图1:
上图Propagation属性是什么?传播方向,默认是给绑定挂载和卷模式提供rprivate
rprivate代表递归目录下所有的,只有在bind mount配置的时候使用,而且在linux主机(相对于容器,就是宿主机)上配置
propagation:rshared|rslave|rprivate # r代表递归所有目录都生效
shared:原始挂载的子挂载只公开给父挂载,父挂载的子挂载也传播给原始挂载
slave:类似于共享挂载,但是只有一个方向;如果原始挂载公开子挂载,则父子挂载可以看到它;但是如果父子挂载公开子挂载,则原始挂载是没办法看到它,就是宿主机目录一旦挂载,就不能再共享给别人。# 如下图1
private:mount私有的挂载,但其中的子挂载不公开给父本挂载;而父本挂载也不公开给原始挂载。
docker run -itd --name devtest --mount type=bind,source="$(pwd)"/htdocs,target=/usr/shate/nginx/html --mount type=bind,source="$(pwd)"/htdocs,target/usr/share/nginx/html2,readonly,bind-propagation=rslave nginx
docker exec -it devtest bash
cd /usr/share/nginx
ls
'''
html html2
'''
ls html/
'''
index.html
'''
ls html2/
'''
index.html
'''
echo 123 > html/index.html # 正常
echo 456 > html2/index.html # 无法写入 ,如下图1
创建volume
docker volume create volume-test1 # 下图1
docker volume ls # 下图1
那被创建的volume-test1卷被放在哪了呢?依然在 /var/lib/docker/volumes 目录中。
cd /var/lib/docker/volumes
ls
'''
_data
'''
cd _data/
ls # 下图1
'''
是一个空目录
'''
如何使用这个创建的卷?
docker run -itd --name bbox1 --volume volume-test1:/volume busybox # 下图2
docker exec -it bbox1 sh
cd /volume
echo "I am in container." > testfile
exit
cat /var/lib/docker/volumes/testfile
'''
I am in container.
'''
docer inspect -f {{.Mounts}} bbox1
图1:
图2:
volume container
volume container:卷容器,专门为其它容器提供卷的容器,它提供的卷可以是 bind mount,也可以是docker managed volume。一旦创建出容器卷,它就永远维持在Created的状态,在实际场景中,发现有created状态的容器,一定要小心是容器卷,别误删了,导致其它依赖此容器卷的容器无法正常运行。。
bind mount:存放webserver的静态文件
docker managed:存放的是一些使用工具
docker create --name vc_data --volume ~/htdocs:/usr/local/apache2/htdocs --volume /usr/local/apache2/logs busybox
docker inspect vc_data # 下图1
docker run --name web10 -d -p 80 --volumes-from vc_data httpd
docker run --name web20 -d -p 80 --volumes-from vc_data httpd
docker run --name web30 -d -p 80 --volumes-from vc_data httpd
docker ps
curl 192.168.31.168:49157
'''
THE NEW PAGE
'''
curl 192.168.31.168:49158
'''
THE NEW PAGE
'''
curl 192.168.31.168:49159
'''
THE NEW PAGE
'''
# 查看容器web10容器中的/usr/local/apache2/logs 日志是否持久化到容器中 如下图3
docker inspect web10
docker volume ls
使用容器卷有啥好处呢?貌似比单独一个一个目录挂载要方便一点。。。
docker run --name web10 -d -p 80 --volume ~/htdocs:/usr/local/apache2/htdocs --volume /usr/local/apache2/logs httpd
docker run --name web20 -d -p 80 --volume ~/htdocs:/usr/local/apache2/htdocs --volume /usr/local/apache2/logs httpd
docker run --name web30 -d -p 80 --volume ~/htdocs:/usr/local/apache2/htdocs --volume /usr/local/apache2/logs httpd
# 实现多个容器卷挂载 下图4
mkdir -p /data/test1
mkdir -p /data/test1
echo "web1" > /data/test1/test.txt
echo "web2" > /data/test2/test.txt
docker create --name bbox1 --volume /data/test1:/data/test1 busybox
docker create --name bbox2 --volume /data/test2:/data/test1 busybox
docker run -itd --name bbox --volumes-from bbox1 --volumes-from bbox2 busybox
docker exec -it bbox sh
cd /data/
ls
'''
test1 test2
'''
图1:
图2:
图3:
图4:
volume备份
mkdir backup
cd backup/
docker ps -a
docker create --name bbox1 --volume /data/test1:/data/test1 busybox
docker run --rm --volumes-from bbox1 -v $(pwd):/backup busybox tar -cvf /backup/backup.tar /data/test1
外部存储(nfs)使用volume
使用nfs跨主机将目录挂载到卷,卷再挂载到容器,实现volume数据映射;
适合场景:动态webserver
# 192.168.1.4主机
yum install nfs-utils rpcbind -y
mkdir /data/nfs/docker -p
vim /etc/exports
/data/nfs *(rw,no_root_squash,sync)
exportfs -r
systemctl start rpcbind
systemctl start nfs-server
showmount -e 192.168.1.4
iptables -F
iptables-save
# 192.168.1.102主机
yum install nfs-utils rpcbind -y
showmount -e 192.168.1.4
'''
Export list for 192.168.1.4:
/data/nfs *
'''
docker volume create --driver local --opt type=nfs --opt o=addr=192.168.1.4,rw --opt device=:/data/nfs volume-nfs # 如下图1
docker volume ls
'''
DRIVER VOLUME NAME
local 7472e9111edcc80fa8b59df69255e93a30f9ed9ca752c21b21cc5cea4dce0d43
local c06700a785d3387655ea79bf1790f01109b19eec758d5f030fd331875f7b4a0a
local f1dbfae59d757137b078be56f5583d51e496fa45f81a15108f82260b650ec773
local volume-nfs
local volume-test1
'''
docker volume inspect volume-nfs
'''
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/volume-nfs/_data", # 把192.168.1.4主机/data/nfs目录挂载到当前主机(192.168.1.102)此目录中了
"Name": "volume-nfs",
"Options": {
"device": ":/data/nfs",
"o": "addr=192.168.1.4,rw",
"type": "nfs"
},
"Scope": "local"
}
]
'''
cd /var/lib/docker/volumes/volume-nfs/_data
docker run -itd --name bbox1 --volume volume-nfs:/nfs busybox
docker inspect -f {{.Mounts}} bbox1
'''
[{volume volume-nfs /var/lib/docker/volumes/volume-nfs/_data /nfs local z true }]
'''
docker exec -it bbox1 sh
ls
'''
bin dev etc home nfs proc root run sys tmp usr var
'''
cd nfs
ls
'''
docker
'''
echo "go go go! " > testfile
exit
# 查看当前主机(192.168.1.102)当前目录(/var/lib/docker/volumes/volume-nfs/_data)没有再容器中拆功能键的文件testfile,这其实不会保存到当前主机卷中的,而是保存到远程主机nfs文件系统目录/data/nfs目录中的。。。。
ls # 为空
去192.168.1.4主机的/data/nfs目录中查看 # 如下图2
图1:
图2:
data-packed volume container
data-packed volume container:将数据打包到镜像中,再用这个镜像做成卷容器,其它容器在启动时再引用这个卷容器;
优点:不依赖主机数据,具有非常强的移植性
缺点:只适合静态场景,比如:webserber的静态文件
# 以apache静态文件默认目录为例,将我们宿主机的挂载目录拷贝到容器中,打包成镜像
FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs # 将此目录(在容器中)映射到宿主机,如果不映射出来,想修改的时候就很麻烦
docker build -t ./Dockerfile datapacked . # 下图1
docker create --name vc_data datapacked
docker run -d --name web-ser -p 8111:80 --volumes-from vc_data httpd
curl 192.168.1.102:8111
docker inspect web-ser # 下图2
docker exec -it web-ser sh # 下图3
图1:
图2:
图3: