docker容器与宿主机的数据交互方式总结

前言

在生产环境中使用 Docker ,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作。

方式一、Docker cp命令

docker cp :用于容器与主机之间的数据拷贝。
语法
# 容器内文件 copy to 宿主机
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
# 宿主机文件 copy to 容器内
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

OPTIONS说明:
-L :保持源目标中的链接

操作示例:

宿主机到容器

容器到宿主机

注:此方式虽然他也可以管理但是数据不交融,基本不会使用,仅做了解

方式二、Docker数据卷

1. 什么是volume

  想要了解Docker Volume,首先我们需要知道Docker的文件系统是如何工作的。Docker镜像是由多个文件系统(只读层)叠加而成。当我们启动一个容器的时候,Docker会加载镜像层并在其上添加一个读写层。如果运行中的容器修改了现有的一个已存在的文件,那该文件将会从读写层下的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失。在Docker中,只读层以及在顶部的读写层的组合被称为Union FIle System(联合文件系统)。

  为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念。简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。

2. 数据卷的特性

• 数据卷 可以在容器之间共享和重用

• 对数据卷的修改会立马生效

• 对数据卷的更新,不会影响镜像

• 数据卷 默认会一直存在,即使容器被删除

3. 数据卷相关操作

Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes

  创建数据卷

Usage: docker volume create [OPTIONS] [VOLUME]
Create a volume
Options:
 -d, --driver string Specify volume driver name (default "local")
 --label list Set metadata for a volume
 -o, --opt map  Set driver specific options (default map[])

  查看所有数据卷

Usage: docker volume ls [OPTIONS]
List volumes
Aliases:
 ls, list
Options:
 -f, --filter filter Provide filter values (e.g. 'dangling=true')
 --format string Pretty-print volumes using a Go template
 -q, --quiet  Only display volume names

  查看单一或多个数据卷详情

Usage: docker volume inspect [OPTIONS] VOLUME [VOLUME...]
Display detailed information on one or more volumes
Options:
 -f, --format string Format the output using the given Go template

  删除单一数据卷

Usage: docker volume rm [OPTIONS] VOLUME [VOLUME...]
Remove one or more volumes. You cannot remove a volume that is in use by a container.
Aliases:
 rm, remove
Options:
 -f, --force Force the removal of one or more volumes

  删除所有闲置数据卷

Usage: docker volume prune [OPTIONS]
Remove all unused local volumes
Options:
 --filter filter Provide filter values (e.g. 'label=<label>')
 -f, --force  Do not prompt for confirmation

操作示例:

4. 数据卷使用

数据卷的使用,类似于 Linux 下对目录或文件进行 mount。

用户可以通过docker run的--volume/-v或--mount选项来创建带有数据卷的容器,但两个参数不能同时使用。

大体来说,--mount更加明确和冗长。最大的区别是-v语法将所有选项组合在一个字段中,而--mount语法将它们分离。对于新手来说建议使用--mount,因为更容易理解。

Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
Options:
 --volume list   Bind mount a volume
 --volume-driver string  Optional volume driver for the container
 --volumes-from list  Mount volumes from the specified container(s)
 --mount mount   Attach a filesystem mount to the container

4.1 --volume使用详述

  参数--volume(或简写为-v)只能创建bind mount。

命令格式:
-v [[HOST-OPTIONS:]CONTAINER-DIR[:OPTIONS]]]
HOST-OPTIONS:
VOLUME_NAME(数据卷名称)
ABSOLUTE-HOST-DIR(宿主机文件目录绝对路径)
ABSOLUTE-HOST-FILE(宿主机文件绝对路径)  (为空的情况下将挂载匿名数据卷)
Options:
rw 读写(默认值)
ro 只读

4.1.1 根据数据卷名称进行挂载

docker run -itd -v VOLUME_NAME:CONTAINER-DIR IMAGE [COMMAND] [ARG...]

示例:

将数据卷 my_vol 挂载到容器的/data/docker/volume/my_vol 目录

docker run -itd --name=vol1_ubuntu -v my_vol:/data/docker/volume/my_vol ubuntu /bin/bash

注:如果数据卷my_vol 存在将直接进行挂载,如果不存在 docker 将先自动创建数据卷再进行挂载。

4.1.2 根据宿主机文件目录绝对路径进行挂载

docker run -it -v ABSOLUTE-HOST-DIR:CONTAINER-DIR IMAGE [COMMAND] [ARG...]

示例:

将宿主机文件目录 /opt/common/docker/volumes/my_vol2 挂载到容器的/data/docker/volume/my_vol 目录

docker run -itd --name=vol2_ubuntu -v /opt/common/docker/volumes/my_vol2:/data/docker/volume/my_vol ubuntu /bin/bash

注:宿主机的文件目录必须为绝对路径。

4.1.3 根据宿主机文件绝对路径进行挂载

docker run -itd -v VOLUME_NAME:CONTAINER-DIR IMAGE [COMMAND] [ARG...]

示例:

将宿主机文件 ~/.bash_history 挂载到容器的/.bash_history

docker run -itd --name=vol3_ubuntu -v ~/.bash_history:/.bash_history ubuntu /bin/bash

4.1.4 挂载匿名卷

-v 参数如果不加任何宿主机相关卷信息docker将创建一个匿名卷进行挂载

docker run -itd -v CONTAINER-DIR IMAGE [COMMAND] [ARG...]

示例:

挂载匿名卷到容器的/data/docker/volume/my_vol 目录

docker run -itd --name=vol4_ubuntu -v /data/docker/volume/my_vol ubuntu /bin/bash

4.1.5 -v综合运行示例如下:

docker run -itd --name=vol_ubuntu \
-v my_vol:/data/docker/volume/my_vol1:ro \
-v /opt/common/docker/volumes/my_vol2:/data/docker/volume/my_vol2:rw \
-v /opt/common/docker/volumes/my_vol3.txt:/data/docker/volume/my_vol3.txt \
-v /data/docker/volume/my_vol4 \
ubuntu /bin/bash

4.2 --mount 使用详述

--mount:由多个用逗号分隔的<key>=<value>键值对组成,键的顺序随意。

命令格式:
--mount type=MOUNT-TYPE,<key>=<value>

对于--moun选项,目前Docker提供了三种不同类型的数据卷从宿主机挂载到容器中:volume,bind,tmpfs。

  三种方式的示意图如下所示:

4.2.1 named mount

  普通数据卷(默认即这种类型),Docker管理宿主机文件系统的一部分,默认位于 /var/lib/docker/volumes 目录中;

--mount type=volume,source=<VOLUME-NAME>,destination=<CONTAINER-PATH>,volume-driver=<DRIVER-NAME>,volume-opt=<OPTION>=<VALUE>,readonly

<key>=<value>说明:
source:数据卷源路径,关键字可以是 source 或 src,如果无此参数docker将自动创建匿名卷挂载
VOLUME-NAME:数据卷名称
destination:数据卷目标路径,关键字可以是 destination 或 dst 或 target
CONTAINER-PATH:数据卷在容器内的挂载路径
volume-driver:指定数据卷驱动程序,默认取 “local”
DRIVER-NAME:驱动名称
volume-opt:可选项,数据卷驱动程序传参选项
OPTION:key值
VALUE:value值
readonly:可选项,设置数据卷以只读权限挂载到容器内,默认为可读写

 代码示例:

docker service create --mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"' --name myservice <IMAGE> 

4.2.2bindmount

  绑定数据卷,文件或目录挂载,意为着可以存储在宿主机系统的任意位置;

--mount type=bind,source=<HOST-PATH>,destination=<CONTAINER-PATH>,bind-propagation=<PG-TYPE>,readonly

<key>=<value>说明:
source:数据卷源路径,关键字可以是 source 或 src,且执行挂在前确保文件或文件目录存在否则会执行出错
HOST-PATH:宿主机文件或目录的绝对路径
destination:数据卷目标路径,关键字可以是 destination 或 dst 或 target
CONTAINER-PATH:数据卷在容器内的挂载路径
bind-propagation:可选项,
PG-TYPE:可选值rprivate, private, rshared, shared, rslave, slave.
readonly:可选项,设置数据卷以只读权限挂载到容器内,默认为可读写即不加此参数

  *注意:Dockerfile 中不支持这种用法,这是因为 Dockerfile 是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。

 代码示例:

docker run -d -it --name devtest --mount type=bind,source="$(pwd)"/target,target=/app --mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave nginx:latest 

4.2.2 tmpfs mount

  临时数据卷,挂载存储在宿主机系统的内存中,而不会写入宿主机的文件系统;

--mount type=tmpfs,destination=<CONTAINER-PATH>,tmpfs-size=<SIZE-VALUE>,tmpfs-mode=<MODE-VALUE>,readonly

<key>=<value>说明:
destination:数据卷目标路径,关键字可以是 destination 或 dst 或 target
CONTAINER-PATH:数据卷在容器内的挂载路径
tmpfs-size:可选项,tmpfs装载的大小(以字节为单位),Linux中默认无限大。
SIZE-VALUE:数值
tmpfs-mode:可选项,tmpfs的八进制文件模式,Linux中的默认值是“1777”。
MODE-VALUE:数值

  注:这个功能只有在Linux上运行Docker时才可用。 

  代码示例:

docker run -d -it --name tmptest --mount type=tmpfs,destination=/app,tmpfs-size=1024,tmpfs-mode=1770 nginx:latest

4.3 -v 与 --mount的区别

  (1)--mount可以支持创建集群服务(services)的数据卷,而-v不行。

  (2)进行文件或目录的挂载,如果挂载前不存在 -v docker会自动创建,--mount 不会(会报错)。

4.4 补充说明

  (1)(--mount基本包含了--volume的可选属性内容)官方建议使用--mount的方式,原文如下:

     Even though there is no plan to deprecate--volume, usage of--mountis recommended.

  (2)官方文档链接:

    https://docs.docker.com/storage/volumes/

    https://docs.docker.com/engine/reference/commandline/service_create/

方式三、Docker数据卷容器

  数据卷容器也是一个容器,但是它的目的是专门提供数据卷给其他容器挂载,如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。

1. 数据卷容器的基本使用1.1 创建数据卷容器

  创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata目录:

docker run -it -v /dbdata --name db_data ubuntu

1.2 其他容器挂载

  其他容器中使用 --volumes-from 来挂载dbdata容器中的数据卷

docker run -it --volumes-from db_data --name db1 ubuntu
docker run -it --volumes-from db_data --name db2 ubuntu

  db1、db2通过db_data来共享了数据

2. 利用数据卷容器来备份、恢复、迁移数据卷

  可以利用数据卷对其中的数据进行进行备份、恢复和迁移。

2.1 备份

  首先使用 --volumes-from 标记来创建一个加载 dbdata 容器卷的容器,并从本地主机挂载当前到容器的 /backup 目录。命令如下:

sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

  容器启动后,使用了 tar 命令来将 dbdata 卷备份为本地的 /backup/backup.tar。

2.2 恢复

  如果要恢复数据到一个容器,首先创建一个带有数据卷的容器 dbdata2。

sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

  然后创建另一个容器,挂载 dbdata2 的容器,并使用 untar 解压备份文件到挂载的容器卷中。

sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar

声明:博文内容纯属个人理解,有异议请点评

到此这篇关于docker容器与宿主机的数据交互方式总结的文章就介绍到这了,更多相关docker容器与宿主机数据交互内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Docker容器访问宿主机网络的方法

    最近部署一套系统,使用nginx作反向代理,其中nginx是使用docker方式运行: $ docker run -d --name nginx $PWD:/etc/nginx -p 80:80 -p 443:443 nginx:1.15 需要代理的API服务运行在宿主机的 1234 端口, nginx.conf 相关配置如下: server { ... location /api { proxy_pass http://localhost:1234 } ... } 结果访问的时候发现老是报 5

  • 详解如何解决docker容器无法通过IP访问宿主机问题

    问题起源 在使用 docker 的过程中我不幸需要在 docker 容器中访问宿主机的 80 端口, 而这个 80 端口是另外一个容器 8080 端口映射出去的. 当我在容器里通过 docker 的网桥 172.17.0.1 访问宿主机时, 居然发现: curl: (7) Failed to connect to 172.17.0.1 port 80: No route to host 查找问题原因 可以确定的是容器与宿主机是有网络连接的, 因为可以在容器内部通过 172.17.0.1 Ping

  • docker容器与宿主机的数据交互方式总结

    前言 在生产环境中使用 Docker ,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作. 方式一.Docker cp命令 docker cp :用于容器与主机之间的数据拷贝. 语法 # 容器内文件 copy to 宿主机 docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- # 宿主机文件 copy to 容器内 docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_

  • 解决docker容器与宿主机相差8小时的问题

    使用docker-compose部署时,在输出的日志以及相关事件校验及输出时,导致事件与现实相差8小时. 排查问题: 1.查看宿主机时间: # 查看时间 date Wed Sep 29 11:12:44 CST 2021 # 查看时区 date -R Wed, 29 Sep 2021 11:13:34 +0800 2.进入容器查看时间 # 查看所有容器 docker ps -a # 进入容器 docker eec -it [容器ID] /bin/bash # 查看时间 date 此时看到的宿主机

  • Docker容器使用宿主机上的mongod/redis等服务详解

    我们在本地的开发中为了保证大家都开发环境一直,PHP 的扩展,版本保持一致, 我们使用了 docker .但是由于redis/mongodb 在宿主机上, 所以通过 127.0.0.1 是连接不上的 前提说明 这个是在 docker 运行容器时使用的桥接模式(默认) 时才会发生以上问题.如果使用 host 模式就没有. 所以,我们就是要把是 docker 的网络模式设置为 host 模式. 具体实现 ~ docker run --network host php56 补充说明 使用了 host

  • docker容器挂载宿主主机目录的操作方法

    有一项重要的参数 -v 目录挂载,就是让容器内部目录和宿主主机目录关联起来,这样就可以直接操作宿主主机目录而不用再操作具体容器了 比如在2中,我们要发布一个war包,是通过 sudo docker cp demo.war tomcat_xiao:/usr/local/tomcat/webapps 来发布的,有没有更快捷的方式呢? 肯定有, 没有 我就不会在这里写这些玩意儿了 sudo docker run -p 8822:8080 --name tomcat_xiao_volume -v /ho

  • docker 实现容器与宿主机无缝调用shell命令

    如下所示: nsenter -t 1 -m -u -n -i sh -c "echo hello world! " docker容器加上privilege权限, 设置pid: "host" 补充:在宿主机执行docker容器中的shell脚本或命令 常见命令形式: docker exec -it master /bin/bash -c 'echo $PATH' docker exec -it master /bin/bash -c 'cd /home/bigdata

  • 如何利用Docker容器实现代理转发与数据备份详解

    前言 我们将应用以Docker容器的方式部署到服务器上的时候,通常需要考虑两个方面的的问题:网络和存储. 网络方面,有些应用需要占用端口,而其中一部分应用甚至需要对外提供访问. 出于安全方面考虑,代理转发方式相对于直接开放防火墙端口方式更为合适. 存储方面,由于容器内部并不适合做数据持久化,所以一般通过挂载卷的方式将数据保存在服务器磁盘上. 但是服务器也不能保证绝对安全,所以数据也需要备份到云上. 代理转发 默认情况下容器之间的网络是互相隔离的,但是对于一些有关联的应用而言(web前端容器和服务

  • Docker 如何分配宿主机网段 IP

    工作需要临时启动一个 gitlab,无奈 gitlab 需要 ssh 的 22 端口;而使用传统网桥方式映射端口则 clone 等都需要输入端口号,很麻烦;22 端口宿主机又有 sshd 监听;研究了下 docker 网络,记录一下如何分配宿主机网段 IP 创建 macvlan 网络 关于 Docker 网络模式这里不再细说;由于默认的网桥方式无法满足需要,所以需要创建一个 macvlan 网络 复制代码 代码如下: docker network create -d macvlan  --sub

  • Docker容器和本机之间的文件传输方法

    主机和容器之间传输文件的话需要用到容器的ID全称. 获取方法如下: 1.先拿到容器的短ID或者指定的name. 2.然后根据这两项的任意一项拿到ID全称. 有了这个长长的ID的话,本机和容器之间的文件传输就简单了. docker cp 本地文件路径 ID全称:容器路径 进入容器之后就能够看到刚才上传进来的文件了. 如果是容器传输文件到本地的话,反过来就好了: docker cp ID全称:容器文件路径 本地路径 进行挂载的话可以参考这篇:利用Volume在主机和Docker容器文件传输. 以上就

  • docker内的容器如何与宿主机共享IP的方法

    目录 问题 原因 解决 问题 有个项目里面需要将一些服务打包到docker镜像中,打包完成后,发现有些服务有问题,主要集中在一些端侧设备接入用的服务,主要是工业相机.相机扫描不到. 原因 当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上.虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中.从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关.

随机推荐