Docker底层架构之网络实现

前言

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
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 命令来在指定网络命名空间中进行配置,从而配置容器 内的网络。

转载于:https://www.cnblogs.com/guge-94/p/11064643.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Docker是一个开源的容器化平台,它使用了一种轻量级的虚拟化技术,可以将应用程序及其依赖项打包成一个独立的容器,提供了更高效、更可靠的应用部署和管理方式。 Docker的系统架构包含以下几个关键组件: 1. Docker守护进程(Docker daemon):Docker守护进程是Docker引擎的核心组件,负责管理镜像、容器和存储等资源。守护进程通过RESTful API与其他组件通信,并执行用户指定的命令。 2. Docker客户端(Docker client):Docker客户端是用户与Docker守护进程进行交互的接口。用户可以通过命令行工具或者Docker提供的API进行操作,例如创建、启动、停止和删除容器等。 3. Docker镜像(Docker image):Docker镜像是一个只读的模板,包含了运行应用程序所需的文件系统、环境变量和依赖项等。镜像可以由基础镜像构建而来,也可以通过Dockerfile定义构建步骤。 4. 容器(Container):容器是基于镜像创建的实例,它是运行应用程序的独立环境。Docker利用Linux内核的隔离技术,如命名空间和控制组,来实现容器与宿主机之间的资源隔离。每个容器都有自己的文件系统、网络和进程空间,可以独立运行和管理。 5. 注册中心(Registry):注册中心是存储和共享Docker镜像的服务器。Docker Hub是最常用的公共注册中心,用户可以从中获取各种官方和社区贡献的镜像。除了公共注册中心,用户还可以搭建自己的私有注册中心。 6. Docker网络(Docker networking):Docker提供了多种网络驱动程序,用于为容器提供网络连接。例如,桥接驱动程序可以创建一个本地网络,将容器连接到宿主机上的网桥设备,以实现容器之间的通信。 总之,Docker的系统架构基于容器化技术,通过守护进程、客户端、镜像、容器、注册中心和网络等组件配合工作,为用户提供了一种便捷、高效的应用部署和管理方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值