docker通信

Docker容器访问

外部要访问Docker中的Container的话,其中外部可以理解为宿主机。外部要访问这些应用,可以通过-P或者-p 参数 来指定端口映射。
当使用-P标记时候,Docker会随机映射一个49000-49900的端口到内部容器开放的网络端口。


容器之间互相连接

在之前可以用--link参数来使容器互相连接,随着Docker网络的完善,我们可以通过Docker网络来连接多个容器。
对于目前的Docker而言,有4种基本模式,分别为bridge(网桥),host(主机),container(容器),none(未联网)。
目前而言还有一种实施跨主机联网的集群解决联网方案,overlay,overlay网络类型用于swarm mode。
---Bridge网桥模式:
如下图所示,一般而言,图中有一个提供给docker容器相互连接的网桥,docker0,其地址一般为172.17.42.1。当容器启动之后,Docker会生成一个veth的接口,这个接口本质相当于软件实现以太网的物理连接,Docker通过veth接口将容器的eth0连接到网桥。
默认情况下,所有容器都可以相互沟通,无论是否已经建立连接,或者已经导出端口。可以在Docker守护进程启动的时候加上--icc=false参数,这个参数将设置一个iptables规则,把容器之间的通信关闭。如果同时设置了--icc=false--iptables=true,那么只有已连接的容器才能通信,这也是通过iptables规则实现的。
网桥模式也是仅仅适用于开发模式,在生产模式下就不一定适用了。

---Host主机模式
如果容器以--net=host启动,那么容器就会共享主机的命名空间,容器会在公网上暴露出来。容器与主机共享一个ip地址,这也就意味着降低了底层开销,在速度上与常规主机一样快。

---Container容器模式
也就是使用另一个容器的命名空间,共享另一容器的ip地址。

---none未联网模式
也就把容器的网络完全关闭,无需连接任何容器,只需要将数据写入挂载在宿主机上的数据卷。

---overlay
overlay是Docker为了解决跨主机联网而实现的‘内附电池’方案。连接容器至overlay与网桥方式基本相同。同样需要建立起Linux网桥,并且需要一对veth接口用于容器之间的互相连接。


具体实施
首先创建一个新的docker网络

docker network create -d bridge my-net

-d参数指定Docker网络类型,有bridgeoverlay
然后连接容器步骤
运行一个容器并且连接到新的my-net网络上

docker run -it --rm --name busybox1 --network my-net busybox sh

打开新的终端,再运行一个容器并且加入到my-net网络

docker run -it --name busybox2 --network my-net busybox sh

再打开一个终端查看容器信息,之后通过ping来证明busybox1busybox2建立了互联关系
但是一般情况下,如果要使用多个容器相互连接的话,还是推荐使用Docker-compose,这样以来,只需要一个简单的模版,就可以完成复杂的工作。


配置docker0网桥
docker0在内核层联通了其他的物理或者虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker0默认制定了docker0接口的ip地址和子网掩码,让主机和容器之间可以通过网桥相互通信。由于目前docker网桥是linux网桥,用户可以使用brctl show来查看网桥和端口连接信息。
每次创建一个新的容器的时候,Docker从可用的地址段中选择一个空闲的ip地址分配给容器的eth0端口。使用本地主机上docker0接口的IP作为所有容器的默认网关。


创建点到点的连接
在默认情况下,Docker会将所有容器连接到由docker0提供的虚拟子网中。
用户有时候需要两个容器之间可以直接连接通信,而不通过主机网桥进行连接,此时就需要创建一对peer接口,分别放在两个容器中,配置成点到点链路类型即可。
首先要启动两个容器

$ docker run -i -t --rm --net=none base /bin/bash
root@1f1f4c1f931a:/#
$ docker run -i -t --rm --net=none base /bin/bash
root@12e343489d2f:/#

找到进程号,然后创建网络命名空间的跟踪文件

$ docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a
2989
$ docker inspect -f '{{.State.Pid}}' 12e343489d2f
3004
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/2989/ns/net:/var/run/netns/2989
$ sudo ln -s /proc/3004/ns/net:/var/run/netns/3004

创建一对peer接口,配置路由

$ sudo ip link add A type veth peer name B
$ sudo ip link set A netns 2989
$ sudo ip netns exec 2989 ip addr add 10.1.1.1/32 dev A
$ sudo ip netns exec 2989 ip link set A up
$ sudo ip netns exec 2989 ip route add 10.1.1.2/32 dev A
$ sudo ip link set B netns 3004
$ sudo ip netns exec 3004 ip addr add 10.1.1.2/32 dev B
$ sudo ip netns exec 3004 ip link set B up
$ sudo ip netns exec 3004 ip route add 10.1.1.1/32 dev B

这样一来两个容器就可以相互ping通,并成功建立连接。点到点链路不需要子网和子网掩码。

你可能感兴趣的:(docker通信)