docker-网络

1 docker网络和容器的通信

1.1 docker网络通信的基本原理

Docker中的网络接口默认都是虚拟的接口。虚拟接口的最大优势 就是转发效率极高。这是因为Linux通过在内核中进行数据复制来 实现虚拟接口之间的数据转发,即发送接口的发送缓存中的数据 包将被直接复制到接收接口的接收缓存中,而无需通过外部物理 网络设备进行交换。对于本地系统和容器内系统来看,虚拟接口 跟一个正常的以太网卡相比并无区别,只是它速度要快得多
Docker容器网络就很好地利用了Linux虚拟网络技术,在本地主机 和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一 对接口叫做veth pair)。

1.2 docker默认网络模式bridge模式

docker run -it centos:7 /bin/bash

进入到容器以后,

yum install -y net-tools && ifconfig
创建一对虚拟接口,分别放到本地主机和新容器的命名空间中;
本地主机一端的虚拟接口连接到默认的docker0网桥或指定网桥上,并具 有一个以veth开头的唯一名字,如veth1234;
容器一端的虚拟接口将放到新创建的容器中,并修改名字作为eth0。这 个接口只在容器的命名空间可见;
从网桥可用地址段中获取一个空闲地址分配给容器的eth0(例如 172.17.0.2/16),并配置默认路由网关为docker0网卡的内部接口docker0 的IP地址(例如172.17.42.1/16)。

1.2 docker的网络模式

安装docker的时候, 它会自动创建四个网络, host, container, bridge, none,

host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机 的IP和端口。
实例:

 docker run -it --rm --net=host centos bash

Container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围
实例:

其中:d8c0a1aa2673是另一个容器的ID
  
docker run -it --network=container:d8c0a1aa2673 busybox /bin/sh
         
eth0     Link encap:Ethernet HWaddr 02:42:AC:11:00:02  
 inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0

None:该模式关闭了容器的网络功能。

docker run -it --rm --net=none  centos_nat bash

Bridge:此模式会为每一个容器分配、设置IP等,并将容器连接到一个 docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。
插件网络
实例:

 docker run -it busybox /bin/sh   ---> 使用bridge的模式
                   
eth0     Link encap:Ethernet HWaddr 02:42:AC:11:00:02  
 inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0

以上五种驱动都是docker原生提供的,如果以上五种不能满足你的要求,除了原生提供,还支持第三方的驱动模式接入。比如常用的 flannel、pipework、weave 和 calico 等等。

2 docker network管理命令

2.1 显示网络列表

docker networkd ls

2.2 创建网络

docker network create <Option> <NetworkName>
## 可选参数
--config-from 复制其他网络配置
--driver 指定网络模式
--gateway 指定网关
--internal 限制只能内部访问
--ip-range 从子网范围分配容器IP
--ipv6 启用IPv6网络
--subnet 指定网段

示例:
docker network create centos-network

2.3 配置容器连接到指定的网络

docker network connect

2.4 取消容器连接到指定的网络

docker network disconnect

2.5 查看网络详情

docker network inspect

2.6 删除网络

docker network rm
示例
docker network rm centos-network

2.7 清理未使用的网络

docker network prune

2.8 启动容器指定网络

docker run -it --network=

2.9 自定义bridge模式

创建network
docker network create -d bridge --ip-range=192.168.1.0/24 --gateway=192.168.1.1 --subnet=192.168.1.0/24 bridge2
创建一个容器指定ip并指定network
docker run -it --network=bridge2 --ip=192.168.1.3
docker run -it --network=bridge2 --ip=192.168.1.4

3 容器间的通信

容器间可以通过IP, Docker DNS Server和joined容器三种方式

3.1 IP通信

两个容器要能通信,必须要有属于同一个网络的网卡。满足这个 条件后,容器就可以通过 IP 交互了。具体做法是在容器创建时通 过 --network 指定相应的网络,或者通过 docker network connect 将现有容器加入到指定网络。
例如上面的ip: 192.168.1.3和192.168.1.4两个容器通信
3.2 Docker DNS Server
通过 IP 访问容器虽然满足了通信的需求,但还是不够灵活。因为我们在部 署应用之前可能无法确定 IP,部署之后再指定要访问的 IP 会比较麻烦。对 于这个问题,可以通过 docker 自带的 DNS 服务解决。
从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使 容器可以直接通过"容器名"通信。方法很简单,只要在启动时用 --name 为 容器命名就可以了。
我们修改上面的两条语句,如下:

docker run -it --network=bridge2 --name box1 busybox
docker run -it --network=bridge2 --name box2 busybox

使用 docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认 的 bridge 网络是无法使用 DNS 的。

3.3 Joined容器

joined 容器是另一种实现容器间通信的方式。它可以使两个或多 个容器共享一个网络栈,共享网卡和配置信息,joined 容器之间 可以通过 127.0.0.1 直接通信

(*)基于httpd的镜像创建容器

docker run -it --name box3 httpd

(*)使用Joined容器创建一个新的容器
   docker run -it --network=container:box3 busybox

(*)测试:在第二个容器中执行wget 127.0.0.1

4 容器访问控制

容器的访问控制主要通过Linux上的iptables防火墙软件来进行管理 和实现。iptables是Linux系统流行的防火墙软件,在大部分发行版 中都自带。

4.1 容器访问外部网络

我们知道容器默认指定了网关为docker0网桥上的docker0内部接口。docker0 内部接口同时也是宿主机的一个本地接口。因此,容器默认情况下是可以访 问到宿主机本地的。更进一步,容器要想通过宿主机访问到外部网络,需要 宿主机进行转发
如果为0,则没有开启转发,则需要手动打开:
sysctl -w net.ipv4.ip_forward=1
更简单的,在启动Docker服务的时候设定--ip-forward=true,Docker服务会自 动打开宿主机系统的转发服务。

4.2 外部访问容器实现

容器允许外部访问,可以在docker run时候通过-p或-P参数来启用。不管用那种办法,其实也是在本地的iptable的nat表中添加相应的 规则,将访问外部IP地址的网包进行目标地址DNAT,将目标地址 修改为容器的IP地址。
例如:以一个开放80端口的Web容器为例
docker run -it -p 80:80 centos bash
代表包容器里的80端口映射到宿主机的80端口
docker run -it -P centos bash

-P 代表是随机生成一个端口,在宿主机上
在主机上,通过iptables -nvL命令来查看

posted @ 2020-04-16 12:34  huningfei  阅读(163)  评论(0)    收藏  举报
levels of contents