前面几篇文章,我们聊了docker的基本概念,以及基本的操作手段:
https://www.cnblogs.com/jilodream/p/18177695 初识docker
https://www.cnblogs.com/jilodream/p/18184687 基本操作
https://www.cnblogs.com/jilodream/p/18189478 镜像制作
但是现在随着分布式多节点的考虑,我们往往需要容器之间可以进行通信。
容器之间的通信一般分为(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )三种途径:
1、通过虚拟ip直接访问
2、通过link方式,指定要连接的容器
3、创建bridge网络,来实现容器互联
为了满足接下来的学习,我们需要利用官方的tomcat镜像为基础,初始化一些指令,DockerFile 如下:
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# cat Dockerfile
- 2 #指定基础镜像
- 3 FROM tomcat:my-tomcat-image
- 4
- 5 #指定维护人员
- 6 MAINTAINER wangruoyi "encijietuo@123.com"
- 7
- 8 # 设置环境变量
- 9 ENV BASE_DIR="/usr/local/"
- 10
- 11 #指定工作路径
- 12 WORKDIR /$BASE_DIR
- 13
- 14 #删除原有的webapps 文件夹
- 15 RUN rm -rf ./tomcat/webapps && cp -r ./tomcat/webapps.dist ./tomcat/webapps && apt-get update && apt-get install net-tools && apt install iputils-ping -y
- 16
- 17 #暴露8080端口,其实没有必要,因为原有的
- 18 EXPOSE 8080
- 19
- 20 #ENTRYPOINT ["echo 'hello myImage'"]
开始构建镜像,并查看
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker build -t new .
- 2 省略部分输出
- 3 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker images
- 4 REPOSITORY TAG IMAGE ID CREATED SIZE
- 5 new latest 9a36ac14523d 21 hours ago 706MB
然后我们回到重点,依次来看看容器的3种通信途径:
1、通过虚拟ip直接访问
安装docker之后,docker会默认搭建一个docker0的网络,后续每个容器就是网络中的一个节点,(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )每个节点因此会有属于网络中的一个虚拟ip。我们可以利用虚拟ip直接进行访问。
如下,我们创建两个容器:
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker run -p 8081:8080 -d --name mytom8081 9a36ac14523d
- 2 f3f1b0f09320e6e42e704625fa4aa2d544a553976cf38dba7c1dcddfe65e8563
- 3 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker run -p 8082:8080 -d --name mytom8082 9a36ac14523d
- 4 744a1395c38840cc01659ec9fa2d55026389ca5d99387092de1d23c026613a65
- 5 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker ps
- 6 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 7 744a1395c388 9a36ac14523d "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:8082->8080/tcp mytom8082
- 8 f3f1b0f09320 9a36ac14523d "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:8081->8080/tcp mytom8081
我们可以通过ifconfig或者inspect 查看容器ip,接着使用 ping 和curl 命令实现两个容器的互相访问,我们发现网络是通着的:
进入8081容器,并查看ip为172.17.0.2
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker exec -it f3f1b0f09320 /bin/bash
- 2 root@f3f1b0f09320:/usr/local# ifconfig
- 3 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
- 4 inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
- 5
- 6 以下省略部分
进入8082容器,,并查看ip为172.17.0.3
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker exec -it 744a1395c388 /bin/bash
- 2 root@744a1395c388:/usr/local# ifconfig
- 3 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
- 4 inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
- 5 inet6 fe80::42:acff:fe11:3 prefixlen 64 scopeid 0x20<link>
- 6
- 7 以下省略部分
8081 ping 8082,并访问对方tomcat端口
- 1 root@f3f1b0f09320:/usr/local# ping 172.17.0.3
- 2 PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
- 3 64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.218 ms
- 4 64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.084 ms
- 5 ^C
- 6 --- 172.17.0.3 ping statistics ---
- 7 2 packets transmitted, 2 received, 0% packet loss, time 1000ms
- 8 rtt min/avg/max/mdev = 0.084/0.151/0.218/0.067 ms
- 9 root@f3f1b0f09320:/usr/local# curl 172.17.0.3:8080
- 10
- 11
- 12
- 13 <!DOCTYPE html>
- 14 <html lang="en">
- 15 <head>
- 16 <meta charset="UTF-8" />
- 17 <title>Apache Tomcat/10.0.14</title>
- 18
- 19 以下省略部分
8082 ping 8081,并访问对方tomcat端口
- 1 root@744a1395c388:/usr/local# ping 172.17.0.2
- 2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
- 3 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.150 ms
- 4 ^C
- 5 --- 172.17.0.2 ping statistics ---
- 6 1 packets transmitted, 1 received, 0% packet loss, time 0ms
- 7 rtt min/avg/max/mdev = 0.150/0.150/0.150/0.000 ms
- 8 root@744a1395c388:/usr/local# curl 172.17.0.2:8080
- 9
- 10
- 11
- 12 <!DOCTYPE html>
- 13 <html lang="en">
- 14 <head>
- 15 <meta charset="UTF-8" />
这种情况一般比较简单,而且实际搭建网络集群时,比较复杂,ip地址也不好维护,所以我们一般只是在环境测试时使用。
2、通过link方式,指定要连接的容器
命令描述如下:
docker run -d --name 容器名称 --link 被连接容器名:被连接容器别名 镜像Id
我们创建两个容器。然后通过ifconfig或者inspect 查看容器ip
我们可以直接通过(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )别名来访问另外一个容器,
以下为8081容器:ip为172.17.0.2:
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker run -p 8081:8080 -d --name mytom8081 9a36ac14523d
- 2 ce95c0e7a3f10a3623c0c86ef38caaa33a758ca15fd2a246757686c7329c9092
- 3 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker ps
- 4 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 5 a67f455d6bf0 9a36ac14523d "catalina.sh run" 15 seconds ago Up 15 seconds 0.0.0.0:8082->8080/tcp mytom8082
- 6 ce95c0e7a3f1 9a36ac14523d "catalina.sh run" 18 minutes ago Up 18 minutes 0.0.0.0:8081->8080/tcp mytom8081
- 7 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker exec -it ce95c0e7a3f1 /bin/bash
- 8 root@ce95c0e7a3f1:/usr/local# ifconfig
- 9 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
- 10 inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
- 11 inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
以下为8082容器,ip为172.17.0.3 :
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker run -p 8082:8080 -d --name mytom8082 --link mytom8081:mytom8081alias 9a36ac14523d
- 2 a67f455d6bf0d37b9fb43769d6d93d0e59903fb585b2fd4d37434b3199394869
- 3
- 4 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker exec -it a67f455d6bf0 /bin/bash
- 5 root@a67f455d6bf0:/usr/local# ifconfig
- 6 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
- 7 inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
8082容器通过ip和网络别名访问8081容器:
- 1 root@a67f455d6bf0:/usr/local# ping 172.17.0.2
- 2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
- 3 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.158 ms
- 4 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.063 ms
- 5 ^C
- 6 --- 172.17.0.2 ping statistics ---
- 7 2 packets transmitted, 2 received, 0% packet loss, time 999ms
- 8 rtt min/avg/max/mdev = 0.063/0.110/0.158/0.047 ms
- 9 root@a67f455d6bf0:/usr/local# ping mytom8081alias
- 10 PING mytom8081alias (172.17.0.2) 56(84) bytes of data.
- 11 64 bytes from mytom8081alias (172.17.0.2): icmp_seq=1 ttl=64 time=0.081 ms
- 12 64 bytes from mytom8081alias (172.17.0.2): icmp_seq=2 ttl=64 time=0.063 ms
- 13 ^C
- 14 --- mytom8081alias ping statistics ---
- 15 2 packets transmitted, 2 received, 0% packet loss, time 1000ms
- 16 rtt min/avg/max/mdev = 0.063/0.072/0.081/0.009 ms
- 17 root@a67f455d6bf0:/usr/local# curl mytom8081alias:8080
- 18
- 19
- 20
- 21 <!DOCTYPE html>
- 22 <html lang="en">
link方式本质上还是使用docker0网络,(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )修改host文件的ip映射,来实现网络通信。并且随着ip的变化还可以动态的维护这种映射关系。
但是link方式也有自己的局限性,如只能单向请求,两个容器无法互相连接请求对方,因为link配置是在启动容器时就已经生成好的,也就是只能后边的容器单向请求前边的容器,无法形成循环的网络。由于诸多不便,link方式也被抛弃了,更推荐的是bridge网络方式。
3、创建bridge网络,来实现容器互联
(1)首先我们创建一个bridge网络:
docker network create 网络名称
如下,我们创建一个网络名称为mynet的网络
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker network ls
- 2 NETWORK ID NAME DRIVER SCOPE
- 3 aa377d4ce411 bridge bridge local
- 4 39d44fbbca56 host host local
- 5 2b8ed0e20118 none null local
- 6
- 7 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker network create mynet
- 8 fd1097786e75a0e3b7160fdacc49f60d815457dbbcc4654bb138136f02d9cb54
- 9 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker network ls
- 10 NETWORK ID NAME DRIVER SCOPE
- 11 aa377d4ce411 bridge bridge local
- 12 39d44fbbca56 host host local
- 13 fd1097786e75 mynet bridge local
- 14 2b8ed0e20118 none null local
(2)新创建3个容器加入到bridege网络中
命令如下docker run -it --name 容器名 ---network bridge网络名 --network-alias 当前容器在网络中的别名 镜像名
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker run -p 8083:8080 -d --name mytom8083 --network mynet --network-alias mytom8083alias 9a36ac14523d
- 2 1d993226c559408a54d18f9258d2dc196283dc5b6b0cffa2d113b4eef579f7c4
- 3 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker run -p 8084:8080 -d --name mytom8084 --network mynet --network-alias mytom8084alias 9a36ac14523d
- 4 c7de74283019bccfc87174941afdeb2fbbd0137496094bd7fd9d6a500352a4ad
- 5 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker run -p 8085:8080 -d --name mytom8085 --network mynet --network-alias mytom8085alias 9a36ac14523d
- 6 28c5fa396b54649edc31c52c4cdf85a96063919272a12f61b208cfb99f1325f9
- 7
- 8 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 9 28c5fa396b54 9a36ac14523d "catalina.sh run" 4 minutes ago Up 45 seconds 0.0.0.0:8085->8080/tcp mytom8085
- 10 c7de74283019 9a36ac14523d "catalina.sh run" 13 minutes ago Up 13 minutes 0.0.0.0:8084->8080/tcp mytom8084
- 11 1d993226c559 9a36ac14523d "catalina.sh run" 14 minutes ago Up 13 minutes 0.0.0.0:8083->8080/tcp mytom8083
(3)进入到3个容器中,分别访问其它容器
以下为8083容器:8083访问8084
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker exec -it 1d993226c559 /bin/bash
- 2 root@1d993226c559:/usr/local# curl mytom8084alias:8080
- 3
- 4
- 5
- 6 <!DOCTYPE html>
- 7 <html lang="en">
- 8 <head>
- 9 <meta charset="UTF-8" />
以下为8084容器: 8084访问8083
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker exec -it c7de74283019 /bin/bash
- 2 root@c7de74283019:/usr/local#
- 3 root@c7de74283019:/usr/local#
- 4 root@c7de74283019:/usr/local#
- 5 root@c7de74283019:/usr/local# ping mytom8083alias
- 6 PING mytom8083alias (172.18.0.2) 56(84) bytes of data.
- 7 64 bytes from mytom8083.mynet (172.18.0.2): icmp_seq=1 ttl=64 time=0.151 ms
- 8 64 bytes from mytom8083.mynet (172.18.0.2): icmp_seq=2 ttl=64 time=0.057 ms
- 9 ^C
- 10 --- mytom8083alias ping statistics ---
- 11 2 packets transmitted, 2 received, 0% packet loss, time 1001ms
- 12 rtt min/avg/max/mdev = 0.057/0.104/0.151/0.047 ms
- 13 root@c7de74283019:/usr/local# curl mytom8083alias:8080
- 14
- 15
- 16
- 17 <!DOCTYPE html>
- 18 <html lang="en">
- 19 <head>
- 20 <meta charset="UTF-8" />
- 21 <title>Apache Tomcat/10.0.14</title>
以下为8085容器:8085访问8083、8084
- 1 [root@iZ2ze3bpa0o5cw6gp42ry2Z ~]# docker exec -it 28c5fa396b54 /bin/bash
- 2 root@28c5fa396b54:/usr/local# curl mytom8083alias:8080
- 3
- 4 <!DOCTYPE html>
- 5 <html lang="en">
- 6 <head>
- 7 <meta charset="UTF-8" />
- 8 <title>Apache Tomcat/10.0.14</title>
- 9 <link href="favicon.ico" rel="icon" type="image/x-icon" />
- 10 <link href="tomcat.css" rel="stylesheet" type="text/css" />
- 11
- 12 省略若干
- 13
- 14 root@28c5fa396b54:/usr/local# curl mytom8084alias:8080
- 15 <!DOCTYPE html>
- 16 <html lang="en">
- 17 <head>
- 18 <meta charset="UTF-8" />
- 19 <title>Apache Tomcat/10.0.14</title>
- 20 <link href="favicon.ico" rel="icon" type="image/x-icon" />
- 21 <link href="tomcat.css" rel="stylesheet" type="text/css" />
我们可以发现第三种(构建bridge网络)的方式,相对来说最为灵活实用,不需要提前规划,并且可以实现网状的网络通信请求。
回到诉求本身,其实我们队容器间的通信诉求并没有想象中的那么迫切,我们往往是通过端口映射到宿主机中,通过访问不通的宿主机ip和端口来实现容器间通信。这样也屏蔽了宿主机中容器的概念,并且可以广泛的无差别使用各种中间件,使得开发起来更容易。
但是有时候出于网络安全考虑,不允许请求进行跳转,或者端口进行屏蔽,此时就需要考虑下是否可以使用容器通信的技术来实现诉求。