本篇文章使用nginx:apline 镜像进行编辑。
docker 版本基于
[root@master song]# docker version
Client:
Version: 18.09.
API version: 1.39
Go version: go1.10.6
Git commit:
Built: Sun Feb ::
OS/Arch: linux/amd64
Experimental: false Server: Docker Engine - Community
Engine:
Version: 18.09.
API version: 1.39 (minimum version 1.12)
Go version: go1.10.6
Git commit:
Built: Sun Feb ::
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:alpine
186938ec427789522267eaec0f865dc7ae0427dd5552a11b249cba6d0b86cc67
[root@master song]# netstat -tnlup |grep
tcp 172.20.0.91: 0.0.0.0:* LISTEN /etcd
tcp 0.0.0.0: 0.0.0.0:* LISTEN /nginx: master
tcp6 ::: :::* LISTEN /kube-proxy
[root@master song]# ps -ef |grep
root : ? :: nginx: master process nginx -g daemon off;
: ? :: nginx: worker process
root : pts/ :: grep --color=auto
[root@master song]# ps -ef |grep
root : ? :: 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-runc
root : ? :: nginx: master process nginx -g daemon off;
root : pts/ :: grep --color=auto 10496 此时容器开发的80端口和主机直接启动nginx的不同点仅仅为主进程号不同
进入容器关闭 nginx服务再查看端口
[root@master song]# docker exec -it nginx /bin/sh
/ # nginx -s stop
2019/03/05 14:45:34 [notice] 13#13: signal process started
/ # [root@master song]#
[root@master song]# netstat -tnlup |grep 80
tcp 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 10496
root 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 a
: lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state UNKNOWN qlen
link/loopback ::::: brd :::::
inet 127.0.0.1/ scope host lo
valid_lft forever preferred_lft forever
: eth0@if13176: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu qdisc noqueue state UP
link/ether ::ac::: brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/ brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ # netstat -tnlup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0.0.0.0: 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 a
: lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state UNKNOWN qlen
link/loopback ::::: brd :::::
inet 127.0.0.1/ scope host lo
valid_lft forever preferred_lft forever
/ # netstat -tnlup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0.0.0.0: 0.0.0.0:* LISTEN /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 -tnlpu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0.0.0.0: 0.0.0.0:* LISTEN /nginx: master pro
/ # cat /etc/hosts
127.0.0.1 localhost
:: localhost ip6-localhost ip6-loopback
fe00:: ip6-localnet
ff00:: ip6-mcastprefix
ff02:: ip6-allnodes
ff02:: ip6-allrouters
172.17.0.2 nginx 0cfd6bb68ece
172.17.0.3 6e4f412da94f
/ # ip a
: lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state UNKNOWN qlen
link/loopback ::::: brd :::::
inet 127.0.0.1/ scope host lo
valid_lft forever preferred_lft forever
: eth0@if13204: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu qdisc noqueue state UP
link/ether ::ac::: brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/ brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever 如果是不同桥连网卡间的通信会是什么样
[root@master song]# docker network list
NETWORK ID NAME DRIVER SCOPE
5f82f4364995 bridge bridge local
0ef8c736b0dd host host local
dd52f3711ec1 none null local
[root@master song]# docker network create song
973161700d443a877e4395ba50a4b81b7175dc5f043a4e89dbe1b58bfbd8db09
[root@master song]# docker network list
NETWORK ID NAME DRIVER SCOPE
5f82f4364995 bridge bridge local
0ef8c736b0dd host host local
dd52f3711ec1 none null local
973161700d44 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 通信原理