Docker 的网络实现其实就是利用了 Linux 上的网络名字空间和虚拟网络设备(特别是 veth pair)。建议先熟悉了解这两部分的基本概念再阅读本章。

基本原理

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

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 参数。

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

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

$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
2778
$ pid=2778
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid

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

$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 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/16 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(5):Docker 网络

    本系列文章将介绍 Docker的相关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...

  2. docker网络配置方法总结

    docker启动时,会在宿主主机上创建一个名为docker0的虚拟网络接口,默认选择172.17.42.1/16,一个16位的子网掩码给容器提供了65534个IP地址.docker0只是一个在绑定到这 ...

  3. 【转】Docker网络详解及pipework源码解读与实践

    好文必转 原文地址: http://www.infoq.com/cn/articles/docker-network-and-pipework-open-source-explanation-prac ...

  4. Docker网络模式

    [编者的话] 本文是<Docker网络及服务发现>一书的一个章节,介绍了搭建Docker单主机网络的基础内容.关于Docker网络的更多内容,包括多主机的网络,请参考该书的其他章节. @C ...

  5. docker网络-如何让外部网络访问容器资源

    docker网络-如何让外部网络访问容器资源 安装httpd 服务: docker:/root# docker exec -it f63b2633d146 bash bash-4.1# yum ins ...

  6. docker网络解析

    Docker概念和默认网络 什么是Docker网络呢?总的来说,网络中的容器们可以相互通信,网络外的又访问不了这些容器.具体来说,在一个网络中,它是一个容器的集合,在这个概念里面的一个容器,它会通过容 ...

  7. docker网络访问(三)

    docker网络访问 ifconfig查看网卡,启动docker的时候,docker会帮我们创建一个docker0的网桥. 1.随机映射 docker run -P 2.指定映射 -p hostPor ...

  8. [Docker网络]模拟一台交换机的拓扑

    [Docker网络]模拟一台交换机的拓扑 本例主要对Docker网络进行实际运用. 背景介绍 一台虚拟机如何模拟成一台多端口交换机分别连接多台虚拟机? bridge网桥技术 实验准备 docker d ...

  9. Docker 网络之理解 bridge 驱动

    笔者在前文<Docker 网络之进阶篇>中介绍了 CNM(Container Network Model),并演示了 bridge 驱动下的 CNM 使用方式.为了深入理解 CNM 及最常 ...

  10. Docker 网络之进阶篇

    笔者在<Docker 基础 : 网络配置>一文中简单介绍了容器网络的基本用法,当时网络的基本使用方式还处于 --link 阶段.时过境迁,随着 docker 的快速发展,其网络架构也在不断 ...

随机推荐

  1. nginx和nfs

    1.安装nginx #yum install epel-release -y #yum install nginx -y #vim /usr/local/nginx/conf/nginx.conf - ...

  2. HTML常用布局---新浪布局

    MarkdownPad Document/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) *//* Author: Nicol ...

  3. (CLR-Via-C#) 类型基础

    CLR要求每个类型最终都派生自System.Object Object提供的公共方法: Equals: 如果两个对象具有相同的值,就返回true GetHashCode: 返回对象的哈希码 ToStr ...

  4. Spring(5)——Spring 和数据库编程

    传统 JDBC 回顾 JDBC 我们一定不陌生,刚开始学习的时候,我们写过很多很多重复的模板代码: public Student getOne(int id) { String sql = " ...

  5. html5之表格元素

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 初试GH-OST

    最近老板让做一个gh-ost和pt-osc 的对比测试,本文将对两者做对比. 一.原理和所用说明   PT-OSC GH-OST 原理 1.创建一个和要执行 alter 操作的表一样的新的空表结构(是 ...

  7. vue的入门/简介

    vue 特点 1. 响应的数据绑定/响应式编程  2. 组件化 vue优点 1. 轻量级的框架  2. 简单易学 3. 双向数据绑定 4. 组件化 5. 视图,数据,结构分离 6. 虚拟DOM 7. ...

  8. 【Android】Mac下Android Studio设置App启动页

    先将启动页放到项目资源中,图片一般是1080*1920的jpg. 新建一个activity,如图: 创建成功之后,打开刚刚创建的activity,来进行代码的编写: public class BZLa ...

  9. bzoj 2437: [Noi2011]兔兔与蛋蛋

    Description Solution 考虑犯错误的条件:之前是处于必胜状态,该操作之后就变成了必败状态. 我们可以把这个过程看成两人对网格图进行黑白染色,变成了一个二分图模型,即当前位置向相邻不同 ...

  10. ●BZOJ 2337 [HNOI2011]XOR和路径

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2337题解: 概率dp, 因为异或的每一位之间没有关系,我们就依次考虑每一位k.(即边权要么为 ...