本篇文章使用nginx:apline 镜像进行编辑。
docker 版本基于[root@master song]# docker versionClient: Version: 18.09.2 API version: 1.39 Go version: go1.10.6 Git commit: 6247962 Built: Sun Feb 10 04:13:27 2019 OS/Arch: linux/amd64 Experimental: falseServer: Docker Engine - Community Engine: Version: 18.09.2 API version: 1.39 (minimum version 1.12) Go version: go1.10.6 Git commit: 6247962 Built: Sun Feb 10 03:47:25 2019 OS/Arch: linux/amd64 Experimental: false
1.host模式
即docker直接共享主机的网络命名空间。
众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
例如,我们在10.10.101.105/24的机器上用host模式启动一个含有web应用的Docker容器,监听tcp80端口。当我们在容器中执行任何类似ifconfig命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用10.10.101.105:80即可,不用任何NAT转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离。
[root@master song]# docker run -d --network=host --name nginx nginx:alpine186938ec427789522267eaec0f865dc7ae0427dd5552a11b249cba6d0b86cc67[root@master song]# netstat -tnlup |grep 80tcp 0 0 172.20.0.91:2380 0.0.0.0:* LISTEN 5055/etcd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10512/nginx: master tcp6 0 0 :::30080 :::* LISTEN 5819/kube-proxy [root@master song]# ps -ef |grep 10512root 10512 10496 0 22:42 ? 00:00:00 nginx: master process nginx -g daemon off;100 10531 10512 0 22:42 ? 00:00:00 nginx: worker processroot 10961 12460 0 22:42 pts/1 00:00:00 grep --color=auto 10512[root@master song]# ps -ef |grep 10496root 10496 3628 0 22:42 ? 00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/186938ec427789522267eaec0f865dc7ae0427dd5552a11b249cba6d0b86cc67 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runcroot 10512 10496 0 22:42 ? 00:00:00 nginx: master process nginx -g daemon off;root 11046 12460 0 22:43 pts/1 00:00:00 grep --color=auto 10496 此时容器开发的80端口和主机直接启动nginx的不同点仅仅为主进程号不同 进入容器关闭 nginx服务再查看端口
[root@master song]# docker exec -it nginx /bin/sh
/ # nginx -s stop2019/03/05 14:45:34 [notice] 13#13: signal process started/ # [root@master song]# [root@master song]# netstat -tnlup |grep 80tcp 0 0 172.20.0.91:2380 0.0.0.0:* LISTEN 5055/etcd tcp6 0 0 :::30080 :::* LISTEN 5819/kube-proxy [root@master song]# ps -ef |grep 10496root 13018 12460 0 22:45 pts/1 00:00:00 grep --color=auto 10496容器直接死亡了,换另外一种方式
[root@master song]# docker run -d --network=host --name nginx nginx:alpine sleep 500
57e1c406e099e31a31a7b739a233b454740e153b7d9efb29bed14253d620e6da容器不启动任何端口,network=host 方式不生效
2.容器模式
在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
[root@master song]# docker run -d --name nginx nginx:alpine 1f5980e70d0fee792eed2183c0459ee37240d1d9cc0f2eae3c5701291114e2d7[root@master song]# docker run -i -t --network=container:nginx --name nginx2 nginx:alpine /bin/sh/ # ip a1: lo:mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever13175: eth0@if13176: mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever/ # netstat -tnlupActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
有人会感觉这个是不是和 --link的操作是一样的
重要区别是。link是hostname的解析,两个容器有自己的的半个网卡。而container直连的是没有这么一说的。
3.none模式
这个模式和前两个不同。在这种模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
[root@master song]# docker run -d --network=none --name nginx nginx:alpine 52bfb4e782d2c2a94fbd7532fac71ad1e25f0cc03b29c76bf2dc480c7c1a1887[root@master song]# docker exec -t -i nginx /bin/sh/ # ip a1: lo:mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever/ # netstat -tnlupActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro/ #
4.bridge
桥接网络是在网络段之间转发流量的链路层设备。网桥可以是硬件设备或在主机内核中运行的软件设备。
就Docker而言,桥接网络使用软件桥,该桥接器允许连接到同一桥接网络的容器进行通信,同时提供与未连接到该桥接网络的容器的隔离。Docker桥驱动程序自动在主机中安装规则,以便不同网桥上的容器无法直接相互通信。
[root@master song]# docker run -d --name nginx nginx:alpine 0cfd6bb68ece619b380535abd9f6253bb6dd00a5914d0eee86ef7a18895e834f [root@master song]# docker run -d --link nginx --name nginx2 nginx:alpine 6e4f412da94f3a508cc208995fc7a688795e6e10e064585ea8d370e355e3d433[root@master song]# docker exec -i -t nginx2 /bin/sh/ # netstat -tnlpuActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro/ # cat /etc/hosts127.0.0.1 localhost::1 localhost ip6-localhost ip6-loopbackfe00::0 ip6-localnetff00::0 ip6-mcastprefixff02::1 ip6-allnodesff02::2 ip6-allrouters172.17.0.2 nginx 0cfd6bb68ece172.17.0.3 6e4f412da94f/ # ip a1: lo:mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever13203: eth0@if13204: mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever 如果是不同桥连网卡间的通信会是什么样
[root@master song]# docker network list
NETWORK ID NAME DRIVER SCOPE5f82f4364995 bridge bridge local0ef8c736b0dd host host localdd52f3711ec1 none null local[root@master song]# docker network create song973161700d443a877e4395ba50a4b81b7175dc5f043a4e89dbe1b58bfbd8db09[root@master song]# docker network listNETWORK ID NAME DRIVER SCOPE5f82f4364995 bridge bridge local0ef8c736b0dd host host localdd52f3711ec1 none null local973161700d44 song bridge local
通信是中断的 包可以过去但是回来的路是找不到的
5. overlay
网络解决跨主机通信
该overlay
网络驱动程序会创建多个码头工人守护主机之间的分布式网络。该网络位于(覆盖)特定于主机的网络之上,允许连接到它的容器(包括群集服务容器)安全地进行通信。Docker透明地处理每个数据包与正确的Docker守护程序主机和正确的目标容器的路由。
-
使用覆盖网络的Docker守护程序的防火墙规则
您需要以下端口打开来往于覆盖网络上参与的每个Docker主机的流量:
- 用于集群管理通信的TCP端口2377
- TCP和UDP端口7946用于节点之间的通信
- UDP端口4789用于覆盖网络流量
-
在创建覆盖网络之前,您需要将Docker守护程序初始化为群集管理器,
docker swarm init
或者使用它将其连接到现有群集docker swarm join
。这些中的任何一个都会创建默认ingress
覆盖网络,默认情况下 由群服务使用。即使您从未计划使用群组服务,也需要执行此操作。之后,您可以创建其他用户定义的覆盖网络,。
不做演示。
最后献上flannel 通信原理