Docker、K8S网络工作原理
一、Docker 网络模式
在讨论 Kubernetes 网络之前,让我们先来看一下 Docker 网络。Docker 采用插件化的网络模式,默认提供 bridge、host、none、overlay、maclan 和 Network plugins 这几种网络模式,运行容器时可以通过–network 参数设置具体使用那一种模式。
bridge:这是Docker默认的网络驱动,此模式会为每一个容器分配Network Namespace和设置IP等,并将容器连接到一个虚拟网桥上。如果未指定网络驱动,这默认使用此驱动。
host:此网络驱动直接使用宿主机的网络。
none:此驱动不构造网络环境。采用了none 网络驱动,那么就只能使用loopback网络设备,容器只能使用127.0.0.1的本机网络。
overlay:此网络驱动可以使多个Docker daemons连接在一起,并能够使用swarm服务之间进行通讯。也可以使用overlay网络进行swarm服务和容器之间、容器之间进行通讯,
macvlan:此网络允许为容器指定一个MAC地址,允许容器作为网络中的物理设备,这样Docker daemon就可以通过MAC地址进行访问的路由。对于希望直接连接网络网络的遗留应用,这种网络驱动有时可能是最好的选择。
Network plugins:可以安装和使用第三方的网络插件。可以在Docker Store或第三方供应商处获取这些插件。
在默认情况,Docker 使用 bridge 网络模式,bridge 网络驱动的示意图如下,此文以bridge 模式对 Docker 的网络进行说明。
1.1 bridge网络的构建过程
1)安装Docker时,创建一个名为 docke0 的虚拟网桥,虚拟网桥使用“10.0.0.0 -10.255.255.255 “、”172.16.0.0-172.31.255.255″和“192.168.0.0——192.168.255.255”这三个私有网络的地址范围。
通过 ifconfig 命令可以查看 docker0 网桥的信息:
通过 docker network inspect bridge 可以查看网桥的子网网络范围和网关:
2)运行容器时,在宿主机上创建虚拟网卡 veth pair 设备,veth pair 设备是成对出现的,从而组成一个数据通道,数据从一个设备进入,就会从另一个设备出来。
将veth pair设备的一端放在新创建的容器中,命名为eth0;另一端放在宿主机的docker0中,以veth为前缀的名字命名。通过 brctl show 命令查看放在docker0中的veth pair设备。
1.2 外部访问
bridge 的 docker0 是虚拟出来的网桥,因此无法被外部的网络访问。因此需要在运行容器时通过 -p 和 -P 参数对将容器的端口映射到宿主机的端口。实际上 Docker 是采用 NAT的方式,将容器内部的服务监听端口与宿主机的某一个端口 port 进行绑定,使得宿主机外部可以将网络报文发送至容器。1)通过-P参数,将容器的端口映射到宿主机的随机端口:
$ docker run -P {images}
2)通过-p参数,将容器的端口映射到宿主机的制定端口:
$ docker run -p {hostPort}:{containerPort} {images}
二、Kubernetes 网络模式
Kubernetes与Docker网络有些不同。Kubernetes网络需要解决下面的4个问题:
集群内:
容器与容器之间的通信
Pod和Pod之间的通信
Pod和服务之间的通信
集群外:
- 外部应用与服务之间的通信
因此,Kubernetes假设Pod之间能够进行通讯,这些Pod可能部署在不同的宿主机上。每一个Pod都拥有自己的IP地址,因此能够将Pod看作为物理主机或者虚拟机,从而能实现端口设置、命名、服务发现、负载均衡、应用配置和迁移。为了满足上述需求,则需要通过集群网络来实现。在本文主要分析容器与容器之间,以及Pod和Pod之间的通信;Pod和服务之间,以及外部应用与服务之间的通信请参考《Kubernetes-核心资源之Service》和《Kubernetes-核心资源之Ingress》。
2.1 同一个 Pod 中容器之间的通信
这种场景对于Kubernetes来说没有任何问题,根据Kubernetes的架构设计。Kubernetes 创建 Pod 时,首先会创建一个 pause 容器,为 Pod 指派一个唯一的IP地址。然后,以pause的网络命名空间为基础,创建同一个Pod内的其它容器(–net=container:xxx)。因此,同一个Pod内的所有容器就会共享同一个网络命名空间,在同一个Pod之间的容器可以直接使用localhost进行通信。
2.2 不同 Pod 中容器之间的通信
对于此场景,情况现对比较复杂一些,这就需要解决 Pod 间的通信问题。在Kubernetes 通过 flannel、calic 等网络插件解决 Pod 间的通信问题。本文以 flannel 为例说明在 Kubernetes 中网络模型,flannel 是 kubernetes 默认提供网络插件。Flannel 是由 CoreOS 团队开发社交的网络工具,CoreOS 团队采用 L3 Overlay 模式设计 flannel, 规定宿主机下各个Pod属于同一个子网,不同宿主机下的Pod属于不同的子网。
flannel会在每一个宿主机上运行名为flanneld代理,其负责为宿主机预先分配一个子网,并为Pod分配IP地址。Flannel使用Kubernetes或etcd来存储网络配置、分配的子网和主机公共IP等信息。数据包则通过VXLAN、UDP或host-gw这些类型的后端机制进行转发。
2.3 Flannel 在 K8S 中运行的整体过程
1)设置集群网络flannel默认使用etcd作为配置和协调中心,首先使用etcd设置集群的整体网络。通过如下的命令能够查询网络配置信息:
$ etcdctl ls /coreos.com/network/config
2)设置 Node 节点上的子网
基于在 etcd 中设置的网络,flannel 为每一个 Node 分配 IP 子网。
获取子网列表
$ etcdctl ls /coreos.com/network/subnets
获取子网信息
$ etcdctl ls /coreos.com/network/subnets/{IP网段}
3)在每个 Node 上启动 flanneld
flannel 在每个 Node 上启动了一个 flanneld 的服务,在flanneld启动后,将从etcd中读取配置信息,并请求获取子网的租约。所有 Node 上的 flanneld 都依赖 etcd cluster 来做集中配置服务,etcd 保证了所有node 上 flanned 所看到的配置是一致的。同时每个 node 上的 flanned 监听etcd上的数据变化,实时感知集群中node的变化。flanneld一旦获取子网租约、配置后端后,会将一些信息写入/run/flannel/subnet.env文件。
$ cat /var/run/flannel/subnet.env
4)创建虚拟网卡
在Node节点上,会创建一个名为flannel.1的虚拟网卡。
$ ip addr show flannel.1
5)创建Docker网桥
并为容器配置名为docker0的网桥,实际是通过修改Docker的启动参数–bip来实现的。通过这种方式,为每个节点的Docker0网桥设置在整个集群范围内唯一的网段,从保证创建出来的Pod的IP地址是唯一。
$ ip addr show docker0
6)修改路由表
flannel会对路由表进行修改,从而能够实现容器跨主机的通信。
$ route -n
2.4 数据传递过程
在源容器宿主机中的数据传递过程:
1)源容器向目标容器发送数据,数据首先发送给 docker0 网桥
在源容器内容查看路由信息:
$ kubectl exec -it -p {Podid} -c {ContainerId} -- ip route
2)docker0 网桥接受到数据后,将其转交给 flannel.1 虚拟网卡处理
docker0 收到数据包后,docker0的内核栈处理程序会读取这个数据包的目标地址,根据目标地址将数据包发送给下一个路由节点:
查看源容器所在Node的路由信息:
$ ip route
3)flannel.1 接受到数据后,对数据进行封装,并发给宿主机的 eth0
flannel.1收到数据后,flannelid会将数据包封装成二层以太包。
Ethernet Header的信息:
From:{源容器flannel.1虚拟网卡的MAC地址}
To:{目录容器flannel.1虚拟网卡的MAC地址}
4)对在flannel路由节点封装后的数据,进行再封装后,转发给目标容器 Node 的 eth0
由于目前的数据包只是vxlan tunnel上的数据包,因此还不能在物理网络上进行传输。因此,需要将上述数据包再次进行封装,才能源容器节点传输到目标容器节点,这项工作在由linux内核来完成。Ethernet Header 的信息:
- From: {源容器 Node 节点网卡的 MAC 地址}
- To: {目录容器 Node 节点网卡的 MAC 地址}
IP Header的信息:
From:{源容器Node节点网卡的IP地址}
To:{目录容器Node节点网卡的IP地址}
通过此次封装,就可以通过物理网络发送数据包。
在目标容器宿主机中的数据传递过程:
5)目标容器宿主机的eth0接收到数据后,对数据包进行拆封,并转发给flannel.1虚拟网卡;
6)flannel.1 虚拟网卡接受到数据,将数据发送给docker0网桥;
7)最后,数据到达目标容器,完成容器之间的数据通信。
Docker、K8S网络工作原理的更多相关文章
- K8s的工作原理
title: Kubernetes之初探 subtitle: K8s的工作原理 date: 2018-09-18 18:26:37 --- K8s概述 我清晰地记得曾经读到过的一篇博文,上面是这样写的 ...
- Docker 架构及工作原理
通过下图可以得知,Docker 在运行时分为 Docker 引擎(服务端守护进程) 和 客户端工具,我们日常使用各种 docker 命令,其实就是在使用 客户端工具 与 Docker 引擎 进行交互. ...
- Docker基本命令及工作原理
第一个Docker容器 1.首先确保Docker运行正常:docker info
- 用一个实际例子理解Docker volume工作原理
要了解Docker Volume,首先我们需要理解Docker文件系统的工作原理.Docker镜像是由多个文件系统的只读层叠加而成.当一个容器通过命令docker run启动时,Docker会加载只读 ...
- Docker基础 :网络配置详解
本篇文章将讲述 Docker 的网络功能,包括使用端口映射机制来将容器内应用服务提供给外部网络,以及通过容器互联系统让多个容器之间进行快捷的网络通信,有兴趣的可以了解下. 大量的互联网应用服务包含多个 ...
- docker容器网络bridge
我们知道docker利用linux内核特性namespace实现了网络的隔离,让每个容器都处于自己的小世界里面,当这个小世界需要与外界(宿主机或其他容器)通信的时候docker的网络就发挥作用了,这篇 ...
- 【k8s】基础概念 + 工作原理
工作原理: 原理图 工作原理描述: 1>用户通过kubectl或者API server的REST API接口,提交需要运行的docker容器(创建pod请求): 2>api server将 ...
- 11.深入k8s:kubelet工作原理及源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 kubelet信息量是很大的,通过我这一篇文章肯定是讲不全的,大家可 ...
- k8s原来这么简单(一)核心组件与工作原理
k8s官方文档:https://kubernetes.io/zh/docs/home/ 前提 掌握容器技术:Docker,Containerd等 K8S优势 使用简单,少量人/小团队可以轻松维护大型 ...
随机推荐
- mysql字符串类型(char,varchar)
原文链接:https://blog.csdn.net/puqutogether/article/details/45648879 MySQL中的字符串有两个常用的类型:char和varchar,二者各 ...
- 图解MySQL索引(三)—如何正确使用索引?
MySQL使用了B+Tree作为底层数据结构,能够实现快速高效的数据查询功能.工作中可怕的是没有建立索引,比这更可怕的是建好了索引又没有使用到.本文将围绕着如何优雅的使用索引,图文并茂地和大家一起探讨 ...
- Ngnix 配置文件快速入门
转自https://www.cnblogs.com/knowledgesea/p/5175711.html 其实也没什么好说的,我想大部分人也不会在意nginx的实现原理啥的.服务器要部署的时候,把n ...
- PHP丨PHP基础知识之流程控制for循环「理论篇」
今天公司同事在看for循环,那么我们今天就来讲讲for循环吧! for循环是编程语言中一种循环语句,而循环语句由循环体及循环的判定条件两部分组成,其表达式为:for(单次表达式;条件表达式;末尾循环体 ...
- c++11新特性注意点
本文记录下一些c++11新特性需要注意的方面,供日后参考 一.auto auto可以当成“占位符”,根据右边的类型自动推导出变量的类型.需要注意的是 auto不能解决溢出的问题. auto可以与指针和 ...
- redis编译报错总结
redis编译报错总结: 1.不能编译没有GCC 编译工具安装报错:问题1:make时可能会报如下错误cc -c -std=c99 -pedantic -O2 -Wall -W -g -rdyna ...
- 线程基础9-quene讲解
在学习Java 多线程并发开发过程中,了解到DelayQueue类的主要作用:是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走. ...
- Day11-微信小程序实战-交友小程序-附近的人(地图的形式)及位置获取
回顾:在下面的tabbar中,我们已经实现了首页 消息 我的,就剩下”附近“页面了 ”附近“的页面主要是用地图来进行展示的(可以显示我的位置,也可以显示周围附近的人的位置) (在地图里面点击它的头像的 ...
- WAF产品记录
WAF产品化 2011-1-13 目标:稳定的版本 和 标准的手册 1.硬件差异问题,争取了OEM提供硬件样机. 2.OEM功能本来在我们手里,为了更好产品化,配合移交工作. 3.我们做好 产品生 ...
- 入门大数据---Kafka的搭建与应用
前言 上一章介绍了Kafka是什么,这章就讲讲怎么搭建以及如何使用. 快速开始 Step 1:Download the code Download the 2.4.1 release and un-t ...