#|Docker网络与容器之间通信原理

1、namespace 扩展知识:
https://www.jianshu.com/p/b2fdf18a88ed
实战:打通两个命名空间的网络,模拟两个容器通信原理

查看命名空间列表 ip netns list 新增一个网络命名空间(名称test1) ip netns addtest1 删除网络命名空间test1 ip netns delete test1 查看本机namespace默认是down的状态 ip netns exec test1 ip a 变为up状态,显示为unknown ip netns exec test1 ip link set dev lo up ip netns exec test1 ip a

#|Docker网络与容器之间通信原理
文章图片

1)先创建一对veth虚拟网络设备veth-test1和veth-test2
创建并查看link ip link add veth-test1 type veth peer name veth-test2 ip link 或者 ip addr

#|Docker网络与容器之间通信原理
文章图片

  1. 把veth-test1设置到test1命名空间,把veth-test2设置到test2命名空间:
添加veth-test1到test1的namespace ip link set veth-test1 netns test1 ip netns exec test1 ip a 添加并查看veth-test2 ip link set veth-test2 netns test2 ip netns exec test2 ip a

#|Docker网络与容器之间通信原理
文章图片

3)给两个主机分别配置ip(进入命名空间启动网卡然后给网卡配置ip),然后互ping
ip netns exec test1 ip link set veth-test1 upip netns exec test2 ip link set veth-test2 upip netns exec test1 ip a add 192.168.1.1/24 dev veth-test1ip netns exec test2 ip a add 192.168.1.2/24 dev veth-test2 # 然后互ping ip netns exec test1 ping 192.168.1.2 ip netns exec test2 ping 192.168.1.1

#|Docker网络与容器之间通信原理
文章图片

#|Docker网络与容器之间通信原理
文章图片

2、bridge网络(桥接网络) 实战演练:
test1与test2通过docker0访问宿主机然后访问的百度外网;
test1、test2与docker在同一网段内是互通的
#|Docker网络与容器之间通信原理
文章图片

1、新建3个容器
docker run -d --name test1 busybox /bin/sh -c “while true; do sleep 3600; done”
docker run -d --name test2 busybox /bin/sh -c “while true; do sleep 3600; done”
docker run -d --name test3 busybox /bin/sh -c “while true; do sleep 3600; done”
2、可以看到容器test1和本机的网卡有veth对,test2与test3也是如此,通过虚拟出的网卡与veth一一对应建立通信
docker exec test1 ip a
#|Docker网络与容器之间通信原理
文章图片

3、查看本机网卡,docker0下这个veth与docker容器中的test1网卡一一对应
ip addr
#|Docker网络与容器之间通信原理
文章图片

4、安装brctl查看交接网络
yum -y install bridge-utils
5、查看本机的veth,查看本机网卡,docker0下有这3个veth(veth40000c8、veth7c8618c、veth825d419)
brctl show
#|Docker网络与容器之间通信原理
文章图片

3、容器通信 解决不同ip网段不同之间的通信
1、首先启动一个容器test5
docker run -d --name test5 busybox /bin/sh -c “while true; do sleep 3600; done”
2、再创建一个有—link的容器,谁link谁就能ping通谁
docker run -d --name test6 --link test5 busybox /bin/sh -c “while true; do sleep 3600; done”
3、此时,可以用test6直接访问test5,类似于访问主机名,但是test5是单独创建的,所以test5容器内是无法平通test6的
#|Docker网络与容器之间通信原理
文章图片

4、端口映射 实战运行一个nginx并对外提供访问
1.运行一个nginx容器
docker run --name web -d nginx
2.查看桥接网络状态
docker network inspect bridge
#|Docker网络与容器之间通信原理
文章图片

3.容器内可以访问,容器外访问不到
ping 172.17.0.7
telnet 172.17.0.7 80
curl http://172.17.0.7
#|Docker网络与容器之间通信原理
文章图片

#|Docker网络与容器之间通信原理
文章图片

#|Docker网络与容器之间通信原理
文章图片

4.停止并删除容器
docker stop web
docker stop web
5.重新创建容器,并指定端口映射
docker run --name web -d -p 80:80 nginx
6.外界可以访问了
http://192.168.56.10/
#|Docker网络与容器之间通信原理
文章图片

5、网络的none和host 查看docker所有网络
docker network ls
none网络:应用场景是安全性极高的情况,应用并不多
创建新的容器,使用none网络
docker run -d --name test7 --network none busybox /bin/sh -c “while true; do sleep 3600; done”
查看none网络状态
docker network inspect none
外界访问不了也无法查看该容器ip,只有进去,127.0.0.1可以访问
ip netns exec test7 a
docker exec -it test7 /bin/sh
ip a
#|Docker网络与容器之间通信原理
文章图片

#|Docker网络与容器之间通信原理
文章图片

【#|Docker网络与容器之间通信原理】host网络,也就是复制并使用宿主机网络:
创建新的容器,使用host网络
docker run -d --name test8 --network host busybox /bin/sh -c “while true; do sleep 3600; done”
查看host网络状态
docker network inspect host
进入容器,查看网络,发现容器外宿主机网络一致
ip netns exec test8 a
docker exec -it test8 /bin/sh
ip a
#|Docker网络与容器之间通信原理
文章图片

6、多容器部署和应用 实例
运行redis容器
docker run -d --name redis redis
编写app.py,做web服务,
$ cat app.py from flask import Flask from redis import Redis import os import socketapp=Flask(__name__) redis=Redis(host=os.environ.get('REDIS_HOST','127.0.0.1'),port=6379)@app.route('/') def hello(): redis.incr('hits') return 'hello docker! count %s and hostname is %s. \n'%(redis.get('hits'),socket.gethostname())if __name__ == "__main__": app.run(host="0.0.0.0",port=5000,debug=True)

编写Dockerfile
$ vi Dockerfile FROM python:2.7 LABEL maintaner="1019213039@qq.com" COPY . /app WORKDIR /app RUN pip install flask redis EXPOSE 5000 CMD ["python","app.py"]

构建redis镜像
docker build -t liuyuanshan/flask-redis .
运行容器,并设置环境变量REDIS_HOST,设置flask-redis 去link redis
docker run -d -p 5000:5000 --link redis --name flask-redis -e REDIS_HOST=redis liuyuanshan/flask-redis
进入容器并查看环境变量
docker exec -it redis /bin/bash
env
访问:
http://192.168.56.10:5000
#|Docker网络与容器之间通信原理
文章图片

7、多机器多容器通信

    推荐阅读