前言

Docker 的网络实现其实就是利用了 Linux 上的网络命名空间和虚拟网络设备(特别是 vethpair)。

基本原理

首先,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收发数据 包;此外,如果不同子网之间要进行通信,需要路由机制。

Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。 Linux 通 过在内核中进行数据复制来实现虚拟接口之间的数据转发,发送接口的发送缓存中的数据包 被直接复制到接收接口的接收缓存中。对于本地系统和容器内系统看来就像是一个正常的以 太网卡,只是它不需要真正同外部网络设备通信,速度要快很多。

Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它 们彼此连通(这样的一对接口叫做 veth pair )。

创建网络参数

Docker 创建一个容器的时候,会执行如下操作:

  • 创建一对虚拟接口,分别放到本地主机和新容器中;
  • 本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 veth65f9;
  • 容器一端放到新容器中,并修改名字作为 eth0,这个接口只在容器的命名空间可见;
  • 从网桥可用地址段中获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 veth65f9。

完成这些之后,容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。

可以在 docker run 的时候通过 --net 参数来指定容器的网络配置,有4个可选值:

  • –net=bridge 这个是默认值,连接到默认的网桥。
  • –net=host 告诉 Docker 不要将容器网络放到隔离的命名空间中,即不要容器化容器内 的网络。此时容器使用本地主机的网络,它拥有完全的本地主机接口访问权限。容器进 程可以跟主机其它 root 进程一样可以打开低范围的端口,可以访问本地网络服务比如 D- bus,还可以让容器做一些影响整个主机系统的事情,比如重启主机。因此使用这个选项 的时候要非常小心。如果进一步的使用 --privileged=true ,容器会被允许直接配置主机 的网络堆栈。
  • –net=container:NAME_or_ID 让 Docker 将新建容器的进程放到一个已存在容器的网络栈 中,新容器进程有自己的文件系统、进程列表和资源限制,但会和已存在的容器共享 IP地址和端口等网络资源,两者进程可以直接通过 lo 环回接口通信。
  • –net=none 让 Docker 将新容器放到隔离的网络栈中,但是不进行网络配置。之后,用户可以自己进行配置。

网络配置细节

用户使用 --net=none 后,可以自行配置网络,让容器达到跟平常一样具有访问网络的权 限。通过这个过程,可以了解 Docker 配置网络的细节。

首先,启动一个 /bin/bash 容器,指定 --net=none 参数。

$ docker run -i -t --rm --net=none base /bin/bash
root@63f36fc01b5f:/#

在本地主机查找容器的进程 id,并为它创建网络命名空间。

$ docker inspect -f '{{.State.Pid}}' 63f36fc01b5f

$ pid=
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid

检查桥接网卡的 IP 和子网掩码信息。

$ ip addr show docker0
: docker0: ...
inet 172.17.42.1/ scope global docker0

创建一对 “veth pair” 接口 A 和 B,绑定 A 到网桥 docker0,并启用它

$ sudo ip link add A type veth peer name B
$ sudo brctl addif docker0 A
$ sudo ip link set A up

将B放到容器的网络命名空间,命名为 eth0,启动它并配置一个可用 IP(桥接网段)和默认 网关

$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/ dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1

以上,就是 Docker 配置网络的具体过程。

当容器结束后,Docker 会清空容器,容器内的 eth0 会随网络命名空间一起被清除,A 接口也 被自动从 docker0 卸载。

此外,用户可以使用 ip netns exec 命令来在指定网络命名空间中进行配置,从而配置容器 内的网络。

Docker底层架构之网络实现的更多相关文章

  1. Docker底层架构之简介

    简介 Docker 底层的核心技术包括 Linux 上的命名空间(Namespaces) 控制组(Control groups) Union 文件系统(Union file systems) 容器格式 ...

  2. Docker底层架构之命名空间

    前言 命名空间是 Linux 内核一个强大的特性.每个容器都有自己单独的命名空间,运行在其中的 应用都像是在独立的操作系统中运行一样.命名空间保证了容器之间彼此互不影响.相应的命名空间功能如下: pi ...

  3. Docker底层架构之基础架构

    Docker 采用了 C/S架构,包括客户端和服务端. Docker daemon 作为服务端接受来自客户 的请求,并处理这些请求(创建.运行.分发容器). 客户端和服务端既可以运行在一个机器上,也可 ...

  4. Docker底层架构之容器格式

    最初,Docker 采用了 LXC 中的容器格式.自 1.20 版本开始,Docker 也开始支持新的 libcontainer 格式,并作为默认选项.

  5. Docker底层架构之联合文件系统

    联合文件系统(UnionFS)是一种分层.轻量级并且高性能的文件系统,它支持对文件系统的 修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several di ...

  6. Docker底层架构之控制组

    概述 控制组(cgroups)是 Linux 内核的一个特性,主要用来对共享资源进行隔离.限制.审计 等. 只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争. 控制组技术最早 ...

  7. Docker技术底层架构剖析

    [Docker  底层技术] docker底层的 2 个核心技术分别是 Namespaces 和 Control groups 在操作系统中,网络配置,进程,用户,IPC(进程之间的调用)等信息之间的 ...

  8. Docker 基础底层架构浅谈

    docker学习过程中,免不了需要学习下docker的底层技术,今天我们来记录下docker的底层架构吧! 从上图我们可以看到,docker依赖于linux内核的三个基本技术:namespaces.C ...

  9. 04 . Docker安全与Docker底层实现

    Docker安全 Docker安全性时,主要考虑三个方面 # 1. 由内核的名字空间和控制组机制提供的容器内在安全 # 2. Docker程序(特别是服务端)本身的抗攻击性 # 3. 内核安全性的加强 ...

随机推荐

  1. 工厂设计模式灵魂拷问-Java实现

    show me the code and take to me,做的出来更要说的明白 GitHub项目JavaHouse同步收录 喜欢就点个赞呗! 你的支持是我分享的动力! 引入 我们经常听到工厂模式 ...

  2. echarts实现group关系图案例

    官网案例:https://www.echartsjs.com/examples/zh/editor.html?c=graph-simple 自己在项目中实现了两个group图: 1.先看实现效果,两个 ...

  3. 洛谷$P3302$ 森林 $[SDOI2013]$ 主席树

    正解:主席树 解题报告: 传送门! 口胡一时爽代码火葬场 这题想法不难,,,但显然的是代码应该还挺难打的 但反正我也不放代码,就写下题解趴$QwQ$ 第一问就是个$Count\ on\ a\ tree ...

  4. Pillow库来着

    第一步肯定是安装啦 pip install pillow 如果安装报错,可以升级一下pip库,因为有可能是pip版本低了......... pip show pip 升级用 python -m pip ...

  5. 「学习笔记」动态规划 I『初识DP』

    写在前面 注意:此文章仅供参考,如发现有误请及时告知. 更新日期:2018/3/16,2018/12/03 动态规划介绍 动态规划,简称DP(Dynamic Programming) 简介1 简介2 ...

  6. java数据结构之常用排序算法

    冒泡排序 private void maopao(int arr[]) { for (int i = 0; i < arr.length; i++) { for (int j = 0; j &l ...

  7. 配置本地目录作为yum端

    ---恢复内容开始--- 最近在配置gnome-session中发现需要太多依赖的包,又由于实验室使用的是局域网,没有办法连接网络,所以想着配置本地yum安装.在网上找了一些资料,经过整理,把自己这次 ...

  8. SpringBoot-2.1.1系列一:使用https

    1.什么是https? HTTPS中文名称:超文本传输安全协议,是以安全为目标的HTTP通道,简单讲是HTTP的安全版.即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要 ...

  9. JVM之对象

    几乎所有对象都是在堆中分配内存的,这次来讲讲java的对象. 对象的创建主要分为以下几步: 首先,查看类是否装载.当JVM读取到new指令的时候,会拿着符号描述去方法区寻找它所属的类,如果未查找到,则 ...

  10. 学以致用,react学习前奏准备阶段

    ReactJS:支持React开发,提供JSX代码提示,高亮显示,ReactJS官方介绍 1.cdm→  componentDidMount: fn() { ... }   cdm 2.cdup→  ...