Docker 网络

容器的三种本地网络

none 网络

故名思议,none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,可以通过 --network=none 指定使用 none 网络。

docker network none

host 网络

连接到 host 网络的容器共享 Docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host 指定使用 host 网络。使用 host 网络,容器和宿主机共用 host 网络,当启动服务时应该避免端口冲突。

docker network host

Bridge 网络

Docker 安装时会创建一个命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上。

docker network bridge

Bridge 网络拓扑: Docker Daemon启动后默认创建 docker0 网桥,起初 docker0 启动时网桥上没有任何端口,当启动容器后,docker0 网桥上也创建了一个端口,他跟容器内的 eth0 网卡形成一个 veth pair。

docker network bridge

Docker 桥接网络拓扑图如下:

docker network bridge

自定义容器网络

  1. docker network create --driver=bridge --subnet=172.88.0.0/16 net1
  2. docker run -tid --name box --network=net1 busybox

docker network create

通过如上命令可以自定义网络,使用新建网络启动容器后,同样会创建一个 veth pair 与新网桥联通。

我想让box容器(自定义网络 net1)和httpd容器(默认网络 docker0)通信该怎么弄?

在 box 里 ping httpd 容器 ip 不通,这是因为 Docker 默认是隔离所有网络之间的通信的

docker network isolation

为了能够通信只需要给 box 容器添加 docker0 网络

docker network connect

net1 与 docker0 网络拓扑:

docker network

多主机网络

为了支持跨主机间的容器通信,Docker 支持多种跨主机网络。

Docker原生网络方案:

  • overlay
  • macvlan

第三方网络方案:

  • Flannel
  • Weave
  • Calico

配置Overlay网络

Docerk overlay 网络需要一个 key-value 数据库用于保存网络状态信息,包括 Network、Endpoint、IP 等。Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 软件,我们这里使用 Consul。

1、部署Consul

  1. docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap

2、接下来修改 host1 和 host2 的 docker daemon 的配置文件/etc/systemd/system/docker.service.d/10-machine.conf —registry-mirror=https://m9sl8pb5.mirror.aliyuncs.com —cluster-store=consul://192.168.115.20:8500 —cluster-advertise=ens3:2376 —cluster-store 指定 consul 的地址—cluster-advertise 告知 consul 自己的连接地址

  1. systemctl daemon-reload
  2. systemctl restart docker.service

3、创建 overlay 网络 ov_net1

  1. docker network create -d overlay ov_net1

4、在 host1 和 host2 上分别启动容器

  1. docker run -tid --name box1 --network=ov_net1 busybox
  2. docker run -tid --name box2 --network=ov_net1 busybox

5、联通性测试

  1. docker exec -ti box2 sh
  2. ping 10.0.0.2

Overlay网络连通性

docker 会为每个 overlay 网络创建一个独立的 network namespace,其中会有一个 linux bridge br0,endpoint 还是由 veth pair 实现,一端连接到容器中(即 eth0),另一端连接到 namespace 的 br0 上。

br0 除了连接所有的 endpoint,还会连接一个 vxlan 设备,用于与其他 host 建立 vxlan tunnel。容器之间的数据就是通过这个 tunnel 通信的。逻辑网络拓扑结构如图所示:

docker network

容器的通信机制

容器访问外部世界

a、busybox 发送 ping 包:172.17.0.2 > www.bing.com

b、docker0 收到包,发现是发送到外网的,交给 NAT 处理

c、NAT 将源地址换成 enp0s3 的 IP:10.0.2.15 > www.bing.com

d、ping 包从 enp0s3 发送出去,到达 www.bing.com

外部世界访问容器

外部网络通过端口映射访问到容器服务,将容器的80端口映射到宿主机的32773端口

  1. docker run -tid --name httpd -p 32773:80 httpd

a、docker-proxy 监听 host 的 32773 端口

b、当 curl 访问 10.0.2.15:32773 时,docker-proxy 转发给容器 172.17.0.2:80

c、httpd 容器响应请求并返回结果

docker network