Docker入门到实践 (四) docker容器数据卷与数据卷容器


一、前言

  在上一篇文章中已经介绍了Dockerfile解析与镜像制作, 下面正式进入到docker容器数据卷与数据卷容器。



二、容器数据卷

1、什么是容器数据卷

  docker的理念将运行的环境打包形成容器运行,运行可以伴随容器,但是我们对数据的要求是希望持久化,容器之间可以共享数据,Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据作为容器的一部分保存下来,那么当容器被删除之后,数据也就没了,为了能够保存数据,在docker容器中使用卷。卷就是文件或者目录,存在于一个或者多个容器中,但是不属于联合文件系统,因此能够绕过Union File System提供一些用于持久化数据或共享数据的特点。

2、容器数据卷的作用与特性

  容器数据卷是一个特殊的文件或者目录,它将主机文件或者目录直接映射进容器中,可供一个或多个容器使用。容器数据卷设计的目的就是为了 数据的持久化,它完全独立与容器的生命周期。因此,容器删除时,不会删除其挂载的数据卷,也不会存在类似的垃圾机制对容器存在的数据卷进行处理。

容器数据卷的特性:

  • 数据卷可以在容器之间进行数据共享和重用
  • 对数据卷里的内容做更改不会影响镜像的更新
  • 对数据卷里的内容做修改,能直接生效,无论是在容器内操作还是本地操作
  • 数据卷的生命周期一直持续到没有容器使用它为止,即使挂载数据卷的容器已经被删除。
  • 数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会拷贝到新初始化的数据卷中

3、容器数据卷的添加

方式一:通过命令添加数据卷
匿名目录挂载

匿名目录挂载只需要写容器内目录或者文件即可,而宿主机对应的目录会在/var/lib/docker/volumes路径下生成

//以交互模式运行容器,并使用-v 匿名挂载容器数据卷
docker run -it -v 容器内目录/文件的绝对路径[:rw/ro] -p 主机端口:容器端口 --name=容器名称 镜像ID/镜像名称[:版本号]

//以后台方式运行容器,并使用-v 匿名挂载容器数据卷 (推荐)
docker run -d -v 容器内目录/文件的绝对路径[:rw/ro] -p 主机端口:容器端口 --name=容器名称 镜像ID/镜像名称[:版本号]

//注意:如果出现Docker挂载宿主机目录显示cannot open directory .:Permission denied
解决办法:在挂载目录后面 多加一个--privileged=true参数即可

案例:使用centos容器内的 根目录 (/) 下的centosVolume目录 匿名挂载到宿主机中

1、创建并运行centos容器,同时匿名挂载数据卷

//这里没有使用--name=容器名称 去指定容器名称,则docker随机一个容器名称
docker run -it -v /centosVolume centos



2、查看数据卷是否挂载成功

docker inspect 81b687fb8e88 (容器ID)


可以看到,centos容器内的/centosVolume数据卷挂载到宿主机/var/lib/docker/volumes路径下的/0a4ea838c43ccc9af377af6d2e641b2c9fd4977c4a56408d76d31c8719b9dd8f/_data目录了


具名目录挂载

具名目录挂载相对于匿名目录挂载,就是在宿主机生成对应的目录时可以指定该目录的名称,同样目录也会在/var/lib/docker/volumes路径下生成。例如:匿名目录挂载生成的对应宿主机目录为0a4ea838c43ccc9af377af6d2e641b2c9fd4977c4a56408d76d31c8719b9dd8f一串随机的数字,而具名目录挂载就是可以将这一串随机的数字改成指定的目录名称

//以交互模式运行容器,并使用-v 具名挂载容器数据卷
docker run -it -v 目录名称:容器内目录/文件的绝对路径[:rw/ro] -p 主机端口:容器端口 --name=容器名称 镜像ID/镜像名称[:版本号]

//以后台方式运行容器,并使用-v 具名挂载容器数据卷 (推荐)
docker run -d -v 目录名称:容器内目录/文件的绝对路径[:rw/ro] -p 主机端口:容器端口 --name=容器名称 镜像ID/镜像名称[:版本号]

//注意:如果出现Docker挂载宿主机目录显示cannot open directory .:Permission denied
解决办法:在挂载目录后面 多加一个--privileged=true参数即可

案例:使用centos容器内的 根目录 (/) 下的centosVolume目录 匿名挂载到宿主机中

1、创建并运行centos容器,同时匿名挂载数据卷

//这里没有使用--name=容器名称 去指定容器名称,则docker随机一个容器名称
docker run -it -v hostVolume:/myVolume centos



2、查看数据卷是否挂载成功

docker inspect 8961c0a39ce8 (容器ID)


可以看到,centos容器内的/myVolume数据卷挂载到 宿主机的/var/lib/docker/volumes/hostVolume/_data目录了,这时的宿主机目录名称不在是一串随机的数字了,而是我们指定的目录名称hostVolume


指定目录挂载

指定目录挂载就是我们可以将容器内部的数据卷指定挂载到宿主机的某一文件或者目录下

//以交互模式运行容器,并使用-v 挂载容器数据卷
docker run -it -v 宿主机目录/文件的绝对路径:容器内目录/文件的绝对路径[:rw/ro] -p 主机端口:容器端口 --name=容器名称 镜像ID/镜像名称[:版本号]

//以后台方式运行容器,并使用-v 挂载容器数据卷 (推荐)
docker run -d -v 宿主机目录/文件的绝对路径:容器内目录/文件的绝对路径[:rw/ro] -p 主机端口:容器端口 --name=容器名称 镜像ID/镜像名称[:版本号]

//注意:如果出现Docker挂载宿主机目录显示cannot open directory .:Permission denied
解决办法:在挂载目录后面 多加一个--privileged=true参数即可

案例:在Host宿主机的 /root目录下使用hostVolume目录 挂载数据卷到 centos容器内的 根目录 (/) 下的containerVolume目录

1、创建并运行centos容器,同时挂载数据卷

//这里没有使用--name=容器名称 去指定容器名称,则docker随机一个容器名称
docker run -it -v /root/hostVolume:/containerVolume centos


可以看到,此时由 root@localhost 转变成为 root@13243e227243 (容器ID),表示我们已经由宿主机进入到centos容器中。

2、查看数据卷是否挂载成功
左边为centos容器,右边为宿主机
可以看到centos容器根目录下多了一个containerVolume目录,宿主机/root目录下多了一个hostVolume目录

同时还可以在宿主机中使用指令docker inspect 容器ID/容器名称来查看是否挂载成功


3、容器与宿主机之间进行通信
左边为centos容器,右边为宿主机

4、关闭容器后,更改宿主机hostVolume目录中的 host.txt文件,容器再次启动后数据仍然同步
左边为centos容器,右边为宿主机

方式二:通过DockerFile添加数据卷

案例:在Host宿主机的 /root目录下创建一个DockerFile文件 (名称随意),并通过docker build指令生成镜像来添加数据卷

1、在Host宿主机的 /root目录下创建一个DockerFile文件,并添加如下内容到文件中

#基于centos镜像进行构建
FROM centos

#数据卷只能指定容器数据卷,不能指定宿主机数据卷,因为并不能够保证在所有的宿主机上都存在这样的特定目录。
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]

#以 /bin/bash方式启动
CMD /bin/bash

2、使用如下指令,把编写的DockerFile文件执行生成镜像,注意:命令最后面是空格 + .

docker build -f 宿主机中DockerFile文件的绝对路径 -t 新镜像名称[:版本号] .



3、运行我们生成的new-centos镜像,就能够查看到在容器内中生成的数据卷


4、那么容器内的数据卷文件/目录地址已经知道,对应的宿主机文件/目录的地址怎么查看?通过如下指令

docker inspect 容器ID/容器名称





三、数据卷容器

1、什么是数据卷容器

  命名的容器已挂载数据卷,其他的容器通过挂载这个容器(父容器)实现数据共享,挂载数据卷的容器,称为数据卷容器。通过数据卷容器可以实现容器间的数据共享。

2、添加数据卷容器

docker run -it/-d  -p 主机端口:容器端口 --name=容器名称 --volumes-from 数据卷容器ID/数据卷容器名称 生成数据卷容器的镜像ID/镜像名称[:版本号]

案例:创建父容器,并在父容器的数据卷中添加数据,以挂载父容器生成子容器,实现数据共享

1、启动父容器,并在父容器的 dataVolumeContainer1目录下新增内容


2、基于父容器生成子容器son-centos,注意是在宿主机中使用如下指令

docker run -it --name=son-centos --volumes-from father-centos new-centos



3、子容器添加数据,父容器查看数据


4、删除父容器,子容器数据依然保留




Docker入门到实践系列文章列表:

Docker入门到实践 (一) docker简介与安装
Docker入门到实践 (二) docker常用命令讲解
Docker入门到实践 (三) Dockerfile解析与镜像制作
Docker入门到实践 (四) docker容器数据卷与数据卷容器
Docker入门到实践 (五) docker数据的备份、恢复与迁移
Docker入门到实践 (六) docker网络模式详解以及容器间的网络通信
Docker入门到实践 (七) docker常用软件的安装
Docker入门到实践 (八) 本地镜像推送到阿里云 和 下载镜像到本地
Docker入门到实践 (九) docker可视化界面portainer的安装与使用
Docker入门到实践 (十) IDEA集成Docker构建容器镜像,部署项目
Docker入门到实践 (十一) docker私有仓库的搭建与配置
Docker入门到实践 (十二) docker compose简介与安装
Docker入门到实践 (十三) docker compose配置文件与常用命令讲解
Docker入门到实践 (十四) docker企业级容器镜像仓库HarBor的搭建与配置




  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
docker-compose 搭建的lamp+redis 代码 附上docker-compose # 标准配置文件应该包含 version、services、networks 三大部分, # 其中最关键的就是 services 和 networks 两个部分,下面先来看 services 的书写规则 # 指定版本号 version: '2' services: # 在 services 标签下的第二级标签是 console,这个名字是用户自己自定义,它就是服务名称。 console: # 为自定义的容器指定一个名称,而不是使用默认的名称 container_name: console # 容器内置名称 hostname: console # 指明路径 build: # context 指定绝对路径或者相对路径 context: ./images/console # dockerfile 指定 Dockerfile 的文件名称 dockerfile: Dockerfile # volumes_from 从其它容器或者服务挂载数据, # 可选的参数是 :ro 或 :rw,前者表示容器只读,后者表示容器数据是可读可写的(默认情况为可读可写的)。 volumes_from: - php # 挂载一个目录或者一个已存在的数据容器,可以直接使用 HOST:CONTAINER 这样的格式 # ,或者使用 HOST:CONTAINER:ro 这样的格式,后者对于容器来说,数据是只读的,这样可以有效保护宿主机的文件系统 volumes: # 使用绝对路径挂载数据 - /root/.ssh/:/root/.ssh/ # 类似于使用 docker run 的效果 我也不知道 不写因为console并不是直接启动导致镜像不会产生 tty: true # web,这个名字是用户自己自定义,它就是服务名称。 web: # 为自定义的容器指定一个名称,而不是使用默认的名称 container_name: web # 容器内置名称 hostname: web # 指明路径 build: # context 指定绝对路径或者相对路径 context: ./images/nginx # dockerfile 指定 Dockerfile 的文件名称 dockerfile: Dockerfile # 映射端口 ports: - '80:80' # 此选项解决了启动顺序的问题 这个的意思是必须在php启动以后才能启动 # 注意的是,默认情况下使用 docker-compose up web 这样的方式启动 web 服务时, # 也会启动 php 服务,因为在配置文件中定义了依赖关系 depends_on: - php # volumes_from 从其它容器或者服务挂载数据, volumes_from: - php volumes: # 已经存在的命名的数据 - nginx-log:/var/log/nginx # 以 Compose 配置文件为中心的相对路径作为数据挂载到容器 - ./images/nginx/sites-enabled:/etc/nginx/sites-enabled - ./images/nginx/cert:/etc/nginx/cert # 加入指定网络 networks: default: # 同一网络上的其他容器可以使用服务器名称或别名来连接到其他服务的容器 aliases: - web.sunchanghao.top - mid.sunchanghao.top - sevice.sunchanghao.top - admin.sunchanghao.top # php,这个名字是用户自己自定义,它就是服务名称。 php: # 为自定义的容器指定一个名称,而不是使用默认的名称 container_name: php # 容器内置名称 hostname: php # 服务除了可以基于指定的镜像,还可以基于一份 Dockerfile, # 在使用 up 启动之时执行构建任务,这个构建标签就是 build,它可以指定 Dockerfile # 所在文件夹的路径。Compose 将会利用它自动构建这个镜像,然后使用这个镜像启动服务容器 build: # context 选项可以是 Dockerfile 的文件路径,也可以是到链接到 git 仓库的 url # 当提供的值是相对路径时,它被解析为相对于撰写文件的路径,此目录也是发送到 Docker 守护进程的 context context: ./images/php # 使用此 dockerfile 文件来构建,必须指定构建路径 dockerfile: Dockerfile # 挂载一个目录或者一个已存在的数据容器, volumes: # 以 Compose 配置文件为中心的相对路径作为数据挂载到容器。 - ./app:/mnt/app # db,这个名字是用户自己自定义,它就是服务名称。 db: # 为自定义的容器指定一个名称,而不是使用默认的名称 container_name: db # 容器内置名称 hostname: db # 从指定的镜像中启动容器,可以是存储仓库、标签以及镜像 ID image: mysql:5.7 environment: MYSQL_USER: 'sch' MYSQL_PASS: '1111' MYSQL_ROOT_PASSWORD: 'root' volumes: - db:/var/lib/mysql ports: - '3306:3306' redis: # 为自定义的容器指定一个名称,而不是使用默认的名称 container_name: redis # 容器内置名称 hostname: redis # image 则是指定服务的镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。 image: redis:3.2.7 # 设置端口号 ports: - '6379:6379' # 挂载一个目录或者一个已存在的数据容器 volumes: # 已经存在的命名的数据。 - redis:/data # node volumes: nginx-log: # 设置volume的驱动,默认是local. driver: local db: driver: local redis: driver: local

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值