docker网络类型介绍

docker基础网络

实现原理

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

四类网络模式

docker网络模式 配置 说明
host模式 -net=host 容器与宿主机共享network namespace
container模式 -net=container:NAME_or_ID 容器和另外一个容器共享network namespace。kubernetes中的pod 就是多个容器共享一个network namespace
none模式 -net=none 容器有独立的network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥离连接,配置IP等。
bridge模式 -net=bridge (默认为该模式)

host模式

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

使用host模式的容器可以使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

host模式示意图:

实例演示:

#创建一个容器加host网络
docker run  -it --network=host alpine:v1 /bin/sh
/ # hostname
docker01    <--主机名
/ # cat /etc/hosts   <--宿主机的hosts文件
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
docker01 10.0.0.11
docker02 10.0.0.12
/ # ip a  <--宿主机的ip地址

container模式

指定新创建的容器和已经存才的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统,进程列表还是隔离的。两个容器的进行可以通过lo网卡设备通信。

container模式示意图:

实例演示:

docker run -it --network container:clever_carson /bin/sh
/ # ip a  <--与别的主机共用一个网络
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
456: eth0@if457: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

none模式

使用none模式,Docker容器拥有自己的Network Namespace,但是并不为docker容器进行任何网络配置。也就是说,这个docker容器没有网卡、IP、路由等信息。需要我们自己为docker容器添加网卡、配置IP等。

这样网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法连网,封闭的网络能很好的保证容器的安全性。

None模式示意图:

实例演示:

docker run -it --network none alpine:v1 /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever <--没有网卡

bridge(桥接)模式

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

从docker0子网中分配一个ip给容器使用,并设置docker的IP地址为容器的默认网关。在关机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show查看。

bridge模式是docker的默认模式,不写-net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转换功能。可以使用iptables -t net -vnL 查看。

桥架网络示意图:

自定义网络

#自定义一个网络
docker network create  -d bridge --gateway 172.19.0.1 --subnet 172.19.0.0/16 class
# 查看网络列表
docker network ls
eb5611ce0e24        class               bridge              local

#容器使用自定义网络
docker run -d -p 81:80  --network class alpine_kod:v3 /bin/sh /init.sh
#查看类型
docker inspect 82aee49 |  grep   Network
            "NetworkMode": "class",
        "NetworkSettings": {
            "Networks": {
                    "NetworkID": "eb5611ce0e24c93301ddbd18c9cc2d9c54943119fc9a8ba0b8a9590df7804bb7",

dockers网络扩展

跨主机通信---macvlan

介绍:macvlan本身是linux kernel模块,其功能是允许在同一物理网卡上配置多个MAC地址,即多个interface,每个interface可以配置自己的IP,mavvlan本质是一种网卡虚拟化技术。

macvlan类似于虚拟机的桥接网络

  1. 跨宿主机通信(ping不同宿主机)

  2. 需要手动管理ip分配

  3. 不需要端口映射就能被外界访问

注:macvlan最大特点ip地址需要手动添加

# 创建网络
docker network create  -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254  -o parent=eth0 macvlan_1
# 参数说明
-d:网络类型(macvlan)
--subnet:指定子网范围
--gateway:宿主机网关
-o parent=eth0:基于哪个网卡创建
macvlan_1:网卡名称

# 查看
docker network ls

使用macvlan模式创建容器:

#docker01
docker run -it --network  macvlan_1  --ip 10.0.0.88 alpine:v1
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
481: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN 
    link/ether 02:42:0a:00:00:58 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.88/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever

       
#docker02
docker run -it --netwrok macvlan_1 --ip 10.0.0.99 alpine:v1
/ # ip addr 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
19: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN 
    link/ether 02:42:0a:00:00:63 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.99/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever

注:这里即可以互相ping通而且还可以ping百度

跨主机通信---overlay

1. 介绍:

Overlay是指基于VXLAN封装实现Docker原生Overlay网络,在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文协议在IP报之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发;而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制支持高达16M的用户,并在必要时可将广播流量转发为组播流量,避免广播数据泛滥。

原理图:

因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案

2. 要想使用Docker源生Overlay网络,需要满足下列任意条件:

  • Docker运行在Swarm

  • 使用键值存储的Docker主机集群

3. 使用键值存储搭建docker主机集群

需要满足下列条件:

  • 集群中主机连接到键值存储,Docker支持 Consul,Etcd和Zookeeper

  • 集群中运行一个Docker守护进程

  • 集群中主机必须具有唯一的主机名,因为键值存储使用主机名来标识集群成员、

  • 集群中Linux主机内核版本在3.12+,支持VXLAN数据报处理,否则可能无法通行

4. 实验

主机名 ip地址 kernel
docker01 10.0.0.11 3.10.0-957.el7.x86_64
docker02 10.0.0.12 3.10.0-957.el7.x86_64
docker03 10.0.0.13 3.10.0-957.el7.x86_64

注:我们这里实验使用的是Consul

#docker03主机
[root@docker03 ~]# docker pull progrium/consul  <---拉取镜像
[root@docker03 ~]# docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap
登录:10.0.0.13:8500

#docker01和02主机
vim /etc/docker/daemon.json
8        "insecure-registries": ["10.0.0.11:5000","10.0.0.12"],
9        "cluster-store": "consul://10.0.0.13:8500", #集群信息存储在consul上
10        "cluster-advertise": "10.0.0.11:2376" #节点自己的信息

效果图:

测试跨主机实例:

#docker01创建容器
docker run -it  --network ol1 --name class1 alpine:latest

#docker02创建容器
docker run -it --network ol1   --name class2 alpine:lstest
之间互相ping容器名字互通
ping class1
PING class1 (172.31.0.2): 56 data bytes
64 bytes from 172.31.0.2: seq=0 ttl=64 time=0.370 ms
64 bytes from 172.31.0.2: seq=1 ttl=64 time=0.722 ms

ping class2
PING class2 (172.31.0.3): 56 data bytes
64 bytes from 172.31.0.3: seq=0 ttl=64 time=0.547 ms
64 bytes from 172.31.0.3: seq=1 ttl=64 time=0.675 ms

 使用端口映射访问:

#docker01
docker run  -d -p 80:80 --network ol1  --name kod01  alpine_kod:v3
#docker02
docker run  -d -p 80:80 --network ol1  --name kod02  alpine_kod:v3

之间相互ping
原文地址:https://www.cnblogs.com/Mercury-linux/p/12725683.html