zoukankan      html  css  js  c++  java
  • 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:

  • 相关阅读:
    POJ 3114 Tarjan+Dijkstra
    278. First Bad Version
    209. Minimum Size Subarray Sum
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    710. Random Pick with Blacklist
    767. Reorganize String
    524. Longest Word in Dictionary through Deleting
    349. Intersection of Two Arrays
    350. Intersection of Two Arrays II
  • 原文地址:https://www.cnblogs.com/zhangchaocoming/p/15526936.html
Copyright © 2011-2022 走看看