2.docker的网络模式

时间:2022-01-17 08:09:18

本篇文章使用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 通信原理

2.docker的网络模式