docker网络

1. 简介

容器网络实质上是由 Docker 为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP 路由表、防火墙等与网络相关的模块

 CNM

Container Network Model,它是 Docker 网络架构采用的设计规范。只要符合该模型的网络接口就能被用于容器之间通信,而通信的过程和细节可以完全由网络接口来实现。

CNM 的网络组成

1. Sandbox: 提供容器的虚拟网络栈,即端口套接字,IP路由表、iptables配置,DNS等。用于隔离容器网络和宿主机网络

2.Network: Docker 虚拟网络,与宿主机网络隔离,只有参与者能够通信

3.Endpoint: 容器内的虚拟网络接口,负责与Docker虚拟网络连接

 Libnetwork

CNM 的标准实现,由Golang开发,它实现了CNM定义的全部三个组件,还实现了本地服务发现,基于 Ingress 的容器负载均衡,及网络控制层和管理层功能

 网络驱动

1.宿主机内部:bridge,host,container,none

2.跨主机:overlay,macvlan (适合swarm等容器编排工具)

3.第三方:flannel,weave,calico
 

 支撑技术

network namespace:用于隔离容器网络资源(IP、网卡、路由等)。netns可确保同一主机上的两个容器无法相互通信,甚至不能与主机本身进行通信,除非配置为通过docker网络进行通信。CNM网络驱动程序为每个容器实现单独的netns。但是,容器可以共享相同的netns,甚至可以是主机的netns的一部分。
 

veth pair:用于不同 netns 间进行通信。veth是全双工链接,在每个名称空间中都有一个接口,充当两个网络名称空间之间的连接线,负责将一个 netns 数据发往另一个 netns 的 veth。如当容器连接到docker网络时,veth的一端放置在容器内部(通常视为ethX接口),而另一端连接到Docker网络(vethxxx)。

iptables:包过滤,端口映射和负载均衡

Docker 网络实现原理

Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信
 

Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过Container-IP访问到容器,如果容器不希望外部能够访问到可以通过映射容器端口到宿主主机(端口映射), 即docker run创建容器时候通过-p或-P参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器
 

docker run -d --name gb -P soscscs/myapp:v1   
#随机映射端口(从32768开始)

docker run -d --name test2 -p 4888:80 hf123456789/nginx:huo  
#自定义映射端口

查看docker网络列表

docker network ls 或 docker network list   

使用docker run 创建容器时们可以使用net或–network选项指定容器的网络模式

host模式:使用--net=host指定

none模式:使用--net--none指定

container模式:使用--net=container:NAME_or_ID指定

bridge模式:使用--nrt+bridge指定,默认设置可省略

总结

1.用的是宿主机的网络命名空间,所以他们的端口范围是共享的,相互之间是不能够重复的,ip地址用的是宿主机的IP地址没有独立IP地址

2.容器用的是宿主机的IP地址,端口号用的是宿主机的端口范围,如果80号端口宿主机用了,容器就不会再用了,把容器暴露在宿主机当中

container模式

1.这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP,端口范围等。可以在一定程度上节省网络资源,容器内部依然不会拥有所有端口。

2.同样,两个容器除了网络方面,其他的如文件系统,进程列表等还是隔离的

3.两个容器的进程可以通过lo网卡设备通信

docker inspect -f '{{.State.Pid}}' 容器id号  #查看容器进程号
ll /proc/容器进程号/ns     #查看命名空间编号

none模式

1.使用none 模式,docker 容器有自己的network Namespace ,但是并不为Docker 容器进行任何网络配置。也就是说,这个Docker 容器没有网卡,ip, 路由等信息。

2.这种网络模式下,容器只有lo 回环网络,没有其他网卡。

3.这种类型没有办法联网,封闭的网络能很好的保证容器的安全性

4.该容器将完全独立于网络,用户可以根据需要为容器添加网卡。此模式拥有所有端口。(none网络模式配置网络)
 

bridge 模式

1.相当于Vmware中的 nat 模式,容器使用独立network Namespace,并连接到docker0虚拟网卡。通过docker0网桥以及iptables nat表配置与宿主机通信,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。

2.当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

3.从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。

4.Docker将veth pair 设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中, 以veth*这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过 brctl show 命令查看。

5.使用 docker run -p 时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL 查看。
 

自定义网络

ifcongfig
#直接使用bridge模式,是无法支持指定IP运行docker的,例如执行以下命令就会报错
 docker run -id --name test4 --network bridge --ip 172.17.0.10 centos7:test3 
/bin/bash

创建自定义网络
#可以先自定义网络,再使用指定IP运行docker 
docker network create--subnet-172.18.0.0/16 -- opt"com.docker.network.bridge.name"="docker1" mynetwork

------------------

#docker1为执行ifconfig -a命令时,显示的网卡名,如果不使用--opt参数指定此名称,那你在使用ifconfig -a命令查看网络信息时,看到的是类似br-110eb56a0b22这样的名字,这显然不怎么好记。

#mynetwork 为执行 docker network list 命令时,显示的bridge网络模式名称。
------------------

docker run -itd --name test5 --network mynetwork --ip 172.18.0.10 nginx:latest /bin/bash
docker inspect test5 |grep IPAddress
#查看ip地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值