使用桥接网络

在网络方面,桥接网络是链路层设备,它在网络段之间转发流量。桥接网络可以是硬件设备或在主机内核中运行的软件设备。

就Docker而言,桥接网络使用软件桥接器,该软件桥接器允许连接到同一桥接网络的容器进行通信,同时提供与未连接到该桥接网络的容器的隔离。Docker桥驱动程序会自动在主机中安装规则,以便不同桥接网络上的容器无法直接相互通信。

桥接网络适用于在同一个 Docker守护程序主机上运行的容器。对于在不同Docker守护程序主机上运行的容器之间的通信,您可以在操作系统级别管理路由,也可以使用覆盖网络

启动Docker时,会自动创建默认桥接网络(也称为bridge),并且除非另行指定,否则新启动的容器将连接到该网络。您还可以创建用户定义的自定义桥接网络。用户定义的桥接网络 优于默认bridge 网络。

用户定义的桥接器可在容器化应用程序之间提供更好的隔离和互操作性

连接到同一个用户定义的桥接网络的容器会自动将所有端口相互暴露,而不会向外界显示任何端口。这使得容器化应用程序可以轻松地相互通信,而不会意外地打开对外界的访问。

想象一下具有Web前端和数据库后端的应用程序。外部世界需要访问Web前端(可能在端口80上),但只有后端本身需要访问数据库主机和端口。使用用户定义的桥接网络,只需要打开Web端口,并且数据库应用程序不需要打开任何端口,因为Web前端可以通过用户定义的桥接网络访问它。

如果在默认桥接网络上运行相同的应用程序堆栈,则需要打开Web端口和数据库端口,并使用 每个的标记-p--publish标记。这意味着Docker主机需要通过其他方式阻止对数据库端口的访问。

用户定义的桥接器在容器之间提供自动DNS解析

默认桥接网络上的容器只能通过IP地址相互访问,除非您使用被认为是过期的的--link选项。在用户定义的桥接网络上,容器可以通过名称或别名相互解析。

想象一下与前一点相同的应用程序,具有Web前端和数据库后端。如果你调用容器中的web或者db,Web容器可以在连接到数据库容器,无论托管在哪个docker 主机,应用程序都会在堆栈上运行。

如果在默认桥接网络上运行相同的应用程序堆栈,则需要在容器之间手动创建链接(使用过期的--link 标志)。这些链接需要在两个方向上创建,因此您可以看到这对于需要通信的两个以上容器而言变得复杂。或者,您可以操作/etc/hosts容器中的文件,但这会产生难以调试的问题。

容器可以在运行中与用户定义的网络连接和分离

在容器的生命周期中,您可以动态地将其与用户定义的网络连接或断开连接。要从默认桥接网络中删除容器,您需要停止容器并使用不同的网络选项重新创建容器。

每个用户定义的网络都会创建一个可配置的桥接网络

如果容器使用默认桥接网络,则可以对其进行配置,但所有容器都使用相同的设置,例如MTU和iptables规则。此外,配置默认桥接网络发生在Docker本身之外,并且需要重新启动Docker。

使用创建和配置用户定义的桥接网络 docker network create。如果不同的应用程序组具有不同的网络要求,则可以在创建时单独配置每个用户定义的桥接网络。

默认桥接网络上的容器共享环境变量

  • 最初,在两个容器之间共享环境变量的唯一方法是使用--link标志链接它们。用户定义的网络无法实现这种类型的变量共享。但是,有更好的方法来共享环境变量。一些想法:

    • 多个容器可以使用Docker卷装入包含共享信息的文件或目录。

    • 可以一起启动多个容器docker-compose,并且compose文件可以定义共享变量。

    • 您可以使用swarm服务而不是独立容器,并利用共享机密和 配置

连接到同一用户定义的桥接网络的容器有效地将所有端口相互暴露。对于可以访问不同网络上的容器或非Docker主机的端口,必须使用or 标志发布该端口。-p--publish

管理用户定义的桥

使用此docker network create命令可以创建用户定义的桥接网络。

$ docker network create my-net

您可以指定子网,IP地址范围,网关和其他选项。有关详细信息,请参阅 docker network create reference或输出docker network create --help

使用此docker network rm命令删除用户定义的桥接网络。如果容器当前已连接到网络, 请先断开它们 。

$ docker network disconnect my-net my-nginx
$ docker network rm my-net

当您创建或删除用户定义的桥接网络或从用户定义的桥接网络连接或断开容器时,Docker使用特定操作系统的工具来管理底层网络基础结构(例如iptables在Linux上添加或删除桥接网络设备或配置规则) )。这些细节应视为实施细节。让Docker为您管理用户定义的网络。

将容器连接到用户定义的桥

创建新容器时,可以指定一个或多个--network标志。此示例将Nginx容器连接到my-net网络。它还将容器中的端口80发布到Docker宿主机上的端口8080,因此外部客户端可以访问该端口。连接到my-net 网络的任何其他容器都可以访问my-nginx容器上的所有端口,反之亦然。

[root@benjamincloud ~]# docker create --name my-nginx \
> --network my-net \
> --publish : \
> nginx:latest

要将正在运行的容器连接到现有的用户定义的桥,请使用该 docker network connect命令。以下命令将已在运行的my-nginx容器连接 到已存在的my-net网络:

[root@benjamincloud ~]# docker network connect my-net my-nginx

断开容器与用户定义的桥接器的连接

要断开正在运行的容器与用户定义的桥接器的连接,请使用该docker network disconnect命令。以下命令将my-nginx 容器与my-net网络断开连接。

[root@benjamincloud ~]# docker network disconnect my-net my-nginx

使用IPv6

如果需要对Docker容器的IPv6支持,则需要 在创建任何IPv6网络或分配容器IPv6地址之前,在Docker守护程序上启用该选项并重新加载其配置。

创建网络时,可以指定--ipv6标志以启用IPv6。您无法在默认bridge网络上有选择地禁用IPv6支持。

 

启用从Docker容器转发到外部世界

默认情况下,来自连接到默认桥接网络的容器的流量 不会转发到外部世界。要启用转发,您需要更改两个设置。这些不是Docker命令,它们会影响Docker主机的内核。

  1. 配置Linux内核以允许IP转发。

    $ sysctl net.ipv4.conf.all.forwarding=
  2. 将策略的iptables FORWARD策略更改DROP为 ACCEPT

    $ sudo iptables -P FORWARD ACCEPT

    这些设置在重新启动时不会持续存在,因此您可能需要将它们添加到启动脚本中,或者相应的配置文件中。

使用默认桥接网络

默认bridge网络被视为Docker的遗留细节,不建议用于生产用途。配置它是一种手动操作,它有 技术缺点

将容器连接到默认桥接网络

如果未使用该--network标志指定网络,并且指定了网络驱动程序,则默认情况下容器将连接到默认bridge网络。连接到默认bridge网络的容器只能通过IP地址进行通信,除非它们使用--link标志进行链接 。

配置默认桥接网络

要配置默认bridge网络,请在中指定选项daemon.json。这是一个daemon.json指定了几个选项的示例。仅指定您需要自定义的设置。

{
"bip": "192.168.1.5/24",
"fixed-cidr": "192.168.1.5/25",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": ,
"default-gateway": "10.20.1.1",
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["10.20.1.2","10.20.1.3"]
}

重新启动Docker以使更改生效。

将IPv6与默认桥接网络一起使用

如果将Docker配置为支持IPv6(请参阅使用IPv6),则还会自动为IPv6配置默认桥接网络。与用户定义的桥接网络不同,您无法在默认桥接网络上有选择地禁用IPv6。

与独立容器联网

预计阅读时间: 18分钟

这一系列教程涉及独立Docker容器的网络连接。有关群组服务的网络,请参阅 使用群组服务进行网络连接。如果您需要了解有关Docker网络的更多信息,请参阅概述

这里仅介绍linux下的教程

  • 使用默认桥接网络演示了如何使用bridgeDocker自动为您设置的默认网络。该网络不是生产系统的最佳选择。

  • 使用用户自定的网络显示如何创建和使用自己的自定义桥接网络,以连接在同一Docker主机上运行的容器。对于在生产中运行的独立容器,建议使用此选项。

尽管覆盖网络通常用于群集服务,但Docker 17.06及更高版本允许您将覆盖网络用于独立容器。

使用默认桥接网络

在此示例中,您alpine在同一个Docker主机上启动两个不同的容器,并进行一些测试以了解它们如何相互通信。您需要安装并运行Docker。

1.打开终端窗口。在执行任何其他操作之前列出当前网络。如果您从未在此Docker守护程序上添加网络或初始化群组,那么您应该看到以下内容。您可能会看到不同的网络,但至少应该看到这些(网络ID会有所不同):

$ docker network ls

NETWORK ID          NAME                DRIVER              SCOPE
17e324f45964 bridge bridge local
6ed54d316334 host host local
7092879f2cc8 none null local

2.bridge是默认网络, 以及hostnone。后两者不是完全成熟的网络,但用于启动直接连接到Docker守护程序主机的网络堆栈的容器,或用于启动没有网络设备的容器。本教程将两个容器连接到bridge网络。

启动两个alpine容器运行ash,这是Alpine的默认shell是ash而不是bash。该-dit标志意味着要首先分离容器(背景),互动(与输入到它的能力),并与TTY(这样你就可以看到输入和输出)。

由于您正在启动它,因此您不会立即连接到容器。而是打印容器的ID。由于您尚未指定任何 --network标志,因此容器将连接到默认bridge网络。

$ docker run -dit --name alpine1 alpine ash

$ docker run -dit --name alpine2 alpine ash

检查两个容器是否实际启动:

3.检查bridge网络以查看连接到它的容器。

在顶部附近,bridge列出了有关网络的信息,包括Docker主机和bridge 网络之间的网关的IP地址(172.17.0.1)。在Containers密钥下面,列出了每个连接的容器,以及有关其IP地址(172.17.0.2for alpine1172.17.0.3for alpine2)的信息。

4.由于容器在后台运行。使用docker attach 命令连接到alpine1

[root@benjamincloud ~]# docker  attach alpine1
/ #

提示符更改为#表示您是root容器中的用户。使用该ip addr show命令显示alpine1容器内的网络接口:

第一个接口是环回设备。暂时忽略它。请注意,第二个接口具有IP地址172.17.0.2,该地址alpine1与上一步中显示的地址相同。

5.从内部alpine1,确保您可以通过ping连接到互联网baidu.com。该-c 2标志将命令限制为两次ping 尝试。

6.现在尝试ping第二个容器。首先,通过IP地址ping它 172.17.0.3

这成功了。接下来,尝试alpine2按容器名称ping 容器。这将失败。

alpine1使用分离序列分离而不停止它, CTRLp 然后 q(按住CTRL并键入p后跟q)。如果你愿意,重视alpine2并重复步骤4,5和6出现,用alpine1取代alpine2。

停止并移除两个容器。

$ docker container stop alpine1 alpine2
$ docker container rm alpine1 alpine2

请记住,bridge不建议将默认网络用于生产。要了解用户定义的桥接网络,请继续学习 下面的内容

使用用户定义的网桥

在此示例中,我们再次启动两个alpine容器,但将它们附加到alpine-net我们已创建的用户定义的网络中。

这些容器根本没有连接到默认bridge网络。然后,我们启动第三个alpine连接到bridge网络,但未连接到的容器alpine-net,以及连接到两个网络的第四个alpine容器。

1.创建alpine-net网络。您不需要该--driver bridge标志,因为它是默认值,但此示例显示了如何指定它。

[root@benjamincloud ~]# docker network create --driver bridge alpine-net
65ddc2eff605b8efdabfb8e476af20de32b9babdd2bf12d2b3182115b03abfaf

2.列出Docker的网络:

检查alpine-net网络。这将显示其IP地址以及没有容器连接到它的事实:

请注意,该网络的网关172.18.0.1与其网关所在的默认网桥相对172.17.0.1。您的系统上的确切IP地址可能有所不同。

3.创建您的四个容器。注意--network标志。您只能在docker run命令期间连接到一个网络,因此您需要在 docker network connect以后连接alpine4bridge 网络。

[root@benjamincloud ~]# docker run -dit --name alpine1 --network alpine-net alpine ash
afe579c54cf2dc7c247d2b6a2a8db98b3f7296f002a07be21aa27dd4cf8f052b
[root@benjamincloud ~]# docker run -dit --name alpine2 --network alpine-net alpine ash
9a1a89cff8ea0028ea2ebb7e20b90354d4dc7475d9c716b8040e8b325cdb0f01
[root@benjamincloud ~]# docker run -dit --name alpine3 alpine ash
b0c0451946a0c8929cd31da1133b812b6353a59542a00f70938f2e3b70305ef2
[root@benjamincloud ~]# docker run -dit --name alpine4 --network alpine-net alpine ash
c9d91c0cf3d5d30514c649a13c772b1cefc26578b1155aaac0b79fde8c95984e

验证所有容器是否正在运行:

4.再次检查bridge网络和alpine-net网络:

容器alpine1alpine2alpine4连接到 alpine-net网络。

5. 在用户定义的网络上alpine-net,容器不仅可以通过IP地址进行通信,

还可以将容器名称解析为IP地址。此功能称为自动服务发现。让我们连接alpine1并测试一下。

alpine1应该能够解析 alpine2alpine4(和alpine1本身)IP地址。

/ # ping -c2 alpine1
PING alpine1 (172.18.0.2): data bytes
bytes from 172.18.0.2: seq= ttl= time=0.041 ms
bytes from 172.18.0.2: seq= ttl= time=0.066 ms --- alpine1 ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 0.041/0.053/0.066 ms
/ # ping -c2 alpine2
PING alpine2 (172.18.0.3): data bytes
bytes from 172.18.0.3: seq= ttl= time=0.080 ms
bytes from 172.18.0.3: seq= ttl= time=0.096 ms --- alpine2 ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 0.080/0.088/0.096 ms
/ # ping -c2 alpine4
PING alpine4 (172.18.0.4): data bytes
bytes from 172.18.0.4: seq= ttl= time=0.086 ms
bytes from 172.18.0.4: seq= ttl= time=0.100 ms --- alpine4 ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 0.086/0.093/0.100 ms

6.从alpine1,您根本无法连接alpine3,因为它不在alpine-net网络上。

/ # ping -c2 alpine3
ping: bad address 'alpine3'

不仅如此,而且无法连接到alpine3来自alpine1它的IP地址的ping。回顾一下网络的docker network inspect输出 bridge并查找alpine3IP地址:172.17.0.2尝试ping它。

/ # ping -c2 172.17.0.2
PING 172.17.0.2 (172.17.0.2): data bytes --- 172.17.0.2 ping statistics ---
packets transmitted, packets received, % packet loss

退出容器使其在后台运行 ctrl+p 接q

7.请记住,alpine4它连接到默认bridge网络和alpine-net。它应该能够到达所有其他容器。但是,您需要alpine3通过其IP地址进行寻址。连接到它并运行测试。

/ # ping -c  alpine1
PING alpine1 (172.18.0.2): data bytes
bytes from 172.18.0.2: seq= ttl= time=0.065 ms
bytes from 172.18.0.2: seq= ttl= time=0.132 ms --- alpine1 ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 0.065/0.098/0.132 ms
/ # ping -c alpine2
PING alpine2 (172.18.0.3): data bytes
bytes from 172.18.0.3: seq= ttl= time=0.101 ms
bytes from 172.18.0.3: seq= ttl= time=0.121 ms --- alpine2 ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 0.101/0.111/0.121 ms
/ # ping -c alpine3
ping: bad address 'alpine3'
/ # ping -c alpine4
PING alpine4 (172.18.0.4): data bytes
bytes from 172.18.0.4: seq= ttl= time=0.074 ms
bytes from 172.18.0.4: seq= ttl= time=0.067 ms --- alpine4 ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 0.067/0.070/0.074 ms
/ # ping -c 172.17.0.2
PING 172.17.0.2 (172.17.0.2): data bytes
bytes from 172.17.0.2: seq= ttl= time=0.124 ms
bytes from 172.17.0.2: seq= ttl= time=0.097 ms --- 172.17.0.2 ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 0.097/0.110/0.124 ms

8.作为最终测试,请确保您的容器都可以通过ping来连接到Internet baidu.com。你已经附上了,alpine4所以从那里开始尝试。

接下来,分离alpine4并连接alpine3 (仅连接到bridge网络),然后重试。最后,连接到alpine1(仅连接到alpine-net网络)并再试一次。

/ # ping -c2 baidu.com
PING baidu.com (220.181.57.216): data bytes
bytes from 220.181.57.216: seq= ttl= time=57.520 ms
bytes from 220.181.57.216: seq= ttl= time=57.523 ms --- baidu.com ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 57.520/57.521/57.523 ms
/ # read escape sequence
[root@benjamincloud ~]# docker attach alpine3
/ # ping -c baidu.com
PING baidu.com (123.125.115.110): data bytes
bytes from 123.125.115.110: seq= ttl= time=36.863 ms
bytes from 123.125.115.110: seq= ttl= time=36.954 ms --- baidu.com ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 36.863/36.908/36.954 ms
/ # read escape sequence
[root@benjamincloud ~]# docker attach alpine1
/ # ping -c baidu.com
PING baidu.com (220.181.57.216): data bytes
bytes from 220.181.57.216: seq= ttl= time=57.521 ms
bytes from 220.181.57.216: seq= ttl= time=57.547 ms --- baidu.com ping statistics ---
packets transmitted, packets received, % packet loss
round-trip min/avg/max = 57.521/57.534/57.547 ms

9.停止并删除所有容器和alpine-net网络。

root@benjamincloud ~]# docker stop alpine1 alpine2 alpine3 alpine4
alpine1
alpine2
alpine3
alpine4
[root@benjamincloud ~]# docker rm alpine1 alpine2 alpine3 alpine4
alpine1
alpine2
alpine3
alpine4
[root@benjamincloud ~]# docker network rm alpine-net
alpine-net

docker从零开始网络(二)桥接网络的更多相关文章

  1. docker从零开始(二)容器初体验

    使用定义容器 Dockerfile Dockerfile定义容器内所需要的环境.对网络接口和磁盘驱动器等资源的访问在此环境中进行虚拟化,该环境与系统的其他部分隔离,因此您需要将端口映射到外部世界,并具 ...

  2. Virtualbox的centos7 nat和桥接网络配置

    在实际配置虚拟机的过程中,网络配置时候一个很繁琐的过程,经常一个点没注意到,就访问不了了.在此,做一个简单的教程以供后续使用时可以参考! 方法一: 使用NAT网络 1. 选择网卡 安装centos7的 ...

  3. VM 虚拟机 CentOS 7 设置 桥接网络

    桥接网络的设置:   安装时设置网络为桥接网络!   找到 ip 地址,设置如下   注意ip地址并不是一样的,用以区分   然后在关闭 windows 防火墙,打开 cmd 使用 ping 命令 O ...

  4. docker 配置桥接网络

    2.5 docker配置桥接网络(上): 为了使本地网络中的机器和Docker 容器更方便的通信,我们经常会有将Docker容器 配置到和主机同一网段的需求. 这个需求其实很容器实现, 我们只需要将D ...

  5. Docker Centos7 下建立 Docker 桥接网络

    为什么要让docker桥接物理网络? docker默认提供了一个隔离的内网环境,启动时会建立一个docker0的虚拟网卡,每个容器都是连接到docker0网卡上的.而docker0的ip段为172.1 ...

  6. 使用Docker的macvlan为容器提供桥接网络及跨主机通讯

    对于了解Docker容器网络的朋友,我想对虚拟机的网络也不会陌生,毕竟我们是跟随这个时代一起学习和进步的人.相比VM,Docker的网络也在逐步走向成熟,本文主要针对其中的macvlan做下简单的介绍 ...

  7. Centos7.x Docker桥接网络

    基于Centos7.x构建Docker桥接网络, 配置bridge桥接网络可以直接设置网卡配置文件: 自定义桥接网络设置如下: 关掉docker0 ifconfig docker0 down 删除do ...

  8. docker从零开始网络(六)Macvlan

    使用Macvlan网络 某些应用程序,尤其是遗留应用程序或监视网络流量的应用程序,希望直接连接到物理网络.在这种情况下,您可以使用macvlan网络驱动程序为每个容器的虚拟网络接口分配MAC地址,使其 ...

  9. docker从零开始网络(三) overly(覆盖)网络

    使用overly网络 该overlay网络驱动程序会创建多个docker进程主机之间的分布式网络.该网络位于(覆盖)特定于主机的网络之上,允许连接到它的容器(包括群集服务容器)安全地进行通信.Dock ...

随机推荐

  1. 【SSH】——Struts2中的动态方法调用(二)

    当action中的方法有很多时,那应该怎么调用呢?上次我们提到的UserAction类中只有一个execute方法,如果我们需要增加用户的增删改查方法,如下: public class UserAct ...

  2. 16常用API

    常用API 今日内容介绍 u 正则表达式 u Date u DateFormat u Calendar 第1章 正则表达式 1.1 正则表达式的概念 正则表达式(英语:Regular Expressi ...

  3. el-table中操作一栏怎么根据当前行的信息显示编辑、删除、编辑完成按钮

    对每个按钮是否显示,使用v-show绑定变量,因为每一行的v-show绑定的变量必须是唯一的(不然的话操作此行,其他行的状态也会跟着变化),所以不可能提前在.ts中对变量进行初始化,只能使用本行的字段 ...

  4. ui-grid从后端获取数据后更改数据显示的格式

    从后端获取的数据时是这样的: { "TotalCount":14,"Items": [ { "ProfileId":14, "Na ...

  5. NAPT 分为锥型(Cone)和 对称型(Symmetric)

    NAPT 分为锥型(Cone)和 对称型(Symmetric) 链接:https://www.zhihu.com/question/38729355/answer/86531260 实际上大部运营商提 ...

  6. 左侧导航条+中间显示内容+右侧菜单配置,Bootstrap+AdminLTE+Jquery

    1.最近做个导航页面,找了一大堆UI,最终选了AdminLTE,这个UI也是以bootstrap为基础,简单实用,中间内容用jquery的load加载,简单暴力,非常适合快速开发. 2.效果图如下: ...

  7. [POJ 1204]Word Puzzles(Trie树暴搜&AC自己主动机)

    Description Word puzzles are usually simple and very entertaining for all ages. They are so entertai ...

  8. 【BZOJ 1770 】 [Usaco2009 Nov]lights 燈 dfs+异或方程组

    这道题明显是异或方程组,然而解不一定唯一他要的是众多解中解为1的数的最小值,这个时候我们就需要dfs了我们dfs的时候就是枚举其有不确定解的数上选0或1从而推知其他解,由于我们dfs的时候先0后1,虽 ...

  9. [POJ2777] Count Color

    \[Count Color\] Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 50865 Accepted: 15346 Des ...

  10. Codeforces Round #520 (Div. 2) D. Fun with Integers

    D. Fun with Integers 题目链接:https://codeforc.es/contest/1062/problem/D 题意: 给定一个n,对于任意2<=|a|,|b|< ...