Kubernetes-基于flannel的集群网络
1、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}
2、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这些类型的后端机制进行转发。

看一下flannel在Kubernetes中运行的整体过程:
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上启动flannelid
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.3 数据传递过程
在源容器宿主机中的数据传递过程:
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)最后,数据到达目标容器,完成容器之间的数据通信。
参考资料
1.《Cluster Networking》地址:https://kubernetes.io/docs/concepts/cluster-administration/networking/
2.《Running flannel》地址:https://github.com/coreos/flannel/blob/master/Documentation/running.md
3.《理解Kubernetes网络之Flannel网络》 作者:Tony Bai 地址:https://tonybai.com/2017/01/17/understanding-flannel-network-for-kubernetes/
作者简介:
季向远,北京神舟航天软件技术有限公司产品经理。本文版权归原作者所有。
Kubernetes-基于flannel的集群网络的更多相关文章
- 搞定 Kubernetes 基于flannel 的集群网络
.Docker网络模式 在讨论Kubernetes网络之前,让我们先来看一下Docker网络.Docker采用插件化的网络模式,默认提供bridge.host.none.overlay.maclan和 ...
- Kubernetes 使用kubeadm创建集群
镜像下载.域名解析.时间同步请点击 阿里巴巴开源镜像站 实践环境 CentOS-7-x86_64-DVD-1810 Docker 19.03.9 Kubernetes version: v1.20.5 ...
- 理解OpenShift(7):基于 Prometheus 的集群监控
理解OpenShift(1):网络之 Router 和 Route 理解OpenShift(2):网络之 DNS(域名服务) 理解OpenShift(3):网络之 SDN 理解OpenShift(4) ...
- 使用Kubeadm搭建Kubernetes(1.12.2)集群
Kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,在2018年将进入GA状态,说明离生产环境中使用的距离越来 ...
- 使用国内的镜像源搭建 kubernetes(k8s)集群
1. 概述 老话说的好:努力学习,提高自己,让自己知道的比别人多,了解的别人多. 言归正传,之前我们聊了 Docker,随着业务的不断扩大,Docker 容器不断增多,物理机也不断增多,此时我们会发现 ...
- 基于k8s的集群稳定架构-转载
基于k8s的集群稳定架构-转载 前言 我司的集群时刻处于崩溃的边缘,通过近三个月的掌握,发现我司的集群不稳定的原因有以下几点: 1.发版流程不稳定 2.缺少监控平台[最重要的原因] 3.缺少日志系统 ...
- Kubernetes自动横向伸缩集群节点以及介绍PDB资源
在kubernetes中,有HPA在需要的时候创建更多的pod实例.但万一所有的节点都满了,放不下更多pod了,怎么办?显然这个问题并不局限于Autoscaler创建新pod实例的场景.即便是手动创建 ...
- 基于puppet分布式集群管理公有云多租户的架构浅谈
基于puppet分布式集群管理公有云多租户的架构浅谈 一.架构介绍 在此架构中,每个租户的业务集群部署一台puppet-master作为自己所在业务集群的puppet的主服务器,在每个业务集群所拥 ...
- 利用ansible来做kubernetes 1.10.3集群高可用的一键部署
请读者务必保持环境一致 安装过程中需要下载所需系统包,请务必使所有节点连上互联网. 本次安装的集群节点信息 实验环境:VMware的虚拟机 IP地址 主机名 CPU 内存 192.168.77.133 ...
随机推荐
- Lucene 09 - 什么是Lucene的高亮显示 + Java API实现高亮显示
目录 1 什么是高亮显示 2 高亮显示实现 2.1 配置pom.xml文件, 加入高亮显示支持 2.2 代码实现 2.3 自定义html标签高亮显示 1 什么是高亮显示 高亮显示是全文检索的一个特点, ...
- SpringBoot入门教程(十三)CORS方式实现跨域
什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域 . 跨域资源访问是经常会遇到的场景,当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资 ...
- Chapter 5 Blood Type——31
I stood carefully, and I was still fine. He held the door for me, his smile polite but his eyes mock ...
- innodb是如何巧妙实现事务隔离级别
之前的文章mysql锁机制详解中我们详细讲解了innodb的锁机制,锁机制是用来保证在并发情况下数据的准确性,而要保证数据准确通常需要事务的支持,而mysql存储引擎innodb是通过锁机制来巧妙地实 ...
- 精读《react-easy-state 源码》
1. 引言 react-easy-state 是个比较有趣的库,利用 Proxy 创建了一个非常易用的全局数据流管理方式. import React from "react"; i ...
- yum仓库的创建
这篇博客是yum仓库的配置过程,如果是yum客户端配置请参考 http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_linux_002.html 1 环境介 ...
- [五] JavaIO之InputStream OutputStream简介 方法列表说明
InputStream 和 OutputStream 对于字节流的输入和输出 是作为协议的存在 所以有必要了解下这两个类提供出来的基本约定 这两个类是抽象类,而且基本上没什么实现,都是依赖于子类具 ...
- [SDOI2018] 战略游戏
Description 给定一张 \(n\) 个点 \(m\) 条边的无向联通图,共有 \(q\) 次操作,每次操作选择一些点作为关键点,询问有多少个点满足删去该点及与其相邻的边后,至少有两个关键点不 ...
- Flask入门第三天
一.数据库操作 1,orm orm(object-Relation Mapping),对象-关系映射,主要实现模型对象到关系数据库数据的映射. 优点: - 只需要面向对象编程, 不需要面向数据库编写代 ...
- Mac终端工具item2实现覆盖在屏幕上透明效果
1.去官网安装item2: https://www.iterm2.com/downloads.html 2.打开preferences 3.到keys配置: 4.点击上图展示的Create a Ded ...