Docker使用数据容器
简介
参考文件CSDN
需求: 代码单独打包为数据容器,其他的应用环境 docker 从此 docker 中获得数据,然后运行。
基本知识
在 Docker 的使用过程中往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,所以这就涉及到 Docker 容器的数据操作。
容器中数据管理主要有两种方式:数据卷和数据卷容器。
- 数据卷(Data Volumes) 容器内数据直接映射到本地宿主机。
- 数据卷容器(Data Volume Containers) 使用特定容器维护数据卷。
数据卷
数据卷是一个特殊的目录,它将主机目录直接映射进容器。可供一个或多个容器使用。
数据卷设计的目的就是为了 数据的持久化,它完全独立与容器的生命周期。因此,容器删除时,不会删除其挂载的数据卷,也不会存在类似的垃圾机制对容器存在的数据卷进行处理。
数据卷的特性:
- 数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会拷贝到新初始化的数据卷中
- 数据卷可以在容器之间共享和重用
- 可以对数据卷里的内容直接修改,修改回马上生效,无论是容器内操作还是本地操作
- 对数据卷的更新不会影响镜像的更新
- 数据卷会一直存在,即使挂载数据卷的容器已经被删除
创建数据卷的方法 : docker run -v /lcoaldir:/volumedir -it /image /bin/bash
Notice: Docker
挂载数据卷的默认权限是读写(rw), 通过上面的 "RW": true 可以看到,我们也可以在创建的时候进行设置为只读。
使用 ro
这种是通过-v
的形式进行挂在容器的,还可以通过 Dockerfile
的创建镜像的形式 进行挂载,但是这种挂载通过此镜像创建的 Container
是完全独立的。
#Dockerfile
FROM hub.c.163.com/library/ubuntu
VOLUME ["/datavolume1","/dockervolume2"]
CMD /bin/bash
1.执行 docker build -t df_vo .
生成镜像。 2.利用这个镜像创建 Container. docker run --name votest1 -it df_vo
这样的形式生成的 Continer
数据是相互独立的。
数据卷容器
用户需要在多个容器之间共享一些数据,就可以使用数据卷容器。
命名的容器挂载数据卷,其他容器通过挂载这个容器实现数据共享,挂载数据卷的容器,就叫数据卷容器。
- 先创建一个容器
- 然后挂载。
挂载数据卷容器的方法:
用户需要在多个容器之间共享一些数据,就可以使用数据卷容器。
docker run --volumes-from 容器名
命名的容器挂载数据卷,其他容器通过挂载这个容器实现数据共享,挂载数据卷的容器,就叫数据卷容器。
下面我们进行如下的数据卷容器的实验
- 先创建一个数据容器镜像
#Dockerfile
FROM alpine
WORKDIR /app
COPY ./datavolume1 .
VOLUME ["/app"]
RUN apk add --no-cache bash
注意 COPY 命令不能使用绝对路径。必须使用相对路径。
命令说明:
-
VOLUME 命令: 在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
-
RUN apk add --no-cache bash
to keep docker image size small. 最小化安装 bash。
-
对镜像进行编译。
docker build -t df_vo .
-
然后对进行进行创建 Container。
docker run --name votest -itd df_vo
-
挂载数据卷容器的方法:
docker run --volumes-from 容器名
#启动一个数据盘容器, 数据盘挂载votest容器。
docker run -it --name votest_data1 --volumes-from votest df_vo
--------------数据变化测试--------------
这个可以在 votest_data1 中的 app 目录下看到从 磁盘带进来的数据。
做如下测试:
- 修改 votest 容器中的数据, votest_data1 中的数据发生变化。
- 修改 votest_data1 中数据 votest 容器中的数据发生变化。
再次搞个容器 votest_data2 进行测试
docker run -it --name votest_data2 --volumes-from votest df_vo
这个时候在启动一个 votest_data2 同样的做文件变动测试,三者完全是联动的。
其实这些是否联动通过docker inspect
命令,找到 Mounts/Name ,表示挂载磁盘的位置。
现在再进行下一步的测试:
启动两个也带有 -v
挂载方式的容器。 启动命令如下:
docker run -it --name votest_data3 -v /home/homework/Cobra/docker/datavolume/log:/app/log --volumes-from votest df_vo
docker run -it --name votest_data4 -v /home/homework/Cobra/docker/datavolume/log:/app/log --volumes-from votest df_vo
做如下测试:【3 应用容器,4 应用容器 ,0 代表数据卷容器, L 代表主机本地,log 目录为从硬盘来源目录】
其中 log 在 应用容器 和 本地是完全相通的。
其中 0,3,4 数据之间的数据是完全相通的。
通过-v 挂进去的数据磁盘,不会影响到数据卷。 他们各自在各自的区域内形成的数据相互影响。
下面我们做下停机的相关测试
-
将 3 数据容器给停止掉。
docker stop votest_data3
在 4 中修改各自范围内文件,0 变,本地也变,他们不会收到 3 的影响。
将 3 数据容器启动,docker start votest_data3
首先看到 3 中的文件已经改变了。已经和 4,5 同步。 -
现在将 0 停掉
docker stop votest
在 3 中修改 数据卷挂载进来的数据。这个时候也会影响到 4。 也就是 3 和 4 是相互通的。
(尽管现在已经将数据盘给停掉了!!!!!!)
这个特性太牛逼了,这样可以将数据盘进行 Hot--Update,不会影响业务使用。现在将数据盘重新进行启动,查看 3 和 4 中的数据是否会更新?
docker run votest
这个时候启动发现数据盘容器的数据也恢复到了 和 3、4 号容器同步了。 这个。。。。 -
现在我们重新对 votest container 删除掉,然后重新创建,我看看下 3、4 号 container 的反应。
docker stop votest
docker rm votest
docker run --name votest -itd df_vo
这个时候发现 数据 votest container 已经完全和 3、4 号容器隔离了。
修改 votest 不会引起其他的变化。
Now!!!我们继续测试。docker restart votest_data3
对 3 号容器进行重启,看看其数据变化情况。
- 重启发现 3 号和 4 号依然是旧的数据容器并且是相通的。
- 同时关闭 3 和 4 然后同时重启,不管怎么操作 3 和 4 都是相通的。。
说明 docker start/stop 不能打断他们想通性。
Now!!! 那我们怎么让应用程序 更新 最新到最新的 votest 的数据容器呢?
docker stop dvtest_data3
docker rm dvtest_data3
#再次重建生成容器
docker run -it --name votest_data3 -v /home/homework/Cobra/docker/datavolume/log:/app/log --volumes-from votest df_vo
这个时候发现 votest_data3 和 votest 的数据进行了同步。 这样就是实现了数据的同步。
结论:如果要实现数据的热更新,应该对 votest 然后对 votest_data 依次进行重新生成 Container。
数据卷的备份和还原
数据卷备份使用的命令:
docker run --volumes-from 存在的容器名 -v $(pwd):/backup --name 新建的容器名 镜像名 tar cvf /backup/backup.tar 数据卷
$(pwd)当前路径
docker run --volumes-from votest-data5 -v /root/backup:/backup hub.c.163.com/library/ubuntu tar cvf /backup/vof1.tar /app
这个时候会出来一个包。在/root/backup 的目录下,有个 vof1.tar 的包。
这个原理很简单,新建一个 Container,然后挂盘本地的磁盘,然后执行 tar 命令备份指定的文件夹。
数据卷的还原
使用命令类似:
docker run --volumes-from 存在的容器名 -v $(pwd):/backup --name 新建的容器名 镜像名 tar xvf /backup/backup.tar
示例:
创建一个容器 votest8 还原数据卷,这样数据就又重新回来了。
docker run --volumes-from votest_data6 -v /root/backup:/backup --name votest8 hub.c.163.com/library/ubuntu tar xvf /backup/vof.tar
通过 docker ps -a 可以看到创建的数据容器。
最后创建一个容器挂在 votest_data6,就可以看到恢复的数据了。
docker run -it --volumes-from votest_data6 hub.c.163.com/library/ubuntu /bin/bash
注意这个容器里面会多出来一个 backup 的文件夹,正式备份的文件,其他的文件也已经加载进来。 这种查看的方法是通过创建一个 container 进去进入查看。
Docker 启动容器后位置越来越大处理方法
默认情况下 Docker 的存放位置为:/var/lib/docker
我们可以通过下面的命令查看
sudo docker info | grep "Docker Root Dir"
解决这个问题,最直接的方法当然是挂载分区到这个目录,但是我的数据盘还有其他东西,这肯定不好管理,所以采用修改镜像和容器的存放路径的方式达到目的。
这个方法里将通过软连接来实现。
首先停掉 Docker 服务:
sudo systemctl stop docker
然后移动整个/var/lib/docker
目录到目的路径:
mv `/var/lib/docker` /data/docker
ln -s /data/docker `/var/lib/docker`
这时候启动 Docker 时发现存储目录依旧是/var/lib/docker
,但是实际上是存储在数据盘的,你可以在数据盘上看到容量变化。
Docker 将普通用户加入到 docker 组中
可以使用普通用户对 docker 进行管理
sudo usermod -aG docker cobra