docker容器互联,实现目录、服务共享
一、需求
docker使服务之间实现容器隔离,比如Javaweb项目前端、后端、数据库、数据库后台,分别把它们部署在不同的容器里面,实现隔离。但服务和服务之间也有互访的需求,这就涉及到容器网络和容器互联挂载访问机制的内容。
容器是基于镜像创建的,最后的容器文件系统包括镜像的只读层+可写层,容器中的进程操作的数据持久化都是保存在容器的可写层上。一旦容器删除后,这些数据就没了,除非我们人工备份下来(或者基于容器创建新的镜像)。能否可以让容器进程持久化的数据保存在主机上呢?这样即使容器删除了,数据还在。
docker本身提供了一种机制,可以将主机上的某个目录与容器的某个目录(称为挂载点、或者叫卷)关联起来,容器上的挂载点下的内容就是主机的这个目录下的内容,这类似linux系统下mount的机制。 这样的话,我们修改主机上该目录的内容时,不需要同步容器,对容器来说是立即生效的。挂载点可以让多个容器共享。
二、通过docker run命令
1、运行命令:
# docker run --name node1 -h nodex -v /home/upload/:/data -d -i -t centos /bin/bash
其中的 -v 标记 在容器中设置了一个挂载点 /data(就是容器中的一个目录),并将主机上的 /home/upload/ 目录中的内容关联到 /data下。
这样在容器中对/data目录下的操作,还是在主机上对/home/upload/的操作,都是完全实时同步的,因为这两个目录实际都是指向主机目录。
通过docker inspect 命令查看目录对应关系
# docker inspect node1
[
{
"Id": "d1c5d9eb3838c724b597db428ce26e72cfc667fbefb0ed712dbbaef5f374070f",
.............................
"Mounts": [
{
"Type": "bind",
"Source": "/home/upload",
"Destination": "/data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
...........................
2、运行命令:
# docker run --name node2 -h nodex -v /data -d -i -t centos /bin/bash
上面-v的标记只设置了容器的挂载点,并没有指定关联的主机目录。这时docker会自动绑定主机上的一个目录。通过docker inspect 命令可以查看到。
# docker inspect node2
[
{
"Id": "d1c5d9eb3838c724b597db428ce26e72cfc667fbefb0ed712dbbaef5f374070f",
.............................
"Mounts": [
{
"Type": "volume",
"Name": "d04353ed38845a54a2bd5909b82c470fe644391626f877644e9580aba22a3a12",
"Source": "/var/lib/docker/volumes/d04353ed38845a54a2bd5909b82c470fe644391626f877644e9580aba22a3a12/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
...........................
上面 Mounts下的每条信息记录了容器上一个挂载点的信息,"Destination" 值是容器的挂载点,"Source"值是对应的主机目录。
可以看出这种方式对应的主机目录是自动创建的,其目的不是让在主机上修改,而是让多个容器共享。
三、通过dockerfile创建挂载点
上面介绍的通过docker run命令的-v标识创建的挂载点只能对创建的容器有效。
通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点。
还有一个区别是,通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。
# cat Dockerfile
下面的dockfile文件通过VOLUME指令指定了两个挂载点 /data1 和 /data2
#test
FROM centos
MAINTAINER djl
VOLUME ["/data1","/data2"]
# docker build -t test .
[root@localhost ~]# docker build -t test .
Sending build context to Docker daemon 28.77 MB
Step / : FROM centos
---> 9f38484d220f
Step / : MAINTAINER djl
---> Running in d14672dadf87
---> 602a4b8e796d
Removing intermediate container d14672dadf87
Step / : VOLUME /data1 /data2
---> Running in 30b586d5aaf4
---> f51b774e7869
Removing intermediate container 30b586d5aaf4
Successfully built f51b774e7869
查看构建的镜像
# docker images
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test latest f51b774e7869 minutes ago MB
centos latest 9f38484d220f months ago MB
运行一个容器
# docker run --name node3 -h nodex -d -i -t test /bin/bash
[root@localhost ~]# docker run --name node3 -h nodex -d -i -t test /bin/bash
6fb05f94a368e05dd96e2f42432f1e4c0dcad1bd6b726079c69fba0625783c38
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6fb05f94a368 test "/bin/bash" seconds ago Up seconds node3
f2bf65a82acc centos "/bin/bash" About an hour ago Up About an hour node1
d1c5d9eb3838 centos "/bin/bash" hours ago Up hours node2
我们通过docker inspect 查看通过该dockerfile创建的镜像生成的容器,可以看到如下信息
# docker inspect node3
[
{
"Id": "d1c5d9eb3838c724b597db428ce26e72cfc667fbefb0ed712dbbaef5f374070f",
.............................
"Mounts": [
{
"Type": "volume",
"Name": "cc2fcaccae2dca5021d82d4d581e1f500816a96745237527d4fa7925a2061e04",
"Source": "/var/lib/docker/volumes/cc2fcaccae2dca5021d82d4d581e1f500816a96745237527d4fa7925a2061e04/_data",
"Destination": "/data1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "2f7419b960ae0a3f7be58875f5021312b181fdad72e2c7390b2bb7aab7d06b24",
"Source": "/var/lib/docker/volumes/2f7419b960ae0a3f7be58875f5021312b181fdad72e2c7390b2bb7aab7d06b24/_data",
"Destination": "/data2",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
...........................
可以看到两个挂载点的信息。
四、容器共享卷(挂载点)
下面我们创建另一个容器可以和node3共享 /data1 和 /data2卷 ,这是在 docker run中使用 --volumes-from标记,如:
1、可以是来源不同镜像,如:
# docker run --name node4 -itd --volumes-from node3 centos /bin/bash
[root@localhost ~]# docker run --name node4 -itd --volumes-from node3 centos /bin/bash
ced022f71608c81fd2d689861809b033996351e4dc23c210eaeda675ff28a31b
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ced022f71608 centos "/bin/bash" seconds ago Up seconds node4
6fb05f94a368 test "/bin/bash" minutes ago Up minutes node3
f2bf65a82acc centos "/bin/bash" hours ago Up hours node1
d1c5d9eb3838 centos "/bin/bash" hours ago Up hours node2
验证:
[root@localhost ~]# docker exec node3 ls /
anaconda-post.log
bin
data1
data2
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
[root@localhost ~]# docker exec node4 ls /
anaconda-post.log
bin
data1
data2
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
2、也可以是同一镜像,如:
# docker run --name node5 -itd --volumes-from node3 test /bin/bash
[root@localhost ~]# docker run --name node5 -itd --volumes-from node3 test /bin/bash
e6a2584eab2cce5b678f432d8eb48a762e5b1b2d57bcd76ee48f121c51ff282d
[root@localhost ~]#
[root@localhost ~]# docker exec node5 ls /
anaconda-post.log
bin
data1
data2
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
五、最佳实践:数据容器
如果多个容器需要共享数据(如持久化数据库、配置文件或者数据文件等),可以考虑创建一个特定的数据容器,该容器有1个或多个卷。
其它容器通过--volumes-from 来共享这个数据容器的卷。
因为容器的卷本质上对应主机上的目录,所以这个数据容器也不需要启动。
# docker run --name dbdata test echo "data container"
[root@localhost ~]# docker run --name dbdata test echo "data container"
data container
[root@localhost ~]#
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac04a4f5d1ab test "echo 'data contai..." seconds ago Exited () seconds ago dbdata
e6a2584eab2c test "/bin/bash" minutes ago Up minutes node5
ced022f71608 centos "/bin/bash" minutes ago Up minutes node4
6fb05f94a368 test "/bin/bash" minutes ago Up minutes node3
f2bf65a82acc centos "/bin/bash" hours ago Up hours node1
d1c5d9eb3838 centos "/bin/bash" hours ago Up hours node2
[root@localhost ~]# docker start dbdata
dbdata
[root@localhost ~]#
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac04a4f5d1ab test "echo 'data contai..." seconds ago Exited () seconds ago dbdata
e6a2584eab2c test "/bin/bash" minutes ago Up minutes node5
ced022f71608 centos "/bin/bash" minutes ago Up minutes node4
6fb05f94a368 test "/bin/bash" minutes ago Up minutes node3
f2bf65a82acc centos "/bin/bash" hours ago Up hours node1
d1c5d9eb3838 centos "/bin/bash" hours ago Up hours node2
说明:有个卷,容器之间的数据共享比较方便,但也有很多问题需要解决,如权限控制、数据的备份、卷的删除等。
参考博客:
docker学习笔记18:Dockerfile 指令 VOLUME 介绍
docker容器互联,实现目录、服务共享的更多相关文章
- Docker容器安装配置SQLServer服务(Linux)
一:前言 随着不断的对Docker容器的实践和学习,越来越觉得容器的强大,把 SQL Server 数据库服务放在docker容器中,比你自己在宿主服务器上面安装配置一个SQL Server服务器是要 ...
- 【Docker学习之六】Docker容器互联
环境 docker-ce-19.03.1-3.el7.x86_64 centos 7 一.基于Volume的互联就是-v参数,将本机文件或目录挂载到容器目录,实现文件目录共享 二.基于Link的互联 ...
- Docker系列(四):Docker容器互联
基于Volume的互联 为什么需要Volume docker文件系统是分层的,下面的是全部是只读的,最上面的是可写层,容器中的进程如果修改了某个文件,比如修改了下层的某个文件,其实是在最顶层复制下层文 ...
- Docker容器挂载宿主目录的情形分析
Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定. 譬如我要启动一个centos容器,宿主机的/test目录挂载到容器的/soft目录,可通过以下方式指定: # docker ...
- 使用weave实现跨主机docker容器互联
关于weave的原理不做细致的说明,如果想了解weave可以登陆官网:https://www.weave.works/ In this post,使用阿里云3台ECS服务器进行weave搭建,并测试搭 ...
- Docker - 容器互联
容器互联 通过docker run命令的--link参数可以让容器之间通过连接(linking)系统进行交互. 参数格式:--link name:alias ,name是要链接的容器名称, alias ...
- centos:解决docker容器内挂载目录无权限 ls: cannot open directory .: Permission denied
docker运行一个容器后,将主机中当前目录下的文件夹挂载到容器的文件夹后 进入到docker容器内对应的挂载目录中,运行命令ls后提示: ls: cannot open directory .: P ...
- Docker | 容器互联互通
上篇讲到创建自定义网络,我创建了 mynet 网络,并指定了网关和子网地址.在上篇结尾呢,我抛出了一个问题:其它网络下的容器可以直接访问mynet网络下的容器吗?今天就让我们一块看下怎么实现容器互联. ...
- docker容器互联
link方式 http://blog.csdn.net/halcyonbaby/article/details/42112325 通过link方式创建容器,然后我们可以使用被link容器的别名进行访问 ...
随机推荐
- Java入门 - 高级教程 - 09.文档注释
原文地址:http://www.work100.net/training/java-documentation.html 更多教程:光束云 - 免费课程 文档注释 序号 文内章节 视频 1 概述 2 ...
- python接口测试,mock模块基本使用介绍
mock简介 py3已将mock集成到unittest库中 为的就是更好的进行单元测试 简单理解,模拟接口返回参数 通俗易懂,直接修改接口返回参数的值 mock作用 解决依赖问题,达到解耦作用 当我们 ...
- java小心机(3)| 浅析finalize()
每天进步一丢丢,连接梦与想 如果你停止就是谷底,如果你还在努力就是上坡 系列文章 java"小心机"(1)[资源彩蛋!] java小心机(2)| 重载和构造器的小细节 预备知识 J ...
- 编写python程序读入1到100之间的整数,然后计算每个数出现的次数,输入0表示结束输人,输入数据不包括0。如果数出现的大现如果大于1,输出时使用复数times
#-*- coding:UTF-8 -*- #环境:python3 print("Enter the numbers between 1 and 100:") enterList= ...
- Java基础系列2:深入理解String类
Java基础系列2:深入理解String类 String是Java中最为常用的数据类型之一,也是面试中比较常被问到的基础知识点,本篇就聊聊Java中的String.主要包括如下的五个内容: Strin ...
- 贪心+huffman编码+模拟退火+分治(一)
(一)贪心 1.A - 今年暑假不AC “今年暑假不AC?” “是的.” “那你干什么呢?” “看世界杯呀,笨蛋!” “@#$%^&*%...” 确实如此,世界杯来了,球迷的节日也来了,估计很 ...
- Python+Flask+MysqL的web技术建站过程
1.个人学期总结 时间过得飞快,转眼间2017年就要过去.这一年,我学习JSP和Python,哪一门都像一样新的东西,之前从来没有学习过. 这里我就用我学习过的Python和大家分享一下,我是怎么从一 ...
- PlayCanvas PBR材质shader代码分析(vertex shader)
顶点shader主要对顶点坐标变换,将顶点坐标从local->world->view->clip 空间变换 local空间:模型物体坐标系 world空间:世界空间坐标系 view空 ...
- CSS-05-伪类及伪元素选择器
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Java程序员学习Go指南(终)
我的博客:https://www.luozhiyun.com/archives/215 context.Context类型 Context类型可以提供一类代表上下文的值.此类值是并发安全的,也就是说它 ...