Kubernetes 网络组件 Flannel 源码分析

Kubernetes 作为容器编排工具的代表,已经成为了云原生时代的核心技术之一。而其中最基础的网络组件 Flannel,也是 Kubernetes 中最重要的一部分。本文将深入分析 Flannel 的原理和源码实现,以及如何在实际应用中使用。

Flannel 简介

Flannel 是一个基于 VXLAN 和 UDP 的网络覆盖方案,可以为 Kubernetes 集群提供 IP 地址管理和通信功能,是 Kubernetes 网络模型中 CNI 的一种实现。Flannel 可以动态为 Pod 分配 IP,并提供网络层隔离和跨主机通信,为整个集群提供了内部通信的支持。

Flannel 的实现依赖于 etcd 存储,可以使用 etcd 存储 IP 地址和其他一些配置信息,这些信息可以动态地根据集群的情况进行调整,保证了整个集群内部的通信效率。

Flannel 的原理

Flannel 的核心原理是将不同主机上的 Pod 所属的虚拟子网(VPC)映射到相同的网络中,并通过 VXLAN 进行通信。Flannel 的工作流程如下图所示:

Flannel 中每个主机对应一个 flanneld 进程,flanneld 进程有两个主要功能:

  1. 作为网络命名空间(NetNS)的 Master,创建并管理虚拟网卡(Veth pair)

  2. 作为 VXLAN 隧道的 Endpoint,接收并处理来自其他节点的数据包

Flannel 在启动时,会默认创建一个 flannel.1 的虚拟子网,并将其分配给当前节点。节点之间通过 VXLAN 隧道来通信,每个 VXLAN Tunnel 使用一个不同的 VNI(Virtual Network Identifier)来区分不同的虚拟网络,这样不同的虚拟网络就可以在同一个物理网络中独立运行,避免混淆。

当一个 Pod 启动时,首先会向 Flannel 发起请求,Flannel 会从 etcd 中获取可用的 IP 地址,并将其分配给 Pod。Pod 包装成数据包后通过节点上的 veth0 接口发送到 Flannel,Flannel 通过 vxlan0 接口封装数据,在 VXLAN 层加上 VNI 和远端节点的 IP 地址信息,发往接收方所在节点的 flanneld 进程进行解封装,最终将数据包交给接收方的 veth0 接口。

Flannel 的源码实现

Flannel 的源码托管在 Github 上,可以克隆代码库进行学习和研究。代码库的主要结构如下:

-------
--- ---------
--- ---
--- ------
--- -----
--- ------
--- ---
    --- -------
    --- ----
    --- ----
    --- ------
    --- -----

Flannel 主要分为以下几个模块:

  • etcd:使用 etcd 作为网络配置信息的存储和分发中心
  • ipam:负责 IP 地址的分配和管理
  • subnet:虚拟子网的创建和管理
  • vxlan:VXLAN 隧道的创建和管理

以 VXLAN 为例,来分析 Flannel 的源码实现。VXLAN 是 Flannel 中最核心的模块之一,VXLAN 以 vxlan.go 的形式进行了实现。Flannel 中的 VXLAN 模块主要完成了以下几个功能:

  • 创建和销毁 VXLAN 设备
  • 发送和接收 VXLAN 数据包
  • 生成 VXLAN 头部(Header)

VXLAN 设备的创建和销毁可以通过 Linux 的命令行工具实现(ip link add/delete),Flannel 中借助 Go 语言的网络库(netlink)封装了这些操作,将 VXLAN 的创建和销毁过程集成到了 flanneld 的启动和结束中。

---- ----------- ------ -
  ---- ------
  --   ------
  --   --------
-

---- --- ------------- ------------------------ ------- ---- ------ -
  --- -
    -   -------------
    --- -------
  -

  ---- --- - ---------
  -- --- -- --- -
    ------ ------------------ -- --- ----- -------- --- ---- ----
  -

  ---------------- - -------
  --------- - ----------
  -------------- - -
  --------- - ---
  --------- - ------
  ----- - -

  -- --- - --------------------------
  -- --- -- --- -
    ------ ------------------ -- --- --------- ---- -------
  -

  -- --- - -------------------- --- -- --- -
    ---
  -

  -- --- --- -- --------------------------- --- -- --- -
    -- --- - ------------------------- ---- --- -- --- -
      ---
    -
  -

  ------ --- - -------------------------------------------- --------- ---------- --
  -- --- -- --- -
    ---
  -

  ------
-

而发送和接收数据包则主要是通过 UDP 完成的,VXLAN 将内部的数据包封装成 UDP 数据包进行发送,对端节点通过监听相应的 UDP 端口接收数据包,然后对 VNI 进行判断,解封并将数据包传到对应的 namespace 中。

---- -- ------- ------- ---------------- ----- -
  -- --- -- ------------------------------------- ---------------
  -- --- -- --- -
    ---
  -

  ----- ---------

  --- -
    ------ -
    ---- -------------
      ------ ---
    --------
      --- -- ------------ ----------
      -------------------------------------------------------
      -- ----- --- -- ---------------
      ---
      -- --- -- ------------------ ----- ------- ------- ------------ --- -- --- -
        ---
      -
    -
  -
-

---- -- ------- ------------- ------- ---- --------- ------- ------ ----------------- ---------- ------- ----- -
  ---
  -- ---- ----- ------
  ----- -- ------------------

  -- ------------- -- --- ----- --- --- ---
  -- ----------------------- -- ---------- -- ----------- -- ------------- -
    ------ ---
  -

  ------ - -----------
  ------------ --- -- -------------------------
  ---
  --- -- ---------
    ------ -------------
      ------ ------- -- ----- --- ---------- --- ---- -- -------
      ----   -----------------------
      ----   -------
      ----   -------
    --
    -------- --
  ------------

  -- --- - ----------------------------------------- -------
  ---

  ----- --- -- ------------------ -------------
    ---   -------
    ----- ---------------
  --
  ---
-

生成 VXLAN 头部是 Flannel 中最核心的部分之一,VXLAN 的头部 Designator 部分包含两个比特的标志和24比特的 Virtual Network Identifier(VNI),其余部分和 Ethernet Frame 头相同。在 Flannel 中,VXLAN 头部的生成由 VXLAN 的 MarshalBinary 函数实现。

---- --- ------------- --------------- -------- ------ -
  - -- ------------ ------------------

  ---- - -------------- -- --
  ---- - -------------- - -----
  ---------------------------------- -------

  ------------- -------
  ------------------------------------ -------

  ------ -- ---
-

使用 Flannel

Flannel 的部署和配置相对简单,可以通过 kubelet 的配置文件中直接指定 Flannel 的配置,例如下面的配置以 etcd 做为存储后端:

----------- ----------------------
----- --------------------
---
------------------ -----
----------- ----------------
---------- --------------
----------------- -
-
    ------- -------
    ------------- --------
    ------- ----------
    ----------- -
        ------- -------
        ---------------- --------------------------------
        ------------- -------------------
        ------------------- ---------------------------------------
        ------------------- --------------------------------------
    -
-

配置启动后,可以通过 kubectl get po -n kube-system 命令来查看 Flannel 的启动状况,并通过 kubectl get node -o wide 来查看 Flannel 所分配的 Pod 网络信息。同时,Flannel 的运行日志可以通过 journalctl -u flanneld -f 来实时查看。

总结

Flannel 作为 Kubernetes 最重要的网络组件之一,为整个 Kubernetes 集群的网络通信提供了非常重要的支持。本文从 Flannel 的原理和源码分析了解到,Flannel 的原理和实现非常复杂,但在实现过程中还是通过简单的方式,借助 Linux 的 namespace 和 VXLAN 技术,为 Kubernetes 提供了更高效、更可靠、更灵活的内部通信方案,让整个集群能够更好地运营。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/64cb01505ad90b6d041e49d7


猜你喜欢

  • Deno 中遇到 Module not found 错误该如何解决?

    什么是 Deno? Deno 是一个用于开发 Web 应用、服务端应用、脚本和工具的 JavaScript 和 TypeScript 运行时环境,它由 Node.js 的创建者 Ryan Dahl 开...

    1 年前
  • 怎么解决 Node.js 进程崩溃的问题

    Node.js 是一种非常流行的服务端开发语言,但是在开发中,我们时常会遇到进程意外崩溃的情况。如果不及时处理这些问题,就会导致严重的线上事故。那么,怎么有效的解决 Node.js 进程崩溃问题呢? ...

    1 年前
  • MongoDB 集群部署的优化和管理技巧

    前言 MongoDB 是当前广泛使用的 NoSQL 数据库之一,它具有高性能、高可用、高可扩展性等优点。但是,MongoDB 集群的部署和管理却是一个比较复杂且需要注意的问题。

    1 年前
  • ES7 async/await:解决你的异步编程困局

    随着 JavaScript 的发展,越来越多的应用需要处理异步操作,例如处理网络请求、操作数据库、定时器等,对于传统的同步编程方式,其效率和性能都无法满足现代应用的需求。

    1 年前
  • 外部库从 CDN 获取,减小 Webpack 打包体积

    随着 web 应用的不断发展,前端应用的体积也不断增大,这也对用户的访问速度和用户体验产生了很大的影响。为了解决这个问题,我们可以通过从 CDN 获取外部库的方式,达到减小 webpack 打包体积的...

    1 年前
  • ECMAScript 2020 中的函数式编程解析及其实际应用举例

    函数式编程是一种编程范式,它使用无副作用的纯函数来构建程序。ES2020 新增的一些特性让我们更容易使用函数式编程。 箭头函数 箭头函数是 ES6 中引入的一个新语法。

    1 年前
  • 学习 Redux:从 “你不知道的 JavaScript” 到实际应用

    Redux 是一个流行的 JavaScript 应用程序状态管理工具。它旨在简化前端应用程序数据的存储和操作,并且能够轻松跨组件维护数据。 虽然 Redux 可以用于任何 JavaScript 应用程...

    1 年前
  • RxJS 中 throwError 的使用场景及应用案例分享

    前言 RxJS 是一个 Reactive Extensions 库,它提供了丰富的 API 和一套响应式编程的范式。在 RxJS 中,throwError 是一个非常有用的操作符,它可以用来抛出一个错...

    1 年前
  • 移动端 Web 自动化测试之 Chai 和 Appium 的实现

    自动化测试是一项非常重要的测试活动,可以帮助我们快速有效地发现软件的缺陷,同时提高测试效率,降低测试成本。在移动端 Web 应用程序中,自动化测试同样重要。本文将介绍移动端 Web 自动化测试中两个重...

    1 年前
  • 在 Material Design 中使用 TextInputEditText 时,如何避免无法输入的情况

    在 Android 开发中,Material Design 被广泛应用在界面的设计中,其中 TextInputEditText 是一个常见的控件,主要用于输入文本、密码等信息。

    1 年前
  • ES10 中的 Array.sort() 方法的实现及扩展性

    在前端开发中经常需要对数组进行排序,而 Array.sort() 方法是最常用的数组排序方法之一。ES10 中的 Array.sort() 方法有一些新的用法和扩展性,本文将详细介绍实现和扩展方式,并...

    1 年前
  • PM2 对 Node.js 应用的线程安全性问题的解决方法

    在 Node.js 应用的部署过程中,我们通常会使用 PM2 进行进程管理,以实现高可用性和负载均衡等功能。然而,在某些情况下,PM2 可能会引发线程安全性问题,因此本文将介绍 PM2 对 Node....

    1 年前
  • Promise 在 JavaScript 中的应用实例讲解

    Promise 是 JavaScript 中的一个强大的异步编程解决方案,可以解决回调地狱的问题,同时也简化了异步操作的代码实现。本文将讲解 Promise 的基本概念,以及实际应用场景并包含示例代码...

    1 年前
  • Mongoose 使用中的错误汇总及解决方法

    Mongoose 是一个基于 Node.js 平台的 MongoDB(NoSQL 数据库)对象模型工具。它提供了对 MongoDB 更简单的操作和更完善的对数据的展示与校验。

    1 年前
  • 将 Elasticsearch 和 Kibana 部署在 Docker 上的问题与解决办法

    前言: Elasticsearch 是一个基于 Lucene 的搜索引擎,使用它可以处理海量数据进行全文搜索、结构化搜索和分析。而 Kibana 是 Elasticsearch 的可视化工具,它可以展...

    1 年前
  • Kubernetes 资源调度 - Scheduler 的寻找和绑定过程

    在 Kubernetes 中,Scheduler 是负责将 Pod 分配到 Node 上的重要组件。Scheduler 通过一系列的算法策略,来决定哪些 Pod 应该分配到哪些 Node 上进行部署。

    1 年前
  • 使用 Socket.io 建立基于 Node.js 的实时 Web 应用程序:教程

    如果你想建立一个实时的 Web 应用程序,那么你需要考虑使用实时通信技术来实现。在这篇文章中,我们将介绍如何使用 Socket.io 和 Node.js 来建立一个实时的 Web 应用程序。

    1 年前
  • 如何在 Express.js 中使用 Passport-local 进行本地认证

    在现在的 Web 应用中,用户认证是一个必不可少的功能。同时,本地认证(指用户名和密码等凭证在本地进行验证)也是比较常见的一种认证方式。在 Node.js 场景下,使用 Passport-local ...

    1 年前
  • ECMAScript 2018 新特性之 RegExp 细则

    ECMAScript 2018 新特性之 RegExp 细则 正则表达式是前端开发中非常重要的一部分,它可以用于字符串的匹配和替换,是实现文本处理功能的核心工具。在 ECMAScript 2018 新...

    1 年前
  • Vue.js:使用 computed 属性监听对象属性变化的技巧

    在 Vue.js 中,computed 属性通常被用来监听响应式数据的变化,以便在数据变化时更新视图。然而,computed 属性可以更进一步,使用它来监听对象属性的变化,以达到更加精细的控制和更新视...

    1 年前

相关推荐

    暂无文章