Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)

一、Docker的原生网络

docker network   子命令

connect         连接容器到指定网络

create            创建网络

disconnect     断开容器与指定网络的连接

inspect           显示指定网络的详细信息

ls                    显示所有网络

rm                  删除网络

首先需要清理实验环境Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第1张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第2张图片

docker-compose up #启动所有服务 

docker-compose stop  #停止正在运行的容器,可以通过docker-compose start 再次启动

docker-compose down #停止和删除容器、网络、卷、镜像。(#停用移除所有容器以及网络相关)

 docker安装后会自动创建3种网络:bridge(桥接)、host(主机网络)、none(禁用)

1、docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器会自动桥接到这个接口。Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第3张图片

[root@server1 ~]# yum install -y bridge-utils 安装网桥管理工具包 (brctl show     查询网桥信息)容器网络以桥接的方式桥接到宿主机上

[root@server1 ~]# docker inspect demo 可以看到容器的网关就是宿主机的桥接Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第4张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第5张图片 172.17是所有容器的地址 0.1是网关 其他容器ip地址是动态分配以单调递增的方式来进行分配 被占用则不能用 如果容器停止它所占用的ip将释放出来给其他的容器 由于此机制 容器重启之后与原来的ip地址不一样      

bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的。容器通过虚拟网卡veth数据包到达docker0网桥在由linux内核数据包路由到eth0出去Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第6张图片

2、host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。

host网络模式需要在容器创建时指定 --network=host 

[root@server1 ~]# docker run -d --name demo --network host nginx
a206df944a2a453a61b447cfb765d5e088f5e2cbfb76c8f6fb788ef8dfee52cc
[root@server1 ~]# brctl show   查询网桥信息 没有桥接
bridge name    bridge id        STP enabled    interfaces
docker0        8000.0242258ffab5    no        
[root@server1 ~]# ip addr    没有新建网络
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default 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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:81:ab:94 brd ff:ff:ff:ff:ff:ff
    inet 172.25.15.1/24 brd 172.25.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe81:ab94/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:25:8f:fa:b5 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:25ff:fe8f:fab5/64 scope link
       valid_lft forever preferred_lft forever

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第7张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第8张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第9张图片

[root@server1 ~]# systemctl status nginx  没有开nginx
● nginx.service - The NGINX HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: inactive (dead) 

3、none模式是指禁用网络功能,只有lo接口,在容器创建时使用    --network=none指定。Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第10张图片

[root@server1 ~]# docker inspect demo | grep Pid 创建容器时容器会有自己的id
            "Pid": 16354,
            "PidMode": "",
            "PidsLimit": null,

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第11张图片

/ns/(namespace)目录下有demo容器的6种命名空间 demo容器基本上作为独立的主机存在  容器在运行时通过这6种命名空间相对安全做了隔离 没有完全隔离很多东西和宿主机共享

清理实验环境

[root@server1 ns]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
12fd840f32fd   bridge    bridge    local
cec1ef142c8c   host      host      local
4e5caf1b11f4   none      null      local
[root@server1 ns]# docker rm -f demo
demo

二、Docker自定义网络

自定义网络模式,docker提供了三种自定义网络驱动: bridge overlay macvlan

bridge驱动类似默认的bridge网络模式,但增加了一些新的功能, overlay和macvlan是用于创建跨主机网络。

[root@server1 ns]# docker network create mynet1
95c68a27938578f4a7bb61e0bd4c5e934eb2470b8e317eaa2816d43391dd1f02
[root@server1 ns]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
12fd840f32fd   bridge    bridge    local
cec1ef142c8c   host      host      local
95c68a279385   mynet1    bridge    local
4e5caf1b11f4   none      null      local

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第12张图片

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第13张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第14张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第15张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第16张图片

[root@server1 ns]# docker run -it --rm --network mynet1 busybox
/ # ping demo1
PING demo1 (172.23.0.2): 56 data bytes
64 bytes from 172.23.0.2: seq=0 ttl=64 time=0.112 ms
64 bytes from 172.23.0.2: seq=1 ttl=64 time=0.080 ms
^C
--- demo1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.080/0.096/0.112 ms
/ #

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第17张图片

[root@server1 ns]# docker run -it --rm --network mynet1 busybox
/ # ping demo1
PING demo1 (172.23.0.3): 56 data bytes
64 bytes from 172.23.0.3: seq=0 ttl=64 time=0.097 ms
64 bytes from 172.23.0.3: seq=1 ttl=64 time=0.083 ms
64 bytes from 172.23.0.3: seq=2 ttl=64 time=0.082 ms

64 bytes from 172.23.0.3: seq=3 ttl=64 time=0.081 ms
^C
--- demo1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.081/0.085/0.097 ms
/ # ping demo2
PING demo2 (172.23.0.2): 56 data bytes
64 bytes from 172.23.0.2: seq=0 ttl=64 time=0.132 ms
64 bytes from 172.23.0.2: seq=1 ttl=64 time=0.080 ms
^C
--- demo2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.080/0.106/0.132 ms
/ #

docker自定义网段在创建时指定参数:--subnet 、--gateway

使用--ip参数可以指定容器ip地址,但必须是在自定义网桥上,默认的bridge模式不支持,同一网桥上的容器是可以互通的。

[root@server1 ns]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
12fd840f32fd   bridge    bridge    local
cec1ef142c8c   host      host      local
95c68a279385   mynet1    bridge    local
4e5caf1b11f4   none      null      local
[root@server1 ns]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
4ff0f3e84bf3   nginx     "/docker-entrypoint.…"   13 minutes ago   Up 13 minutes   80/tcp    demo2
6effdb7ac322   nginx     "/docker-entrypoint.…"   22 minutes ago   Up 13 minutes   80/tcp    demo1

[root@server1 ns]# docker run -d --name demo3 --network mynet1 --ip 172.23.0.10 nginx
5b3d1a0b5ba04931ca215d9fbf3b8e695bb00fe7b44ee8b93d64c56382b3da03
docker: Error response from daemon: user specified IP address is supported only when connecting to networks with user configured subnets.  只有配置子网才能指定ip
[root@server1 ns]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
5b3d1a0b5ba0   nginx     "/docker-entrypoint.…"   2 minutes ago    Created                   demo3
4ff0f3e84bf3   nginx     "/docker-entrypoint.…"   17 minutes ago   Up 17 minutes   80/tcp    demo2
6effdb7ac322   nginx     "/docker-entrypoint.…"   26 minutes ago   Up 16 minutes   80/tcp    demo1
[root@server1 ns]# docker rm -f demo1
demo1
[root@server1 ns]# docker rm -f demo2
demo2
[root@server1 ns]# docker rm -f demo3
demo3
[root@server1 ns]# docker network rm mynet1
mynet1

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第18张图片

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第19张图片

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第20张图片

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第21张图片[root@server1 ns]# docker run -d --name demo2 --network mynet2 --ip 172.30.0.10 nginx
1d7670934b049577e3c42cc255418d680aa21b94f1da205e139cee9c6adbbc6b
[root@server1 ns]# brctl show 不同的容器桥接到不同的网桥上
bridge name    bridge id        STP enabled    interfaces
br-7ace48192525        8000.024292b7c209    no        veth36e866f
br-ee2e2bfae934        8000.02422b17f726    no        veth5ffe06f
docker0        8000.0242258ffab5    no    

桥接到不同网桥上的容器,彼此是不通信的。 docker在设计上就是要隔离不同network的。 

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第22张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第23张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第24张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第25张图片

那么如何使两个不同网桥的容器通信呢: 使用 docker network connect命令为serene_wozniak添加一块my_net1的网卡。

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第26张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第27张图片

三、Docker的容器通信

容器之间除了使用ip通信外,还可以使用容器名称通信。

docker 1.10开始,内嵌了一个DNS server。

dns解析功能必须在自定义网络中使用。

启动容器时使用 --name 参数指定容器名称。

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第28张图片

Joined容器一种较为特别的网络模式。 在容器创建时使用--network=container:vm1指定。(vm1指定的是运行的容器名

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第29张图片 Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第30张图片

  处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信。

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第31张图片 busybox和demo两个容器使用相同的网络栈 网络资源唯一 它们监听资源的端口不能重复 demo使用nginx镜像 已经开通80端口 如果一个容器已经占取80端口 第二个容器在占取80端口 势必会冲突

--link 可以用来链接2个容器。

--link的格式: --link :alias

name和id是源容器的name和id,alias是源容器在link下的别名 Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第32张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第33张图片

当容器id发生变化时 解析会发生变化 变量不会发生变化Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第34张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第35张图片

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第36张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第37张图片

容器如何访问外网是通过iptables的SNAT实现的 

外网访问容器用到了docker-proxy和iptables DNAT

宿主机访问本机容器使用的是iptables DNAT

外部主机访问容器或容器之间的访问是docker-proxy实现

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第38张图片

外网如何访问容器: 端口映射 -p 选项指定映射端口 Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第39张图片

当你访问本机80端口时它会重定向到容器80 Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第40张图片

当从外部网络访问172.25.15.1的80端口时会被重定向172.17.0.2的80端口( 访问宿主机80端口直接被重定向到80端口)

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第41张图片 双冗余机制(有一种成立就可以)Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第42张图片

当删除docker映射端口时 外网依然可以访问

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第43张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第44张图片

当删掉docker-proxy 外网访问失败Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第45张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第46张图片

恢复:容器在启动或关闭的时侯会刷新nat规则Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第47张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第48张图片

当删除docker-proxy时 外网依然可以访问Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第49张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第50张图片

四、跨主机容器通信

server1和server2是两台独立的机器 相隔离的Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第51张图片

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第52张图片如何实现跨界点网络通信  首先清理实验环境

跨主机网络解决方案

docker原生的overlay(docker集群)和macvlan

众多网络方案是如何与docker集成在一起的

libnetwork     docker容器网络库

CNM (Container Network Model)这个模型对容器网络进行了抽象

CNM分三类组件

Sandbox:容器网络栈,包含容器接口、dns、路由表。(namespace)

Endpoint:作用是将sandbox接入network (veth pair)

Network:包含一组endpoint,同一network的endpoint可以通信。

macvlan网络方案实现

Linux kernel提供的一种网卡虚拟化技术。 无需Linux bridge,直接使用物理接口,性能极好。 

在两台docker主机上各添加一块网卡,打开网卡混杂模式: # ip link set eth1 promisc on

本次实验演示macvlan网络方案

1、不添加网卡的方式

分别打开server1和server2的eth0网卡的混杂模式

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第53张图片

查看两台主机网卡混杂模式是否开启并且网卡必须是激活(up)状态 Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第54张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第55张图片

创建私有网络 -d 指定驱动类型 (macvlan网络方式)-o 父级 使用物理接口进行通信 不用添加新的虚拟网卡Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第56张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第57张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第58张图片

 查看没有新的虚拟网卡 没有桥接

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第59张图片

两个不同主机之间上的容器之间的互通 Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第60张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第61张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第62张图片

macvlan网络结构分析

没有新建linux bridge

容器的接口直接与主机网卡连接,无需NAT或端口映射。

2、添加网卡方式

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第63张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第64张图片 Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第65张图片

查看添加eth1网卡 激活eth1网卡并打开eth1网卡的混杂模式

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第66张图片

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第67张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第68张图片

不指定mynet2 的ip地址会随机分取

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第69张图片

macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络

vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id取值为1~4094。 

Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第70张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第71张图片Docker --docker网络知识详解(原生网络、自定义网络、容器通信、跨主机容器网络)_第72张图片

通过子接口的方式来进行创建不一样的虚拟网络

macvlan网络间的隔离和连通

macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的。

可以在三层上通过网关将macvlan网络连通起来。

docker本身不做任何限制,像传统vlan网络那样管理即可。 

你可能感兴趣的