docker入门-Docker的储存

  • 默认情况下,在运行中的容器里创建的文件会被保存在一个可写的容器层
  • 如果这个容器被删除,数据也会随之丢失(停止容器时不会丢失数据)
  • 可写的容器层和特定的容器进行绑定,即这些数据无法方便的与其他容器共享

针对数据持久化的问题,Docker主要提供了两种方式:

  • Data Volume:由Docker管理,是持久化数据最佳方式
  • Bind Mount:由用户指定储存的数据挂载在系统什么位置

在这里插入图片描述

1. Data Volume

  • 创建一个Dockerfile文件和my-cron文件,这个镜像的作用是执行计划任务(这里是每隔一分钟输出时间到一个文件里),具体过程可以参考Docker Blog

Dockerfile_Volume:

FROM alpine:latest
RUN apk update
RUN apk --no-cache add curl
ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.1.12/supercronic-linux-amd64 \
    SUPERCRONIC=supercronic-linux-amd64 \
    SUPERCRONIC_SHA1SUM=048b95b48b708983effb2e5c935a1ef8483d9e3e
RUN curl -fsSLO "$SUPERCRONIC_URL" \
    && echo "${SUPERCRONIC_SHA1SUM}  ${SUPERCRONIC}" | sha1sum -c - \
    && chmod +x "$SUPERCRONIC" \
    && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \
    && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic
COPY my-cron /app/my-cron
WORKDIR /app
# RUN cron job
CMD ["/usr/local/bin/supercronic", "/app/my-cron"]

my-cron:

*/1 * * * * date >> /app/test.txt
  • 创建镜像:docker image build -f Dockerfile_Volume -t my-cron .
  • 创建容器:docker container run -d my-cron
  • 进入交互式shell:docker container exec -it 379 sh

完成上述操作后进入到容器内部后,会查看到my-cron文件和output.txt文件,每隔一分钟去查看output.txt会出现新的时间戳。

问题1:如果将容器删除后,output.txt文件也就被删除了,该如何持久化储存在磁盘上?

  • 修改Dockerfile文件,在其中添加VOLUME命令:

Dockerfile_Volume_New:

FROM alpine:latest
RUN apk update
RUN apk --no-cache add curl
ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.1.12/supercronic-linux-amd64 \
    SUPERCRONIC=supercronic-linux-amd64 \
    SUPERCRONIC_SHA1SUM=048b95b48b708983effb2e5c935a1ef8483d9e3e
RUN curl -fsSLO "$SUPERCRONIC_URL" \
    && echo "${SUPERCRONIC_SHA1SUM}  ${SUPERCRONIC}" | sha1sum -c - \
    && chmod +x "$SUPERCRONIC" \
    && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \
    && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic
COPY my-cron /app/my-cron
WORKDIR /app

VOLUME ["/app"]

# RUN cron job
CMD ["/usr/local/bin/supercronic", "/app/my-cron"]

VOLUME ["/app"]/app表示VOLUME需要持久化的容器目录

  • 重新构建镜像和容器
  • 查看已经存在的VOLUME的NAME:执行docker volume ls会出现VOLUME NAME
  • 查看VOLUME详细的信息:执行docker volume inspect (完整的VOLUME NAME),会出现该VOLUME详细的信息,其中Mountpoint就是该VOLUME储存文件(即容器/app目录下的文件)的位置,此时便可以查看该位置下被持久化储存的文件(在Windows系统下是无法直接根据这个路径进行查看文件,需要到docker engine中查看),这个文件同样每隔一分钟会出现新的时间戳

在这里插入图片描述

问题2:此时使用该镜像再次创建新的容器,就会出现一个新的VOLUME(VOLUME NAME每次是随机的),导致数据储存的位置不一样了,但是我们的目的是尽管创建了新容器,还是要使用相同VOLUME的数据(即可以继续使用原来output.txt中的数据),要实现这个要求该如何操作?

  • 创建新容器的时候指定VOLUME的名字:执行docker container run -d -v cron-data:/app my-cron。其中,cron-data为自定义的VOLUME名字,/app与dockerfile文件中VOLUME ["/app"]的含义一致(不在dockerfile文件中写命令,直接指定-v也可)。这样再次创建新容器时执行相同的命令,就可以使用相同的VOLUME

tips:
docker volume prune -f:删除所有的volume(删除volume前要删除所属容器)

2. Bind Mount

在使用Data Volume时,每次执行如docker container run -d -v cron-data:/app my-cron命令时,相当于使用cron-data这个Volume给你指定的储存路径,这样会导致之前提到的Windows系统下无法直接查看储存的文件的情况。如果能直接指定本地用于储存文件的路径就会方便很多,此时就要使用Bind Mount:

docker container run -d -v $(pwd):/app my-cron:将原来的命令中指定的Volumecron-data改为当前路径$(pwd)(Linux下为圆括号,Windows下为大括号)即可,此时再使用docker volume ls不会出现新的Volume,并且在本机当前目录下会出现output.txt文件。

假如当前本机中没有gcc的编译环境,要使用container去完成某个C文件的编译和执行该如何操作?

  • 在本地的当前目录创建需要执行的hello.c文件
  • 创建一个gcc:9.4的镜像
  • 执行docker container run --it -v $(pwd):/root gcc:9.4进入到容器中
  • 此时在容器root目录下会出现hello.c文件,执行gcc -o hello hello.c./hello 即可完成
  • 在本地的当前目录也会出现编译好的hello文件

3. 多个机器之间的容器共享数据

之前的内容我们是将本地的目录和容器中的目录进行挂载,所以在查看VOLUME详细信息时会看到Driver:'local'

在这里插入图片描述

此时要实现两台主机容器间的数据共享该如何操作?

假设有两台主机,信息如下:

hostnameipssh usernamessh password
docker-host1192.168.200.10vagrantvagrant
docker-host2192.168.200.11vagrantvagrant
  • 在两台主机上都安装一个plugin vieux/sshfs:执行docker plugin install --grant-all-permissions vieux/sshfs

  • 在docker-host1中创建volume:

docker volume create --driver vieux/sshfs \
              -o sshcmd=vagrant@192.168.200.12:/home/vagrant \
              -o password=vagrant \
              sshvolume

​ 其中,vagrant@192.168.200.12:/home/vagrant表示指定目标主机储存的目录,sshvolume为创建的VOLUME NAME。此时查看该VOLUME的详细信息时会发现Mountpoint发生了改变,下图中表示将docker-host2的/home/vagrant挂载到了docker-host1的Mountpoint:

在这里插入图片描述

  • 创建容器挂载Volume:执行docker container run -it -v sshvolume:/app busybox sh,即实现挂载sshvolume到使用busybox镜像创建的容器的/app目录,然后进入容器的shell,在/app目录创建一个test.txt文件。此时在docker-host1、docker-host2都会出现test.txt文件

4. 参考

https://dockertips.readthedocs.io/en/latest/docker-volume.html

https://dockertips.readthedocs.io/en/latest/docker-blog/docker-cron.html

https://docs.docker.com/storage/volumes/#share-data-among-machines

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值