第6节 Docker数据持久化和数据卷
之前VOLUME也可以实现数据持久化,就是容器删掉,数据还在宿主上放着,就是有点缺点,太乱了,存放没法自定义,或者要-v 命令行选项的方式来指定。
再来看下镜像和容器的分层数据存放
image的
容器的
首先容器run起来就是复制一份image
因为这个容器停掉了,所以数据释放掉了,running起来,才有merge才有复制image的那一份。
挂一个前台让他running
再看分层数据
这次就看到merged了👆
然后我将image和run起来的容器的分层目录 放一起看看
上图是容器里的meger复制了一份image里的diff,其实inspect容器可见LowerDir分层里直接写了image的diff分层,
容器生成的数据是放在diff下,比如日志、以及其他容器中生成的新的数据,这个diff就是可读可写层。
看下日志,应该就在UpperDir也就是diff里。不过我上面是tail -f /dev/null,没有日志输出,所以重新run一个有std的
然后去分层diff里看
但是显然是没有的,因为,没有落文件
落一个文件
现在diff里是空的
然后生成一个新的文件
然后UpperDir里就有了,于此同时merge作为合并层也就看得到了
这是容器起来后生成一个新的文件,如果是容器build的时候生成文件会出现在哪个目录里呢?
这里做了日志文件和生成了test文件,不过是build的时候就已经生成test了,看看
可见build阶段的文件是不会出现在UpperDir里的。而是出现在LowerDir里的diff里的
分层目录理解:结论来了
1、diff就是容器和镜像相比 diff出来的,就是多出来的
2、而UpperDir的diff就是容器的可写层
3、而LowerDIr的diff就是基于某个FROM基础镜像创建新的镜像的时候的底层。是可写的,因为不管是test还是access.log都是可以写的。 其实是不可写的,就是build的时候打进去的,后面可写都是UpperDir里的diff才是,LowerDirr的diff只是 区别于 FROM基础镜像的diff,同样也是只读层。
3、LowerDir里的每个路径之间用冒号分隔,代表一层层build的时候的封装。
4、merged就是联合文件整体的呈现。
下面开始学习持久化保存
1、session这些就是有状态的东西,没必要持久化。
2、mysql数据需要持久化,需要持久化。
持久化的的方法就是:
1、容器删除,/var/lib/doker/overlay2/xxxxxxxxx..xxx这个对应的文件夹就自动没了
2、对于重要的数据,单独存放到宿主的其他路径就行了。
具体的技术:
1、数据卷
2、数据集容器就是数据卷的变种,不常用
使用方法
docker run 命令的以下格式可以实现数据卷
-v, --volume=[host-src:]container-dest[:<options>]
<options>
ro 从容器内对此数据卷是只读,不写此项默认为可读可写
rw 从容器内对此数据卷可读可写,此为默认值
host-src 宿主机目录如果不存在,会自动创建
不管什么方法,肯定都不在/var/lib/docker/overlay2/下了,不会随容器删除而删除
方法1:手动指定宿主目录
#指定宿主机目录或文件格式:
—v <宿主机绝对路径的目录或文件>:<容器目录或文件>[:ro] # 将宿主机目录挂载容器目录,两个目录都可以自动创建
方法2:卷ID
# 匿名卷,只指定容器内路径,没有指定宿主机路径信息,宿主机自动生成/var/lib/docker/volumes/<卷ID>/_data目录,并挂载至容器指定路径
-v <容器内路径>
# 示例:
docker run --name nginx -v /etc/nginx nginx
方法3:卷名比卷ID识别度好,最通用的方式。
#命名卷将固定的存放在/var/lib/docker/volumes/<卷名>/_data
-v <卷名>:<容器目录路径>
# 可以通过以下命令事先创建,如果没有事先创建卷名,docker run时也会自动创建。
# 里面外面都能自动创建文件夹,但是文件不行!
#示例:
docker volume create vol1 # 也可以事先不创建,就是这句可以不写的。
docker run -d -p 80:80 --name -v vol1:/usr/share/nginx/html nginx
docker rm 的-v选项可以删除容器的时候,同时删除相关联的匿名卷,只能是匿名卷
这种删除就会删掉①docker run -v 和Dockerfile里的VOLUME都是匿名,都会被删掉。
-v,--volumes Remove the volumes associated with the container
这是之前Dockerfile里的VOLUME也有类似的效果,好像就是方法2的效果一样。
这种就是随机字符串的目录名,没有可读性好的名字,所以一般就称之为匿名卷。没有名字
实验
把之前nginx的容器的Dockerfile来做挂载VOLUME实验
Dockerfile.son本次实验不要太关注,就是测试ONBUILD 指令的。
先跑一个不用方法3的,因为Dockerfile理由指定VOLUME所以也就是方法2的效果
先清一下none的镜像docker images -f "Dangling=true"
不run一下是没有VOLUME卷的是吧...应该是的
run起来看看
然后重点关注VOLUME
因为HOST变量没有值,所以文件也是空的👇
然后在宿主机上往里面写点东西玩玩哈哈
这不就有了吗,哈哈,其实应该去entrypoint.sh脚本里,给HOST赋值才对哦~~
顺便也瞟一眼健康检查的log
先看下方法2的匿名卷(也就是VOLUME名称是随机一长串字符串)的效果
我想通过runlike看到VOLUME的值,看来build阶段的VOLUME,run阶段是看不到的,runlike就是看docker run的选项的。
只能通过inspect去看咯
可见这个VOLUME名称是不友好的,改之,
docker run -d --name web2-run -P -v /dirtest/html:/dirtest/html -e DO C_ROOT=/dirtest/html/ -e HOST=ttttttt web1
👇图中-e DOC_ROOT 和-e HOST是传参,跳转页面转发路径,以及HOST这里赋值修复脚本里没给HOST赋值的情况。
上图👆curl的时候HOST要注意,已经被你改成tttttt了。
容器里面也是自动创建了这个目录
好了然后这个VOLUME也是自定义的就比较好维护了
方法3才是最棒的
docker run -d --name web3-run -P -v vol1:/dirtest/html -e DOC_ROOT=/dirtest/html/ -e HOST=www.test.tk web1
不要自己定义宿主的挂载目录,就用统一的/var/lib/docker/volumes/起个名字/_data/就行。
然后要注意就是Dockerfile里的VOLUME你也没删,docker run 的时候又-v vol1:/dirtest/html
所以就是创建了两个挂载卷了👆。
插播docker起不来排错思路
docker build ok,run的时候没有达到预期的排错
1、正向检查,Dockerfile是否ok
2、docker ps -a看看里面的信息,特别是CMD,不过看不全,没事用
由于又报错了
所以上面说的
还是改为截图吧
看的全
3、docker run去掉-d,不挂后台,run着看看
4、docker logs看看现象
5、docker exec 进去手动其服务或则CMD的命令,起不来无非是CMD那条问题,起来还有别的问题才是进一步的配置设置之类的,用ENTRYPOINT和CMD的组合来解释,通常是初始化脚本没初始化好等等。或者RUN里的的apk add漏安装包啦之类的。
下图说明如果挂载的宿主卷里有文件,然后Dockerfile里有COPY了同名这个文件进去,哪一个优先,宿主的优先会覆盖掉的,如果vol1里是空的,就不会覆盖同名的文件了👇
-v只能自动删除 匿名卷
①docker run -v dir xxx 这种自动创建的匿名卷
②Dockerfile里的VOLUME配置后run出来的匿名卷
查看卷
单独创建卷
方法1指定宿主机的目录就不是能在docker volume ls里看的到的了
看不到就不叫数据卷,方法1直接挂宿主机目录,这个目录就不是数据卷。
方法2,方法3,一个是匿名卷,一个是命名卷,都是有名字的数据卷。
只读,指的是容器里只读
容器里是只读
宿主里是可写的
此时容器里面就看到了
工作案例分享
linux如何拨v2ray
1、搭建桥接client,server利旧
1、安装docker
https://mirrors.tuna.tsinghua.edu.cn/help/docker-ce/
2、pull镜像
https://hub.docker.com/r/v2fly/v2fly-core/tags
3、run容器
https://github.com/v2fly/docker
修改配置文件为👇根据你server那边的进行配置就行。
不行,进去看, # 其实就是修改配置文件后没有重启容器
换下国内源
https://mirrors.tuna.tsinghua.edu.cn/help/alpine/
安装curl测试,在容器里
然后正式实施的时候加上--restart always和安装runlike
docker run -d --name v2ray --restart always -v vol1:/etc/v2ray -p 10086:1080 v2fly/v2fly-core run -c /etc/v2ray/config.json
yum -y install python3-pip
pip install runlike
2、搭建nginx反代,不需要搞错了
将sockt反指到本地监听端口
别搭了了,需求搞错了,目前正确的需求是将所有流入进来的流量,转发到本地的socks5:10086上去。
而不是再配置一个nginx去暴露一个端口
2、构建本地流量转发
1、使用ssh试试
不行,ssh也是要指定端口的
2、iptables 可行
3、redsocks 可行
明天继续
https://tttang.com/archive/1878/
https://www.cnblogs.com/zhenyuyaodidiao/p/5494569.html
而且要构建三层代理的转发,但是通过docker exec进去发现监听的是tcp/udp,也就是说只支持4层代理,就是socks代理。不是我需要的东西,该实验暂停~
还是用softehter就行~
然后如何设置全局代理,配置变量就行了,不管是本地还是给鄙人用
1、linux
2、windows
然后
浏览器可以代理,cmd不行,也就是说明了
socks不管是5还是4也无法代理cmd,全软件代理还得依靠APP本身指向socks。
cmd 里没看到proxy变量设置,所有没有走代理,手动配置一个,就像linux一样
cmd里还不用用socks变量,的用linux一样的socks5
概念梳理:
全协议:http的代理、socks4代理tcp、5就是tcp/udp都支持,这种需要APP自己走socks套接字才行的。默认浏览器就会走socks,但是cmd这些就需要手动配置代理变量为socks5,其他APPS同理。这是两个概念,全协议是隧道本身的属性,APPS走隧道时APPS自己的配置。
有一种就是无需APPS配置,直接所有软件 浏览器、cmd、等等 统统走隧道,就是全软件代理。这就要虚拟网卡将默认网关全部打到隧道里去:
全软件:最新的v2ray tun模式是由虚拟网卡的,电脑上所有软件的流量就虚拟网卡就是全软件代理了。包括cmd都代理了。 # 这种就是要虚拟网卡的。
全局:沟通要统一,我习惯全局就是这里,是全部流量都走代理,就是不分流的意思。