layout: post
title: Docker网络
date: 2018-04-21
tags: [“Docker”,”自动化运维工具”]


一、docker网络名称空间原理。

docker的网络与内核的名称空间有关,每一个docker容器彼此之间拥有不同的名称空间,而对于宿主机的TCP/IP协议栈来说,docker容器的网络实际是宿主机TCP/IP协议栈的一部分。docker使用与宿主不同的网络名称空间,通过虚拟网卡来实现与主机进行桥接的。

为了更好的理解docker网络的名称空间,下面我会做网络名称空间的实际例子。

二、netns网络虚拟化

netns是在linux中提供网络虚拟化的一个项目,使用netns网络空间虚拟化可以在本地虚拟化出多个网络环境,目前netns在lxc容器中被用来为容器提供网络,其原理与docker是同样的。

使用netns创建的网络空间独立于当前系统的网络空间,其中的网络设备以及iptables规则等都是独立的,就好像进入了另外一个网络一样。

每一个网卡接口都只能够在一个名称空间中工作,我们可以使用虚拟以太网卡对不同的网络名称空间进行桥接。

下面我们使用”ip”命令来构建一个独立的网络名称空间,并使之与默认的网络名称空间进行通信。

1、环境准备

  1. yum install -y briage-utils

2、使用ip命令创建一个新的网络名称空间

  1. ip help #获取ip命令帮助
  2. ip netns help #获取网络名称空间帮助
  3. ip netns add mynetspace #创建一个新的网络名称空间
  4. ip netns exec mynetspace ifconfig -a #在mynetspace挽留过名称空间中执行命令
  5. lo: flags=8<LOOPBACK> mtu 65536
  6. loop txqueuelen 1 (Local Loopback)
  7. RX packets 0 bytes 0 (0.0 B)
  8. RX errors 0 dropped 0 overruns 0 frame 0
  9. TX packets 0 bytes 0 (0.0 B)
  10. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

3、创建虚拟网卡

  1. ip link add vethx type veth peer name veth0 #创建一对虚拟网卡(其中vethx与vethy是对等的,就相当于一个虚拟网卡的两部分)
  2. ip link set veth0 netns mynetspace #讲vethy放入 mynetspace 网络名称空间中
  1. ip netns exec mynetspace ifconfig -a
  2. lo: flags=8<LOOPBACK> mtu 65536
  3. loop txqueuelen 1 (Local Loopback)
  4. RX packets 0 bytes 0 (0.0 B)
  5. RX errors 0 dropped 0 overruns 0 frame 0
  6. TX packets 0 bytes 0 (0.0 B)
  7. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
  8. veth0: flags=4098<BROADCAST,MULTICAST> mtu 1500
  9. ether 02:7e:99:4a:63:19 txqueuelen 1000 (Ethernet)
  10. RX packets 0 bytes 0 (0.0 B)
  11. RX errors 0 dropped 0 overruns 0 frame 0
  12. TX packets 0 bytes 0 (0.0 B)
  13. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

4、将vethx和docker0进行桥接(已经安装了docker)

  1. brctl addif docker0 vethx
  2. brctl show
  1. bridge name bridge id STP enabled interfaces
  2. docker0 8000.024271e0ef26 no vethx

5、为veth0配置ip地址并ping docker0

  1. ip netns exec mynetspace ifconfig veth0 172.17.0.10/16 up
  2. ip netns exec mynetspace ifconfig lo 172.17.0.10/16 up
  3. ip netns exec mynetspace ping 172.17.0.1
  4. PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
  5. 64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.122 ms
  6. 64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.110 ms
  7. 64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=0.048 ms
  8. ^C
  9. --- 172.17.0.1 ping statistics ---
  10. 3 packets transmitted, 3 received, 0% packet loss, time 1999ms
  11. rtt min/avg/max/mdev = 0.048/0.093/0.122/0.033 ms

6、删除虚拟空间

  1. ip netns del mynetspace #删除网络名称空间
  2. 注意:这时我们所创建的虚拟以太网卡已经消失了,vethx veth0 是秤和砣的关系,相互依存。

注意:默认的docker的网卡接口一半在容器内,而另一半则关联到了docker0桥上。

三、docker的网络模型

1、封闭式网络模型(容器内只有一个lo设备,不能与其他网络名称空间进行通信)

2、桥接式网络模型,容器内拥有网络接口并桥街道docker0桥(默认,且常用,DNAT)

3、联合式网络模型,多个容器共用同一个网络名称空间,容器与容器之间可以使用lo进行内部通信,从而实现了IPC(只用网络名称空间是共享的,其他的则不共享)

4、开放式网络模型,直接使用宿主机的网络名称空间(例,一个运行着nginx的docker容器,其使用的开放式网络模型,当有请求访问宿主机的80端口,而做出响应的实际是运行nginx的docker容器,使用这种网络模型可以实现快速的分发和启动,但当使用单个应用程序时则不建议使用这种模型,因为容器与宿主机隔离的越彻底越好)

四、docker的4种网络模型实现

使用桥网络运行容器:

  1. docker run -itd --name c1 --rm --network bridge nginx:1.12-alpine

使用无网络运行容器:

  1. docker run -itd --name c2 --rm --network none nginx:1.12-alpine

使用开放式网络运行容器:

  1. docker run -itd --name c3 --rm --network host nginx:1.12-alpine #此种方式运行的容器,容器内的应用所监听的端口会直接在宿主机上进行监听。

使用联合式网络运行容器:

  1. docker run -itd --name c4 --rm --network bridge nginx:1.12-alpine #联合式网络需要使用bridge模型来运行
  2. 815b7c86382e81a148de94535135fed1a51144334895aa6d7fa3ba80a61f3d51
  3. docker run -itd --name c5 --rm --network container:c4 tetraweb/php #固定格式, 和名称为c4的容器共用一个网络名称空间
  4. c5592c273c8a79982692c7878d37ba27f3c88b565808a7b492b80f4c4ebdb3e6

五、docker运行与主机端口的映射

  1. -p 选项的使用格式
  2. -p <containerPort> # 将指定的容器端口映射至主机所有地址的一个动态端口
  3. -p <hostPort>:<containerPort> # 将容器端口 <containerPort> 映射至指定的主机端口 <hostPort>
  4. -p <ip>::<containerPort> # 将指定的容器端口 <containerPort> 映射至主机指定 <ip> 的动态端口
  5. -p <ip>:<hostPort>:<containerPort> # 将指定的容器端口 <containerPort> 映射至主机指定 <ip> 的端口 <hostPort>
  6. " 动态端口" 指随机端口,具体的映射结果可使用 docker port 命令查看

 

文档更新时间: 2020-03-27 13:42   作者:张尚