networking - docker 网络

标签 networking docker subnet

我试图了解以下之间的关系:

  • eth0在主机上;和
  • docker0桥;和
  • eth0每个容器上的接口(interface)

  • 据我了解,Docker:
  • 创建一个 docker0桥接,然后为其分配一个与主机上运行的任何内容不冲突的可用子网;然后
  • Docker 绑定(bind) docker0eth0在主机上运行;然后
  • Docker 将每个新容器绑定(bind)到 docker0 ,这样容器的 eth0接口(interface)连接到docker0在主机上,该主机又连接到 eth0在主机上

  • 这样,当主机外部的东西试图与容器通信时,它必须将消息发送到主机 IP 上的端口,然后转发到 docker0桥,然后广播到主机上运行的所有容器,是吗?

    此外,这样,当一个容器需要与主机外部的东西通信时,它有自己的 IP(从 docker0 子网租用),因此远程调用者将看到消息来自容器的 IP。

    因此,如果我上面所说的任何内容都不正确,请首先为我澄清!

    假设我或多或少是正确的,我主要担心的是:
  • 当远程服务“调用”容器时,所有容器都会广播相同的消息,这会产生大量流量/噪音,但也可能存在安全风险(其中只有容器 1 应该是某些消息的接收者,但所有在其上运行的其他容器也会收到消息);和
  • 当 Docker 在不同的主机上选择相同的子网时会发生什么?在这种情况下,位于主机 1 上的容器 1 可能与位于主机 2 上的容器 2 具有相同的 IP 地址。如果容器 1 需要“调用”某个外部/远程系统(不在主机上),那么如何远程系统区分容器 1 和容器 2(两者都将显示相同的导出 IP)?
  • 最佳答案

    我不会说你对 Docker 中的网络概念很清楚。
    让我先澄清这部分:
    所以事情是这样的:

  • Docker 使用 Linux 内核的一个名为命名空间的特性来分类/划分资源。
  • 当容器启动时,Docker 会为该容器创建一组命名空间。
  • 这提供了一层隔离。
  • 其中之一是“网络命名空间”:用于管理网络接口(interface)。

  • 现在谈谈网络命名空间:
    网络命名空间,
  • 让每个容器都有自己的网络资源,自己的网络栈。
  • 它有自己的网络接口(interface)。
  • 它是自己的路由表。
  • 它有自己的 iptables 规则。
  • 它自己的套接字(ss,netstat)

  • 我们可以跨网络命名空间移动网络接口(interface)。
  • 所以我们可以在某处创建一个 netns 并在其他容器中使用它。
  • 通常: 使用两个虚拟接口(interface),充当交叉电缆。
  • eth0@container netNS,与host中的虚拟接口(interface)vethXXX配对
    网络 ns。
    ➔ 所有虚拟接口(interface) vethXXX 都桥接在一起。 (使用桥接器 docker0)

  • 现在,除了命名空间之外,Linux 内核中还有第二个特性可以让创建容器成为可能:c-groups(或 control-groups)。
  • 控制组让我们实现计量和限制:
  • 内存
  • 中央处理器
  • block I/O
  • 网络


  • TL/DL
    简而言之:
    容器之所以成为可能是因为内核的两个主要特性:
    命名空间和 C 组。

    Cgroups ---> Limits how much you can use.

    Namespaces ---> Limits what you can see.


    你不能影响你看不到的东西。

    回到你的问题,当主机接收到一个用于容器的数据包时,它被封装在层中,这样每一层都可以帮助网络 Controller ,它一层一层地剥离数据包以将其发送到目的地。 (同样在传出时,数据包被逐层封装)
    所以,我认为这也回答了你的两个问题。
  • 这不完全是广播。其他容器看不到与它们无关的数据包(命名空间)。
  • 由于在数据包进入外部网络时添加了层,因此外部层(不同主机不同)将帮助数据包唯一地识别它的接收者。

  • PS:
    如果有人发现某些信息有误,请在评论中告诉我。我匆忙写了这篇文章,很快就会用更好的评论文本更新它。
    谢谢你。

    关于networking - docker 网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32862146/

    相关文章:

    docker - 将 NFS docker 卷中的单个文件挂载到容器中

    c# - 连接 2 台不同的子网计算机

    azure - Azure VNET 中的子网地址范围确定

    azure - 当我在 terraform 中运行 cidrsubnet 函数时,我得到 'prefix extension of 3 does not accommodate a subnet numbered 8' 。为什么是这样?

    spring-boot - 无法访问 docker 容器中的其余端点

    mongodb - Docker 注册层 mongo 失败

    linux - 主机对本地主机进行不必要的 dns 查找

    linux - 使用 RAW 套接字在 Linux 上捕获传出 icmpv6 数据包

    networking - 使用腻子进行端口转发(隧道)

    c - 您可以在一个套接字接收调用中获得两个数据包以进行多播吗?