18.1 Data Volume

Docker持久化数据方案

  • 基于本地文件系统的Volume

  可以在执行docker create或者docker run的时候,通过-v参数将主机的目录作为容器的数据卷。这部分功能便是基于本地文件系统的Volume管理。

  • 基于plugin的Volume

  支持第三方的存储方案,比如NAS、AWS等。

Data Volume 类型

  • 受管理的data volume,由docker后台自动创建
  • 绑定挂载的volume,具体挂载位置可以由用户指定

通过例子来查看

  以MySQL为例,可以查看官方的Dockerfile,当中用到了Volume。

# 查看volume
[root@docker ~]# docker volume ls
[root@docker ~]#
# 创建一个MySQL的容器
[root@docker ~]# docker run -d --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql # 查看MySQL容器跑起来之后的volume
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local e3c54bb7b620d86524b6cebc4c28568a2a81a104871a5baf41e22c02bd8d7bac
[root@docker ~]#
# 查看这个volume的想象信息
[root@docker ~]# docker volume inspect e3c54bb7b620d86524b6cebc4c28568a2a81a104871a5baf41e22c02bd8d7bac
[
{
"CreatedAt": "2018-06-07T09:13:24Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/e3c54bb7b620d86524b6cebc4c28568a2a81a104871a5baf41e22c02bd8d7bac/_data",
"Name": "e3c54bb7b620d86524b6cebc4c28568a2a81a104871a5baf41e22c02bd8d7bac",
"Options": null,
"Scope": "local"
}
]
[root@docker ~]#

  可以看到,这个volume并不在容器当中,而是挂载到了宿主机的/var/lib/docker/volumes/e3c54bb7b620d86524b6cebc4c28568a2a81a104871a5baf41e22c02bd8d7bac/_data目录下。

  再创建一个mysql2的容器:

[root@docker ~]# docker run -d --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql

[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local a3c730f24ca254cabbd328b4c5a6e7fa1822d7e1b2e54c9ac9104839295e5225
local e3c54bb7b620d86524b6cebc4c28568a2a81a104871a5baf41e22c02bd8d7bac
[root@docker ~]# docker volume inspect a3c730f24ca254cabbd328b4c5a6e7fa1822d7e1b2e54c9ac9104839295e5225
[
{
"CreatedAt": "2018-06-07T09:22:18Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/a3c730f24ca254cabbd328b4c5a6e7fa1822d7e1b2e54c9ac9104839295e5225/_data",
"Name": "a3c730f24ca254cabbd328b4c5a6e7fa1822d7e1b2e54c9ac9104839295e5225",
"Options": null,
"Scope": "local"
}
]
[root@docker ~]#

  删除这两个容器:

[root@docker ~]# docker stop mysql1 mysql2
[root@docker ~]# docker rm mysql1 mysql2
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local a3c730f24ca254cabbd328b4c5a6e7fa1822d7e1b2e54c9ac9104839295e5225
local e3c54bb7b620d86524b6cebc4c28568a2a81a104871a5baf41e22c02bd8d7bac
[root@docker ~]#

  可以发现,volume在容器删除之后也不会被删除,可以防止容器删除之后数据也不存在了的问题。但是volume的名字非常不友好,不方便我们使用,但是我们可以在创建或者启动容器的时候给volume设置别名来方便我们使用。

给volume起别名

  重新创建mysql1容器,在启动的时候给volume设置别名

[root@docker ~]# sudo docker run -d -v mysql:/var/lib/mysql --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local mysql
[root@docker ~]# docker volume inspect mysql
[
{
"CreatedAt": "2018-06-07T09:30:33Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql/_data",
"Name": "mysql",
"Options": null,
"Scope": "local"
}
]
[root@docker ~]#

  验证一下这个mysql的volume是否已经被使用:进入mysql1容器,创建一个数据库

[root@docker ~]# docker exec -it mysql1 /bin/bash
root@5aa496b309cc:/# mysql -uroot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.11 MySQL Community Server - GPL Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec) mysql> create database docker;
Query OK, 1 row affected (0.07 sec) mysql> show databases;
+--------------------+
| Database |
+--------------------+
| docker |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec) mysql> \q
Bye
root@5aa496b309cc:/# exit
[root@docker ~]# 停止mysql1容器,并删除mysql1容器
[root@docker ~]# docker stop mysql1
[root@docker ~]# docker rm mysql1
[root@docker ~]# 创建一个新的mysql2的容器,急需使用mysql这个volume
[root@docker ~]# sudo docker run -d -v mysql:/var/lib/mysql --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
[root@docker ~]# 进入mysql2查看是否存在之前的数据
[root@docker ~]# docker exec -it mysql2 /bin/bash
root@cf1cc3ad331e:/# mysql -uroot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.11 MySQL Community Server - GPL Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases;
+--------------------+
| Database |
+--------------------+
| docker |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec) mysql> \q
Bye
root@cf1cc3ad331e:/# exit

  可以发现,volume中的数据并不会因为容器的删除二消失,实现了数据持久化的目标。但是这种方式的volume需要在Dockerfile中使用VOLUME来预先指定容器中的数据存放路径。

18.2 Bind Mounting

  Bind Mounting跟上面的方式不一样,可以动态的指定容器内文件存放路径和宿主机上的数据库卷目录。

  构建一个docker-nginx的镜像:

# Dockerfile
[root@docker docker-nginx]# cat Dockerfile
# this same shows how we can extend/change an existing official image from Docker Hub FROM nginx:latest
# highly recommend you always pin versions for anything beyond dev/learn WORKDIR /usr/share/nginx/html
# change working directory to root of nginx webhost
# using WORKDIR is prefered to using 'RUN cd /some/path' COPY index.html index.html # I don't have to specify EXPOSE or CMD because they're in my FROM
[root@docker docker-nginx]# cat index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"> <title>hello</title> </head> <body>
<h1>Hello Docker! </h1>
</body>
</html>
[root@docker docker-nginx]# 构建镜像
[root@docker docker-nginx]# docker build -t staryjie/docker-nginx .
[root@docker docker-nginx]# 创建容器
[root@docker docker-nginx]# docker run -d -p 80:80 --name web staryjie/docker-nginx
[root@docker docker-nginx]# 本地访问
[root@docker docker-nginx]# curl 127.0.0.1
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"> <title>hello</title> </head> <body>
<h1>Hello Docker! </h1>
</body>
</html>
[root@docker docker-nginx]#

  但是index.html文件是无法更改的,如果要更改必须要重新构建镜像,这样非常不便。

[root@docker docker-nginx]# 强制删除web容器
[root@docker docker-nginx]# docker rm -f web
[root@docker docker-nginx]# 重新创建一个容器,指定宿主机上index.html的目录到容器中nginx的html目录
[root@docker docker-nginx]# docker exec -it web1 /bin/bash
root@18af473954f1:/usr/share/nginx/html# ls
Dockerfile index.html
root@18af473954f1:/usr/share/nginx/html# touch test.txt
root@18af473954f1:/usr/share/nginx/html# exit
[root@docker docker-nginx]# ls
Dockerfile index.html test.txt
[root@docker docker-nginx]# curl 127.0.0.1
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"> <title>hello</title> </head> <body>
<h1>Hello Docker! </h1>
</body>
</html>
[root@docker docker-nginx]# 修改index.html
[root@docker docker-nginx]# cat index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"> <title>hello</title> </head> <body>
<h1>Hello Docker! </h1>
<h1>Hello, I have changed this file! </h1>
</body>
</html>
[root@docker docker-nginx]# curl 127.0.0.1
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"> <title>hello</title> </head> <body>
<h1>Hello Docker! </h1>
<h1>Hello, I have changed this file! </h1>
</body>
</html>
[root@docker docker-nginx]#

  采用Bind Mounting的方式实现volume的话,容器内外的数据是同步的,只需要修改一个地方,容器内或者容器外都会同步修改,非常的方便快捷。

  采用Bind Mounting的方式,将docker作为开发环境可以使我们的开发环境和生产环境保持一致,这也是实现DevOps的第一步。(很多开发使用的都是Windows的系统,但是服务器一般都是Linux的,无法保持环境的一致性,影响开发效率。)

  利用docker搭建一个与生产环境统一的开发环境

18、docker的持久化存储和数据共享的更多相关文章

  1. s5 Docker的持久化存储和数据共享

    数据库容器的数据如何才能不会丢失?Docker的持久化存储技术.Docker的数据共享技术能极大提高开发人员的开发效率,边写代码,边看运行结果. 数据持久化之Data Volume Docker持久化 ...

  2. Docker持久化存储与数据共享

    一.Docker持久化数据的方案 基于本地文件系统的Volume:可以在执行docker create或docker run时,通过-v参数将主机的目录作为容器的数据卷.这部分功能便是基于本地文件系统 ...

  3. 20.docker 持久化存储与数据共享

    1.image layer 和 container layer 的关系 image layer 是可读的 container layer 是在image layer 之上创建的 一个可读可写层 con ...

  4. docker volume持久化存储与数据分享

    第一种 指定volume文件mysql存储,存储的位置为/var/lib/mysql -v mysql:/var/lib/mysql 第二种 同步文件,将容器中的skeleton文件夹的内容同步到宿主 ...

  5. 五十四.自定义镜像及仓库、持久化存储 、 Docker网络架构

    1. 制作自定义镜像(base基础镜像,搭建共性环境) 基于centos镜像使用commit创建新的镜像文件 基于centos镜像使用Dockerfile文件创建一个新的镜像文件   1.1 使用镜像 ...

  6. docker容器的持久化存储:Volume

    独立于docker容器的持久化存储: 法(1):自动将服务器文件夹挂载到容器内部文件夹/usr/share/nginx/html,这样只修改服务器文件夹下的内容即可对应修改容器内部文件夹的内容 将服务 ...

  7. Centos7——docker持久化存储和卷间状态共享(笔记)

    docker持久化存储和卷间状态共享(笔记)  本章介绍 存储卷的介绍 存储卷的两种类型 宿主机好额容器之间如何共享数据 容器之间如何共享数据 存储卷的声明周期 存储卷之间的数据管理和控制模式 就像在 ...

  8. docker容器持久化卷讲解

    docker容器自身存储数据效率比较低,因此我们为了提高磁盘IO的性能等,需要在容器中挂载一个外部存储设备.关于讲解大致如下: Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中 ...

  9. Docker的OverlayFS存储驱动

    OverlayFS存储驱动 OverlayFS是一个现代的Union Filesystem,类似于AUFS,但速度更快,实现更简单.Docker为OverlayFS提供了两个存储驱动程序:overla ...

随机推荐

  1. 发布MVC项目到服务器上时候遇到的 模块 DirectoryListingModule 通知 ExecuteRequestHandler 处理程序 StaticFile 错误代码 0x00000000

    应用程序“HMW121197”中的服务器错误错误摘要HTTP 错误 403.14 - ForbiddenWeb 服务器被配置为不列出此目录的内容. 详细错误信息模块 DirectoryListingM ...

  2. C# 窗口页面卡的处理方案-异步编程委托

    今天用winform做了一个小程序,主要是用于远程数据的登录采集,因为数据量非常大,到时每次点击按钮执行程序的时候界面都会出现假死状态,具体表现是无法拖动窗口,无法最小化或关闭等,只能任务管理进程结束 ...

  3. Linux网络通信

    使用TCP协议的socket 1.网络字节序 由于在主机存储为小端序,网络传输为大端序,并且在网络中需要读取IP号和端口号,所以发送端要将小端序转为大端序,接收端将大端序转为小端序 #include ...

  4. SpringBoot yml properties文件

    一.在SpringBoot实现属性注入: 1).添加pom依赖jar包: 1 <!-- 支持 @ConfigurationProperties 注解 --> 2 <!-- https ...

  5. Process ProcessThread Thread

    Process ProcessThread: Process and ProcessThread objects have a ProcessorAffinity property of IntPtr ...

  6. 解决selenium不支持firefox低版本的问题

    解决selenium不支持firefox低版本的问题 在火狐浏览器升级后,突然发现webdriver运行脚本的时候不能调出火狐浏览器了,并报错WebDriverException:Message:'C ...

  7. unity3d-ngui UIScrollView 滚动方向与滚轮相反

    生成一个滚动面板之后发现滚轮向上滚,界面向下:滚轮向下界面向上.在编辑窗口里发现这个选项 本来是-2,修改成正数就可以了. http://ju.outofmemory.cn/entry/146754

  8. cmake 总结

    cmake中一些预定义变量 PROJECT_SOURCE_DIR 工程的根目录 PROJECT_BINARY_DIR 运行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/bui ...

  9. php多进程 防止出现僵尸进程

    对于用PHP进行多进程并发编程,不可避免要遇到僵尸进程的问题. 僵尸进程是指的父进程已经退出,而该进程dead之后没有进程接受,就成为僵尸进程(zombie)进程.任何进程在退出前(使用exit退出) ...

  10. (转载)我的java问题排查工具单

    原文地址:https://yq.aliyun.com/articles/69520 我的问题排查工具箱 前言 平时的工作中经常碰到很多疑难问题的处理,在解决问题的同时,有一些工具起到了相当大的作用,在 ...