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:

原文地址:https://www.cnblogs.com/zhangchaocoming/p/15526936.html