前言

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. 19.yield和send的区别

    转载:https://www.jianshu.com/p/ccb5e7da3fd8 https://www.cnblogs.com/xhcdream/p/8304953.html https://ww ...

  2. Liquibase 使用(全)

    聊一个数据库脚本的版本工具 Liquibase,官网在这里 ,初次看到,挺神奇的,数据库脚本也可以有版本管理,同类型的工具还有 flyway . 开发过程经常会有表结构和变更,让运维来维护的话,通常会 ...

  3. flask修改数据库字段的类型和长度

    flask修改数据库字段的类型和长度 ​ 在将models中的字段的db.String(256)修改为db.String(1024)后,执行migrate和upgrade操作后,发现数据库并没有更新, ...

  4. 【C++】几个简单课本例题

    // // main.cpp // 2_1 // // Created by T.P on 2018/2/28. // Copyright © 2018年 T.P. All rights reserv ...

  5. 在Windows Server 2003中搭建DNS服务器

    1.安装Windows Server 2003虚拟机 准备好Windows Server 2003的镜像:http://www.downza.cn/soft/184944.html 2.Windows ...

  6. 《图解机器学习-杉山将著》读书笔记---CH1

    CH1 什么是机器学习 重点提炼 机器学习的种类: 常分为:监督学习.无监督学习.强化学习等 监督学习是学生从老师那获得知识,老师提供对错指示 无监督学习是在没有老师的情况下,学生自习 强化学习是在没 ...

  7. static和final关键字

    static关键字 静态变量 静态变量:又称做类变量,也就是这个变量属于整个类,而不属于单个实例.类所有的实例共享静态变量,可以直接通过类名来访问它.静态变量在内存中只存在一份,当系统第一次加载类时, ...

  8. 【原创】(十六)Linux内存管理之CMA

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  9. 解决httpclient设置代理ip之后请求无响应的问题

    httpclient这个工具类对于大家来说应该都不陌生吧,最近在使用过程中出现了碰到一个棘手的问题,当请求的接口地址由http变成https之后,程序执行到 httpClient.execute(ht ...

  10. 使用redis的zset实现高效分页查询(附完整代码)

    一.需求 移动端系统里有用户和文章,文章可设置权限对部分用户开放.现要实现的功能是,用户浏览自己能看的最新文章,并可以上滑分页查看. 二.数据库表设计 涉及到的数据库表有:用户表TbUser.文章表T ...