docker 卷

就是数据持久化,因为容器中数据随着容器的删除,数据就没了,而且容器间数据不共享。

解决的办法就是,挂载和卷。

  • Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层
  • 如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的浅副本所隐藏,此即“写时复制机制”

 

先模拟docker容器内部数据丢失的例子。

这说明啥?说明在容器内的改动了,不会随着它的启动或停止而消失,但是要是再把它删了,在启动一个新的容器,之前容器数据就丢失了。我觉得这是理所当然的,没什么好奇怪的,但是还要BB下。

# 1.首先创建了容器
docker run -d --name nginx-test nginx

# 2.在容器里打开个终端
docker exec -t nginx-test bash

# 3.为nginx的default.conf创建个副本作为新的config
cd /etc/nginx/conf.d
cp default.conf nginx-test.conf

# 4.此处不会修改nginx-test.conf的内容,现在停止该容器
docker stop nginx-test

# 5.再次启动该容器
docker start ngnix-test

# 6.在容器内打开个终端
docekr exec -it nginx-test bash

# 7看看变更是否存在
cd /etc/nginx/conf.d
ls 
default.conf nginx-test.conf

# 8.由于该容器之前仅仅是被停止了,所以数据还存留着。再来停止删除容器
docker stop ngnix-test
docker rm nginx-test

# 9.启动个容器, 启动的是新容器
docker -d --name nginx-test nginx

# 10.再次运行终端
docker exec -it nginx-test bash

# 11.检查nginx conf.d 目录的内容
cd /etc/ngnix.conf.d
ls 
default.conf

 

 

绑定挂载

写在前面:

个人的理解,绑定挂载,就是给宿主机的目录起一个别名,然后在给这个别名放到容器中。

宿主机文件  <==> 容器文件,  宿主机和容器公用一个文件,不管谁修改文件,修改对对方都是可见的

 

在绑定挂在中,宿主机上的文件/目录会被挂载到容器中。

接下来,将会把Docker宿主机的主目录挂载到容器中一个名为host-home的目录。

这些输出表名,该挂载是绑定类型,其源是Docker宿主机目录,就是/User/xxx,而其挂载的目标是/host-hom。

docekr run -it --name mount-test type=bind, source="$HOME",target=/host-home ubuntu bash
或
docker run -it --nmae mount-test -v &HONE:/host-home ubuntu bash

然后查看刚才创建的容器
docekr inspect mount-test | jq .[0].Mounts
[
 {
  "Type": "bind",
  "Source": "/Users/xxx",
  "Destination":"/host-home"
  }
]

 

然后进入容器终端,执行操作

# 查看挂载是否正常
cd /host-home
ls

cd /host-home
echo "This is a file created from container having kernrl `uname -r`" > host-home-file.txt

这个文件是从位于该容器的/host-home目录中一个拥有linuxkit-aufs内核的容器创建的。由于这是Docker宿主机目录的绑定挂载,所以也应该在Docker宿主机主目录创建这个文件。

进入宿主机

cd ~ 
ls -lah host-home-file.txt           -h是显示更为易读的容量
会显示文件

这些信息表明,在容器中创建的文件的确可供容器外部使用。

然后可以停止容器,删除容器,再访问家目录,发现host-home-file.txt依然是存在的。

而且,要注意,绑定挂载的数据流是双向流动的,任何破坏性的操作,也都会对Docker宿主机造成负面影响。

所以说如果一段错误的脚本rm-rf 就可能造成Docker宿主机全面宕机。为避免这个问题,我们可以创建一个具有只读的选项的绑定挂载。

下面是只读挂载

docker run -it --name mount-test --mount type=bind,source="$HOME",target=/host-home,readonly ubuntu bash

或

docker run -it --name mount-test -v $HOME:/host-home:ro ubuntu bash
# 宿主机目录:容器目录


docker inspect mount-test | jq .[0].Mounts
# 发现变成ro,只读了。
[
 {
   ...
   "Mode":"ro",
 }
]

然后可以测试下只读挂载

echo "This is a file created from container having kernel `uname -r`" > host-home-file.txt 
# 会返回失败,说文件是只读的。


rm host-home-file.txt
# 也会返回失败,

 

使用卷时,会在Docker宿主机的Docker存储目录中创建一个新目录,并且目录的内容时由Docker来管理的。

Docekr卷时目前最为推荐的将容器中存储的数据持久化的方法。卷完全是由Docker托管的,并且相对于绑定挂载而言,卷有很多优势

  • 卷比绑定挂载更易于备份和转移
  • 卷同时适用于Linux和Windows容器
  • 可以顺利地跨多个容器共享卷

下面是关于Docker卷的几条命令

  • docker volume create
  • docker volume inspect
  • docker volume ls
  • docker volume prune
  • docker volume rm

创建卷

docker volume create --name=<name of the volume> --label=<any extra metadata>

docekr volume create --name=nginx-volume
# 创建一个叫ngixn-volume 的卷

查看详情

docker volume inspect nginx-volume

docker volume inspect nginx-volume

[
 {
  ...
   "Mountpoint": "/var/lib/docker/volumes/nginx-volume/_data"
  ...
 }
]

Mountpoint 属性列出了docker宿主机上的位置,该位置保存了包含卷数据的文件

列出卷信息

显示了宿主机上存在的所有卷

docker volume ls

精简卷

会移除本地未使用的本地卷,就是自动删除没使用的卷,不能指定要删哪个

docker volume prune <--force>

如果没有一个容器在使用卷,那么Docker就会认为这个卷是未使用的。 --force 是命令运行时将不会要求用户确认。

移除卷

docker 不会移除使用中的卷,并返回一条错误信息。

docker volume rm <name>

docker volume rm nginx-volume

 

下面是重点

在启动容器时使用卷

# 先创建个卷
docker volume create volume-test

docker run -it --name volume-test --mount source=volume-test,target=/data-volume ubuntu bash
或者
docker run -it --name volume-test -v volume:/data/volume ubuntu bash
# 卷的名:关联容器里的路径
# 在容器终端输入
echo "This is a file created from container having kernel `uname -r`" > docker_kernel_info.txt

# 然后删除停止容器
docker stop volume-test
docker rm volume-testa
# 重启启动个容器,再绑定上卷
docker run -it --name volume-test -v volume-test:data-volume ubuntu bash

cd /data-volume/
ls
docker-kernel-info.txt

cat docker -kernel-info.txt

使用卷就是为了让Docker将数据存储在由Docker自身管理的卷文件中。在启动新容器时,与run命令一起提供卷名称就会将这个卷附加到容器了,从而让之前保存的数据可提供新启动容器使用。

自己的理解:

和前面的挂载有啥子区别?感觉不一样,但又说不出,还在现在都用卷,也就不用花费我的精力去想用哪种方法了。

就是先创建个卷,然后启动容器时,加上这个卷,然后还要制定容器的哪个目录和这个卷关联。容器在这个指定目录存得数据,不会随着容器的删除而消失,再启动个容器,-v 指定这个卷和这个容器要关联的目录,在这个容器的目录里就可以直接访问上个容器存得数据了。说的自己都有些乱,但是我觉得自己时理解了,原理,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值