docker有3种网络:

使用命令docker network ls,执行结果如下。

NETWORK ID          NAME                DRIVER              SCOPE
82e8822065c7 bridge bridge local
a36f938bc6c6 host host local
55ee9a442ee8 none null local

1,bridge:是NAT Bridge。在宿主机器上创建一个软件的交换机或者是网卡。

ifconfig可以看到多了个【docker0】。

【docker0】既可以作为交换机,也可以作为网卡。不给它地址就是交换机,给它地址就既能当交换机也能当网卡。

linux内核可以为进程创建虚拟网卡对,这个网卡对就像网线一样,有2个头。

一头连接到自己进程所属的网络命名空间,另一头连接任何地方。

linux内核也可以创建软件交换机,使用【brctl】命令创建。

创建虚拟网络,以实现让进程C1和进程C2可以通信。

  • 步骤1:创建一个网线m
  • 步骤2:创建一个网线n
  • 步骤3:创建一个虚拟交换机S1。
  • 步骤4:让网线m的一端连上进程C1所属的网络命名空间,让网线m的另一端连上虚拟交换机S1。
  • 步骤5:让网线n的一端连上进程C2所属的网络命名空间,让网线n的另一端连上虚拟交换机S1。
  • 进程C1和进程C2就可以通信了。

创建虚拟网络,以实现让进程C1和进程C3可以通信。

  • 步骤1:创建一个网线k
  • 步骤2:创建一个虚拟交换机S2。
  • 步骤3:创建一个图中间的微内核,让这个内核代替路由器。或者不需要路由器的话,创建1根网线,连接S1和S2,这样一来就不需要步骤4了。
  • 步骤4:创建2根网线,让S1和S2都连都微内核上。
  • 进程C1和进程C3就可以通信了。

有个著名的开源的创建虚拟交换机的软件:OVS(OpenVSwitch).

overlay network(叠加网络)

C1(192.168.1.3)和C5(192.168.1.4)在同一个网段,物理机器h1(10.1.1.3)和h2(10.1.1.4)连接在同一个交换机上。因为C1和C5在同一个网段,所以它们2个可以互相看见,当C1要发送数据给C5时,ip报文里是C1:C5,然后经过虚拟网桥(docker0),转发给物理机器h1,物理机器h1在【ip报文C1:C5】外面再包裹一层【h1:h2】,物理机器h2接受到报文后,拆掉外层的【h1:h2】,发现里面还有【C1:C5】,所以通过虚拟网桥(docker0),转发给C5。

上图里面的【docker0】,就是在运行docker daemon进程的机器上,执行ifconfig,看到的【docker0】,它是nat bridge。每启动一个容器,就产生一条网线,一端就插在【docker0】上,一端插在自己容器的网络命名空间上。。

那么如何查看,【docker0】上插了几根网线呢?

使用【yum install bridge-utils】里面的【brctl show】命令,查看网桥上插了哪些网线。

[root@localhost ys]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242af11c649 no veth93593bc
vethc7cb2ca

从上面的执行结果可以看出来,在【docker0】上插了2根网线分别是veth93593bc和vethc7cb2ca。用在宿主机上使用ifconfig,可以看到这2个网线。

[root@localhost ys]# ifconfig
veth93593bc: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 ..... prefixlen 64 scopeid 0x20<link>
ether ..... txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vethc7cb2ca: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 .. prefixlen 64 scopeid 0x20<link>
ether ..... txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

使用【ip link show】也可以看到veth93593bc和vethc7cb2ca,而且还可以发现veth93593bc的另一端是if14,vethc7cb2ca的另一端是if12

[root@localhost ys]# ip link show
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:42:af:11:c6:49 brd ff:ff:ff:ff:ff:ff
13: vethc7cb2ca@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether a2:a3:b8:3c:8c:88 brd ff:ff:ff:ff:ff:ff link-netnsid 0
15: veth93593bc@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether b2:24:a8:13:4d:56 brd ff:ff:ff:ff:ff:ff link-netnsid 1

【iptables -t nat -vnL】查看,发现了下面的规则,所以说明docker0是nat bridge。

iptables种的DNAT和SNAT概念

Chain POSTROUTING (policy ACCEPT 47 packets, 3073 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0

in:*,代表:从任何接口进来

out:!docker0,代表:不从docker0出去

source:172.17.0.0/16,代表:原地址来自172.17.0.0/16的任何主机地址,

destination:0.0.0.0/0,代表:发送到任何主机地址,

target:MASQUERADE,代表:做源地址转换 (SNAT ),也就是自动在本机上选择一个源地址。

把上面的话连接起来的意思:从任何接口进来,不从docker0出去,原地址是来自172.17.0.0/16的任何主机地址,发送到任何主机地址,做源地址转换。

创建网络命名空间

查看ip命令的工具包是否安装:rpm -q iproute

使用ip命令,看到object里有网络命名空间(netns),所以我们用ip命令就可以创建网络命名空间。

[root@localhost ys]# ip
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
ip [ -force ] -batch filename
where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
vrf }
OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
-h[uman-readable] | -iec |
-f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |
-4 | -6 | -I | -D | -B | -0 |
-l[oops] { maximum-addr-flush-attempts } | -br[ief] |
-o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
-rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}
  • 获得ip netns命令的帮助信息:

    [root@localhost ys]# ip netns help
    Usage: ip netns list//查看当前系统里的网络命名空间
    ip netns add NAME//添加网络命名空间
    ip netns set NAME NETNSID
    ip [-all] netns delete [NAME]
    ip netns identify [PID]//让某个进程使用某个网络命名空间
    ip netns pids NAME
    ip [-all] netns exec [NAME] cmd ...//在某个网络命名空间上执行网络命令。
    ip netns monitor
    ip netns list-id
  • 命令ip netns使用例子:创建网络命名空间和查看网络命名空间

    [root@localhost ys]# ip netns list
    [root@localhost ys]# ip netns add ns1
    [root@localhost ys]# ip netns add ns2
    [root@localhost ys]# ip netns list
    ns2
    ns1
  • 获取ip link命令的帮助信息:ip link help

    [root@localhost ys]# ip link help
    Usage: ip link add [link DEV] [ name ] NAME
    [ txqueuelen PACKETS ]
    [ address LLADDR ]
    [ broadcast LLADDR ]
    [ mtu MTU ] [index IDX ]
    [ numtxqueues QUEUE_COUNT ]
    [ numrxqueues QUEUE_COUNT ]
    type TYPE [ ARGS ]
    ...后面太多了,省略了。
  • 在指定的网络命名空间里执行网络命令:

    # ip netns exec ns1 ifconfig
  • 给网络命名空间创建网线(虚拟网卡对),命令里面的【type】是网卡对的类型,veth是以太网。

    # ip link add name veth1.1 type veth peer name veth1.2

    使用ip link show可以看到刚创建的veth1.1和veth1.2,他们互为一对,而且他们都是插宿主机上的。

    22: veth1.2@veth1.1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 4e:e3:65:60:bb:08 brd ff:ff:ff:ff:ff:ff
    23: veth1.1@veth1.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 2a:16:5b:ce:fe:f6 brd ff:ff:ff:ff:ff:ff

    使用ifconfig,发现他们都没有被显示出来,因为还没有激活他们。用ifconfig -a是可以显示出来的。

    先创建一个网络命名空间:ip netns add ns1,然后让veth1.2插在ns1上。

    # ip link set dev veth1.2 netns ns1

    然后在宿主机网络命名空间上执行ip link show,发现veth1.2没有了。因为veth1.2已经到ns1网络命名空间里了。

    23: veth1.1@if22: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 2a:16:5b:ce:fe:f6 brd ff:ff:ff:ff:ff:ff link-netnsid 0

    再去ns1网络命名空间里,执行ip netns exec ns1 ifconfig -a,发现veth1.2在里面。

    veth1.2: flags=4098<BROADCAST,MULTICAST>  mtu 1500
    ether 4e:e3:65:60:bb:08 txqueuelen 1000 (Ethernet)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    也可以修改veth1.2的名字,修改成eth0.

    # ip netns exec ns1 ip link set dev veth1.2 name eth0

    执行ip netns exec ns1 ifconfig -a,发现变成了eth0了。

    eth0: flags=4098<BROADCAST,MULTICAST>  mtu 1500
    ether 4e:e3:65:60:bb:08 txqueuelen 1000 (Ethernet)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
  • 让虚拟网卡插在某个网络命名空间。

    # ip link set dev veth1.2 netns ns1
  • 激活虚拟网卡(赋给它IP就是激活)。

    激活veth1.1

    # ifconfig veth1.1 10.1.0.1/24 up

    执行ifconfig,发现虚拟网卡veth1.1有ip地址了。

    veth1.1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
    inet 10.1.0.1 netmask 255.255.255.0 broadcast 10.1.0.255
    ether 2a:16:5b:ce:fe:f6 txqueuelen 1000 (Ethernet)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    激活ns1里的eth0

    # ip netns exec ns1 ifconfig eth0 10.1.0.2/24 up

    执行ifconfig,发现虚拟网卡eth0有ip地址了。

    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 10.1.0.2 netmask 255.255.255.0 broadcast 10.1.0.255
    inet6 fe80::4ce3:65ff:fe60:bb08 prefixlen 64 scopeid 0x20<link>
    ether 4e:e3:65:60:bb:08 txqueuelen 1000 (Ethernet)
    RX packets 11 bytes 1447 (1.4 KiB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 7 bytes 586 (586.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    从宿主机ping一下ns1里的eth0,是可以ping通的。

    # ping 10.1.0.2
    PING 10.1.0.2 (10.1.0.2) 56(84) bytes of data.
    64 bytes from 10.1.0.2: icmp_seq=1 ttl=64 time=0.073 ms

    再从ns1ping一下宿主机的veth1.1,也是可以ping通的。

    # ip netns exec ns1 ping 10.1.0.1
    PING 10.1.0.1 (10.1.0.1) 56(84) bytes of data.
    64 bytes from 10.1.0.1: icmp_seq=1 ttl=64 time=0.039 ms
  • 使用ip命令可以创建虚拟网卡,使用brctl,可以创建虚拟交换机,有了它俩,就可以模拟很多虚拟网络,比如物理桥,nat桥等,不需要安装额外的虚拟机,很轻量。

有个问题,docker容器间是如何互相通信的呢?

  • 假设容器都是以bridge方式启动

    • 2个容器都插在docker0上,那么这2个容器都在172.17网段上,互相通信没有任何问题。

    • 容器和宿主机互相通信没有问题。

    • 客户端CL1,要通过80端口访问nginx容器WEB1,但是客户端CL1同nginx容器WEB1在不同的网络,如何通信呢?nginx容器WEB1所在的宿主机只能使用DNAT技术,才能实现通信。也就是说客户端CL1访问的是宿主机,宿主机再转发给nginx容器WEB1。

      这就有个问题了,如果web2和web3也是nginx,也要使用80端口,那么宿主机转发的时候就不知道转给哪个容器了。

另一种方式:容器可以有独立的6个命名空间,为了2个容器间可以用lo(127.0.0.1)通信,让他们只拥有3个(user,mount, pid)独立的命名空间,另外3个(uts, net, ipc)他们共享使用。

二,host:

容器间可以共用3个(uts, net, ipc)空间,那么容器可以和宿主机(docker daemon进程所运行的机器)共用吗?是可以的。让一个容器A和宿主机共用3个(uts, net, ipc)空间,让其他的容器使用桥接,这样一来容器A就有了管理网络的特权。这就是docker的host连接方式。

三,none:容器没有网卡,只有lo。所以不能网络通信。

docker 网络种类:

查看网络连接具体信息的命令(inspect 可以查看任何docker object):

# docker network inspect bridge/host/none

查看容器的网络连接具体信息。

# docker container inspect ng1

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

docker 网络设置概述的更多相关文章

  1. Docker 网络设置

    一.Docker 网络默认使用的 Bridge 模式 默认生成为 docker0 :每个容器使用 veth 对,一头在容器的网络 namespace 中,一头在 docker0 上: 1.Docker ...

  2. Docker网络设置及文件挂载

    网络设置–net=bridge- 默认选项,用网桥的方式来连接docker容器.–net=host- docker跳过配置容器的独立网络栈.–net=container:NAME_or_ID- 告诉d ...

  3. docker网络设置(待整理)

      手动指定容器的配置      -h HOSTNAME or --hostname=HOSTNAME  \\设定容器的主机名.      --dns=IP_ADDRESS  \\指定DNS地址.  ...

  4. Docker网络配置概述

    Overview One of the reasons Docker containers and services are so powerful is that you can connect t ...

  5. Docker网络基础:快速指南

    Docker网络基础:快速指南 原文连接:http://blogxinxiucan.sh1.newtouch.com/2017/07/30/Docker网络基础:快速指南/ 了解有关扩展网络功能的默认 ...

  6. 《Docekr入门学习篇》——Docker网络及数据卷

    Docker网络设置 默认情况下docker会创建一个桥接网卡[docker 0],docker有两种映射方式,一种是随机映射,一种是指定映射. 提示:生产场景一般不使用随机映射,但是随机映射的好处是 ...

  7. docker 网络概述及网络模式详解

    docker 网络概述及网络模式详解 1.网络概述 2.网络模式详解 1.网络概述: Docker 网络实现原理 Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0) ...

  8. 5、Docker网络配置(单机)

    一.概述 以下内容参考:https://docs.docker.com/network/#network-drivers Docker容器和服务如此强大的原因之一是您可以将它们连接在一起,或者将它们连 ...

  9. docker安装及概述

    相关快捷键 退出:Ctrl-D or exit detach:Ctrl-P + Ctrl-Q Docker 核心技术 1.Namespace — 实现Container的进程.网络.消息.文件系统和主 ...

随机推荐

  1. PCA主成分分析(最大投影方差)

    PCA简介: 从n维数据中提取最能代表这组数据的m个向量,也就是对数据进行降维(n->m),提取特征. 目标: 找到一个向量\(\mu\),使n个点在其上的投影的方差最大(投影后的数据越不集中, ...

  2. 关于java基础、多线程、JavaWeb基础、数据库、SSM、Springboot技术汇总

    作者 : Stanley 罗昊 本人自行总结,纯手打,有疑问请在评论区留言 [转载请注明出处和署名,谢谢!] 一.java基础 1.多态有哪些体现形式? 重写.重载 2. Overriding的是什么 ...

  3. python高阶函数——map/reduce

    python 内置了map()和reduce()函数 1.map()函数 map()函数接收两个参数,一个是函数,一个是可迭代对象Iterable,map将传入的函数依次作用于序列的每一个元素.并把结 ...

  4. 从0系统学Android--4.1探究碎片

    从0系统学Android--4.1探究碎片 本系列文章目录:更多精品文章分类 本系列持续更新中.... 初级阶段内容参考<第一行代码> 第四章:手机平板要兼顾--探究碎片 平板电脑和手机最 ...

  5. rocksdb学习笔记

    rocksdb是在leveldb的基础上优化而得,解决了leveldb的一些问题. 主要的优化点 1.增加了column family,这样有利于多个不相关的数据集存储在同一个db中,因为不同colu ...

  6. shell编程之case分支语句

    shell编程之case分支语句 case分支语句和if的多分支语句很相似. if多分支语句一般用在有(区间范围)的地方 :例如:0-100之间. if需要判断多个不同的条件. case的分支语句用在 ...

  7. 6 Ubuntu软件安装

      6 软件安装¶ 6.1 通过apt 安装/卸载软件¶ apt是Advanced Packaging Tool,是Linux下的一款安装包管理工具 可以在终端中方便的安装/卸载/更新软件包 # 1. ...

  8. 安卓投屏助手(ARDC)最新版

    安卓投屏助手(B1493) 1.兼容Android 10: 2.增加灭屏投屏功能: 3.增加显示鼠标位置功能; 4.增加了虚拟NaviBar功能: 5.捐赠界面增加QQ支付,移除Paypal,感谢大家 ...

  9. 2019阿里天猫团队Java高级工程师面试题之第三面

    2019阿里天猫团队Java高级工程师面试题之第一面 2019阿里天猫团队Java高级工程师面试题之第二面 1.说说MySQL的锁并发?加锁的机制是什么? https://www.cnblogs.co ...

  10. error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in

    问题: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_ ...