1.容器通信

容器之间除了使用ip通信外,还可以使用容器名称通信
docker1.10开始,内嵌了一个DNS server
dns解析功能必须在自定义网络中使用

以容器demo的网络打开一个新容器,此时新容器的ip和demo的ip完全一致
处于这个模式下的docker容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信

[root@server2 ~]# docker ps
[root@server2 ~]# docker inspect demo
[root@server2 ~]# docker run -it --rm --network container:demo busybox
/ # ip addr
/ # netstat -antlp

docker两边 mac 双屏 docker两个容器通信_nginx


–link可以用来链接两个容器

实验前删除不用的docker

[root@server2 ~]# docker rm -f demo demo2

传输一个nginx容器

[root@server1 mnt]# scp nginx.tar server2:
[root@server2 ~]# docker load -i nginx.tar

docker两边 mac 双屏 docker两个容器通信_nginx_02


后台开启一个demo容器,在开启一个容器nginx链接demo,此时nginx可以ping通demo、nginx

[root@server2 ~]# docker run -d --name demo nginx
[root@server2 ~]# docker run -it --rm --link demo:nginx busybox
/ # env
/ # ping demo
/ # ping nginx
/ # cat /etc/hosts

docker两边 mac 双屏 docker两个容器通信_docker两边 mac 双屏_03


查看他的解析

docker两边 mac 双屏 docker两个容器通信_nginx_04


docker两边 mac 双屏 docker两个容器通信_docker_05

停止demo,开启demo2

[root@server2 ~]# docker stop demo 
[root@server2 ~]# docker run  -d --name demo2 nginx
[root@server2 ~]# docker inspect demo2

docker两边 mac 双屏 docker两个容器通信_linux_06


此时demo2的ip会占用demo的ip

docker两边 mac 双屏 docker两个容器通信_网络_07


开启demo,ip会变化

[root@server2 ~]# docker start demo 
[root@server2 ~]# docker inspect demo

docker两边 mac 双屏 docker两个容器通信_linux_08


此时在之前未停止的容器上在去ping nginx,会发现解析已经自动变化,但是env下的没有变化

docker两边 mac 双屏 docker两个容器通信_linux_09

容器如何访问外网是通过iptables的SNAT实现的

外网如何访问容器
端口映射
-P 选项指定映射端口

[root@server2 ~]# docker rm -f demo demo2
[root@server2 ~]# docker ps
[root@server2 ~]# docker run -d --name demo -p 80:80 nginx
[root@server2 ~]# netstat -antlp
[root@server2 ~]# iptables -t nat -nL

docker两边 mac 双屏 docker两个容器通信_docker两边 mac 双屏_10


docker两边 mac 双屏 docker两个容器通信_nginx_11

[root@server2 ~]# kill 9658
[root@server2 ~]# curl localhost
[root@server2 ~]# [root@server1 ~]# curl 192.168.3.202
[root@server1 ~]# curl 192.168.3.202

删除docker-proxy,此时本地ping不同,但是ip可以

docker两边 mac 双屏 docker两个容器通信_网络_12


docker两边 mac 双屏 docker两个容器通信_linux_13


server1上访问

docker两边 mac 双屏 docker两个容器通信_docker_14


容器内部

如果单独删除docker-proxy进程,容器之间访问也不受影响

[root@server2 ~]# docker run -it --rm busyboxplus
/ # curl 172.17.0.2

docker两边 mac 双屏 docker两个容器通信_nginx_15


删除iptables DNAT

[root@server2 ~]# docker rm -f demo 
[root@server2 ~]# docker run -d --name demo -p 80:80 nginx
[root@server2 ~]# iptables -t nat -nL
[root@server2 ~]# netstat -antlp
[root@server2 ~]# iptables -t nat -D DOCKER 3

docker两边 mac 双屏 docker两个容器通信_linux_16


docker两边 mac 双屏 docker两个容器通信_docker两边 mac 双屏_17

docker两边 mac 双屏 docker两个容器通信_docker_18


此时都可以访问

[root@server2 ~]# curl localhost
[root@server2 ~]# [root@server1 ~]# curl 192.168.3.202
[root@server1 ~]# curl 192.168.3.202

docker两边 mac 双屏 docker两个容器通信_nginx_19


docker两边 mac 双屏 docker两个容器通信_docker两边 mac 双屏_20


docker两边 mac 双屏 docker两个容器通信_网络_21

所以外王访问容器用到了docker-proxy和iptables DNAT,宿主机访问本机容器使用的是iptables DNAT,外部主机访问容器或者容器之间的访问是docker-proxy实现

2.跨主机容器网络

macvlan网络方案实现

linux kernel提供的一种网卡虚拟化技术
无需linux bridge,直接使用物理借口,性能及好。

实验条件:

在两台主机上个添加一块网卡,打开网卡混杂模式

docker两边 mac 双屏 docker两个容器通信_docker两边 mac 双屏_22


docker两边 mac 双屏 docker两个容器通信_docker_23


打开混杂模式

[root@server2 ~]# ip link set eth1 promisc on
[root@server2 ~]# ip addr show eth1

docker两边 mac 双屏 docker两个容器通信_docker_24


创建自定义网络,添加子网和网关,父级网卡为eth1物理网卡

[root@server2 ~]# docker network create -d macvlan --subnet 172.21.0.0/24 --gateway=172.21.0.1 -o parent=eth1 mac_net1
[root@server2 ~]# docker network  ls

docker两边 mac 双屏 docker两个容器通信_linux_25

server1进行上述相同步骤,此处不作展示

在两台主机上打开相同网段的容器,发现是可以相互ping通的

[root@server2 ~]# docker run -it --rm --network mac_net1 --ip 172.21.0.12 busybox
[root@server1 ~]# docker run -it --rm --network mac_net1 --ip 172.21.0.11 busybox

docker两边 mac 双屏 docker两个容器通信_nginx_26

docker两边 mac 双屏 docker两个容器通信_nginx_27

自定义第二个网络,注意和第一个的网络的区别

[root@server1 ~]# docker network create -d macvlan --subnet 172.22.0.0/24 --gateway=172.22.0.1 -o parent=eth1.1 mac_net2
[root@server2 ~]# docker network create -d macvlan --subnet 172.22.0.0/24 --gateway=172.22.0.1 -o parent=eth1.1 mac_net2

docker两边 mac 双屏 docker两个容器通信_网络_28


在自定义网络二下的相同网段两台主机上的容器也可以通

[root@server1 ~]# docker run -it --rm --network mac_net2 --ip 172.22.0.21 busybox
/ # ping 172.22.0.22
ctrl + pq保存退出

docker两边 mac 双屏 docker两个容器通信_网络_29

[root@server2 ~]# docker run -it --rm --network mac_net2 --ip 172.22.0.22 busybox

docker两边 mac 双屏 docker两个容器通信_nginx_30


尝试用自定义网络一去ping网络二是不同的

[root@server1 ~]# docker ps
[root@server1 ~]# docker run -it --rm --network mac_net1 --ip 172.21.0.11 busybox
/ # ip addr
/ # ping 172.22.0.21

docker两边 mac 双屏 docker两个容器通信_网络_31


所以macvlan网络在二层上是隔离的,所以在不同macvlan网络的容器是不能通信的
可以在三层上通过网关将macvlan网络连通起来