Docker同一个宿主机不同容器之间通信问题
一、为什么要书写此文档?因为Docker容器思想一个容器只做一件事,所以JavaWeb整体会在一个容器中,数据库(Mysql,redis,Hbase)会单独存在另一个容器中,势必会造成容器之间的通信,由于Docker容器之间采用沙箱隔离运行机制,所以在不同容器之间数据通信就成了一个大问题!二、如何解决容器之间数据通信问题?(link第一种方式)有两种方案,第一种搭建容器的桥接网络(...
一、为什么要书写此文档?
因为Docker容器思想一个容器只做一件事,所以JavaWeb整体会在一个容器中,数据库(Mysql,redis,Hbase)会单独存在另一个容器中,势必会造成容器之间的通信,由于Docker容器之间采用沙箱隔离运行机制,所以在不同容器之间数据通信就成了一个大问题!
二、如何解决容器之间数据通信问题?(link第一种方式)
有两种方案,第一种搭建容器的桥接网络(详情见docker容器桥接网络设置文档.doc,相对麻烦),第二种使用Docker容器之间的Link机制
此处解决方案使用第二种方式:使用Docker容器的link通信机制,解决同一宿主机容器之间通信问题;
三、以一个简单的JavaWeb项目为例(写一个简单的数据库查询所有),数据库使用MySql容器,宿主机上启动两个镜像,一个MySql,一个JavaWeb,两个镜像分别启动了2个容器!
查看运行的容器
启动两个容器的先后顺序为数据库为先启动,调用数据库的服务为后启动
启用Mysql 的Shell脚本如下:
docker run --name mysql -p 3306:3306 -v /mysql/database/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
Shell脚本说明
①: run Docker的运行命令
②:--name docker运行给容器取得别名
③:-p 容器内部和外部的端口映射
④:-v 容器内部数据持久化,映射到/mysql/databases/data文件夹下
-v /mysql/databases/data:/var/lib/mysql 宿主机目录:容器内部数据存储目录
⑤:-e 设置容器Mysql数据库的用户密码
⑥:root 密码为root
⑦:-d 程序后台运行
⑧:mysql:5.7 镜像名称:tar/镜像ID
启用JavaWeb 镜像Tomcat的Shell脚本如下
docker run -d -v /Docker:/usr/java/tomcat/apache-tomcat-8.5.27/webapps -p 8080:8080
--name MyTomcat --link mysql:aliasmysql javaweb:1.0 /root/run.sh
①:-d 后台运行
②:-v 文件夹映射,方便部署项目使用
③:-p 映射tomcat对外端口
④:--name 当前容器服务的别名MyTomcat
⑤:--link 通信机制命令
⑥:mysql 当前web容器需要连接的容器的别名mysql【mysql是启动的数据库容器别名】
⑦:aliasmysql 给当前连接的数据库取一个别名为aliasmysql【配置文件需要用】
⑧:javaweb:1.0 镜像名称:tar
⑨:/root/run.sh 启动Tomcat的运行shell脚本
上述修改完毕,Web项目并不能运行
还需要修改Web项目中配置文件
原始配置文件
修改后的配置文件
此处是将原始宿主机IP替换为运行javaweb的link数据库取的别名aliasmysql 访问Web 项目的控制层
此时测试成功
Link缺点:
①:停止link连接的目标容器,hosts文件并不会更新,只有目标容器重新启动,才会更新hosts文件。
②:容器需要按照link之间的依赖关系依次启动。
③:移除一个link连接的容器,可能会造成整个系统的link失效,需要删除并重新建立所有使用–link的容器。
④:在Docker官方文档中显示,在后续会去掉--link方法
四、同一宿主机不同容器之间多个link使用方法
用例:容器:JavaWeb(Tomcat+Nginx+JDK)
容器:Mysql数据库
容器:Redis数据库
3个以上容器之间数据通讯解决问题
按照顺序启动:
启动 数据库提供服务者:
启动 Mysql
docker run --name mysql -p 3306:3306 -v /mysql/database/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
启动Redis
docker run -d -p 6379:6379 --name redis -v /redis/database/data:/data redis:3.2 redis-server --appendonly yes
启动数据库消费方(JavaWeb):
docker run -d -v /Docker:/usr/java/tomcat/apache-tomcat-8.5.27/webapps -p 8080:8080 --name MyTomcat --link mysql:aliasmysql --link redis:aliasredis javaweb:1.0 /root/run.sh
修改MySql数据库配置文件
修改redis数据库配置文件
配置文件IP地址分别统一用link的别名替换
访问Web项目页面,查看MysqL数据库
访问Web项目页面,查看Redis数据库
综上所述:同一宿主机,不同容器多个(二个以上)容器通信问题接已经解决了!
六、同一宿主机下不同容器之间的通信(第二种方式)
不使用Docker容器的 --link命令
直接使用 docker inspect 容器ID
查看容器的元信息,
用例:查看Redis数据库IP
在配置文件中:修改
注意:此IP不是容器宿主机的IP,而是宿主机上容器ID的分配的容器IP
调用Web项目,查看Redis数据库, 同样可以进行数据通信,这种方式
优点:是不用按照数据库提供服务顺序进行进行启动,不用取别名,较为简单
缺点:通过观察发现,每一个启动容器的ip地址不是固定的,容器重启后ip地址会改变
总结:同一个宿主机上的多个docker容器之间如果想进行通信,可以通过使用容器的ip地址来通信,也可以通过宿主机的ip加上容器暴露出的端口号来通信,前者会导致ip地址的硬编码,不方便迁移,并且容器重启后ip地址会改变,除非使用固定的ip,后者的通信方式比较单一,只能依靠监听在暴露出的端口的进程来进行有限的通信。通过docker的link机制可以通过一个name来和另一个容器通信,link机制方便了容器去发现其它的容器并且可以安全的传递一些连接信息给其它的容器
备注:link的方式只能解决单机容器间的互联,多机的情况下,需要进行网络桥接
更多推荐
所有评论(0)