Docker使用Link与newwork在容器之间建立连接
一,使用 --link容器互联
docker 默认使允许container 互通的(通过-icc=false 关闭互通)同一个宿主机上的多个docker容器之间如果想进行通信,可以通过使用容器的ip地址来通信,也可以通过宿主机的ip加上容器暴露出的端口号来通信,前者会导致ip地址的硬编码,不方便迁移,并且容器重启后ip地址会改变,除非使用固定的ip,后者的通信方式比较单一,只能依靠监听在暴露出的端口的进程来进行有限的通信。通过docker的link机制可以通过一个name来和另一个容器通信,link机制方便了容器去发现其它的容器并且可以安全的传递一些连接信息给其它的容器。
格式 -link name:alias 命令连接指定container
1,创建并启动一个被连接的容器
docker run --name mypostgres_merry -d -p 5432:5432 -e POSTGRES_PASSWORD=123456 -e PGDATA=/data/ -e POSTGRES_USER=admin -e POSTGRES_DB=my_db postgres
查看容器名称 docker ps
2,修改主程序配置文件
# 生产配置 server: port: 8081 spring: jpa: show-sql: true hibernate: ddl-auto: update properties: hibernate: jdbc: lob: non_contextual_creation: true datasource: driverClassName: org.postgresql.Driver url: jdbc:postgresql://db:5432/my_db username: admin password: 123456 initialization-mode: always #执行根目录下面data.sql初始化数据 continue-on-error: false
3,启动主程序并连接到另一个容器
docker run -d --name web --link mypostgres_merry:db -p 8081:8081 ejiyuan/demo-docker
注意,link后面的名字要必须是一个存在的容器名称(与上图中NAMES一致)冒号后面的别名为容器内部识别名称,别名要与主程序配置文件一致
4,验证
登录到容器
docker exec -it node /bin/sh
执行 env 查看环境变量(或者使用: docker exec 16087e0f620a env),包含db相关配置参数
执行 ping db 可以ping通
使用了link机制后,可以通过指定的名字来和目标容器通信,这其实是通过给/etc/hosts
中加入名称和IP的解析关系来实现的,下面是名为web的容器中的/etc/hosts
信息.
二,使用network互联
1,查看docker网络说明:
docker network ls
Docker内置这三个网络,运行容器时,你可以使用该--network标志来指定容器应连接到哪些网络。
1.1 Host:host相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址
1.2 Container:在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
1.3 None:该模式将容器放置在它自己的网络栈中,但是并不进行任何配置。在容器并不需要网络(例如只需要写磁盘卷的批处理任务)使用该模式关闭了容器的网络功能。
1.4 Bridge:相当于Vmware中的Nat模式,容器使用独立network Namespace,并连接到docker0虚拟网卡(默认模式)。通过docker0网桥以及Iptables nat表配置与宿主机通信;bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上,除非你使用该docker run --network=<NETWORK>选项指定,否则Docker守护程序默认将容器连接到此网络。
2,查看容器网络配置
docker inspect 容器id
查看networks段配置
查看brigdge 网络配置
docker network inspect bridge
结果如下:
3,创建网络
docker network create --driver bridge new_net_1
--driver为网络类型,后面“new_net_1”为网络名称,默认为bridge可以不指定--driver bridge
通过network inspect再次查看网络
通过 inspect 查看,分配了一个新的ip段
4,启动服务加入网络
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=123456 -e PGDATA=/data/ -e POSTGRES_USER=admin -e POSTGRES_DB=my_db --network new_net_1 postgres
使用inspect 查看网络设置
docker inspect ba5e1d752bc9
5,启动另一个程序服务加入网络另一个网络
docker run -d -t --name web -p 8081:8081 ejiyuan/demo-docker
- 默认加入到 bridge
- ejiyuan/demo-docker配置文件数据库连接字符串为:jdbc:postgresql://172.25.0.2:5432/my_db 即上面启动数据库容器加入到new_net_1网络的ip地址
因为不在一个网段,无法访问,通过docker logs xxxx 输出日志发现
6,修改配置文件连接字符串jdbc:postgresql://db:5432/my_db使用 --link连接
修改启动参数
docker run -d -t --name web --link gracious_mcnulty:db -p 8081:8081 ejiyuan/demo-docker
服务无法启动,错误如下:
Error response from daemon: Cannot link to /gracious_mcnulty, as it does not belong to the default network.
7,修改启动参数加入同一个网络
docker run -d -t --name web --net new_net_1 -p 8081:8081 ejiyuan/demo-docker
使用inspect查看网络设置
验证可以正常访问的
三,总结
- 通过验证发现docker network作用为分组隔离不同网络环境中的各组应用
- 在都加入到“new_net_1”的情情况下,使用--link无法进行互通,在默认不指定网络的情况下可以使用 --link 互通,介于下面参考资料1中尾部所诉,这里具体原因就不做研究了
四,参考资料