前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >隐蔽的角落-这次我们只聊Cilium IPAM

隐蔽的角落-这次我们只聊Cilium IPAM

作者头像
LanceZhang
发布2021-12-06 15:49:41
9510
发布2021-12-06 15:49:41
举报
文章被收录于专栏:二哥聊云原生

礼记《学者有四失》里说“人之学也,或失则多”,这是给我提醒每篇推文最好只聊一个概念。前一篇文章着重介绍了一下Cilium的各种炫酷的花式玩法,今天我们来看一个最最基本的功能:IPAM(IP Address Management)。

IPAM的概念很简单,就是IP地址管理。DHCP就是IPAM常用的一种工具。可为什么我们要在这里单独聊它呢?因为概念虽然简单,但在容器网络这个场景里,有它特殊的实现方式和业务挑战。

图 1:Cluster内,Pod间通信示意图

在开始聊IPAM之前,我们先来看看图1。这是一张示意图,它画出了一个cluster内部,Pod内容器间通信,Pod间(跨主机)通信的典型场景。这张图里面还画出了一些额外的信息:

  • 一个Pod内部可能有若干个container,其中一定会包含一个Infra-container。
  • 一个container内部是可以同时跑多个process的。
  • 每个Pod都有一个在容器网络环境独一无二的IP地址。容器网络环境和宿主机网络环境的区别与联系请阅读二哥之前的推文“镜子-或许我们也和Pod一样生活在虚拟世界”。
  • Pod内部所有的容器都共享其所在Pod的IP地址,但是这些容器需要使用不同的端口。

我们可以看到除了Pod内容器间通信是可以直接用localhost之外,不同的Pod之间通信是需要用到pod IP的。那随之而来的问题是:pod IP地址是谁给分配的?又是在什么时候安排上的?如果Pod没了,这个IP地址被谁收走了?

你肯定觉得在隐秘的角落,应该有一个类似DHCP的东西在控制着这一切,但好像K8s里面又没有提到DHCP这个事情。其实答案很简单:CNI插件。

CRD

Cilium用到了一个叫K8s CRD(Custom Resouce Definition)的技术。所谓CRD,就是有一些功能K8s没有提供,但是呢K8s通过插件的方式外包给第三方。CRD是K8s生态中核心扩展机制(另外一个核心扩展机制是Custom API Server)。

图 2:CRD在K8s apiserver中的位置示意图(图片取自书籍《Programming Kubernetes》)

如图2所示,在kube-apiserver中有一个模块叫apiextensions-apiserver来单独服务CRD。它的位置仅靠着K8s native-resource。

CRD是K8s的一个resource,用来描述对Custom Resouce(CR)的定义,而后者则是基于该CRD而创建的资源。来一句绕口令吧:CRD是CR的定义,CR是CRD的实例。

下面的一小段示例用来向K8s注册CR definition,好让K8s知道有一个第三方定义的resouce存在。

代码语言:javascript
复制
apiVersion: "apiextensions.k8s.io/v1beta1"
kind: CustomResourceDefinition
metadata:
  name: ciliumnodes.cilium.io
spec:
  group: cilium.io
  names:
     kind: CiliumNode
     shortNames:
      - cn
      - ciliumn
...    

而下面这段另外的示例用来基于前一步注册的CRD来创建CR。这段示例仅展示了部分内容。K8s收到这样的请求会创建一个数据结构,填充内容并存放到etcd中,数据的结构从CRD中得到,如spec.group、spec.names、spec.ipam等等,而数据内容其实就是由下面这段声明式yaml来填充。每一份这样的数据被叫作CR实例(CR instance)。

代码语言:javascript
复制
apiVersion: "cilium.io/v2"
kind: CiliumNode
metadata:
  name: "cilium-2"
spec:
  ipam:
    pool:
        10.0.1.78: {}
...      

上面这两段示例也说明了使用CRD的标准方式:先注册CRD,再创建CR。

CR和K8s自带的resource如Pod,Namespace,Deployment一样,也是一种resource,只不过它是由第三方自定义的,用于提供和K8s native-resource一样的使用体验,如果不注意,你甚至都不会在意这个resource是第三方提供的。为啥能有这么自然的使用体验呢?因为CRD也是被K8s apiserver一起无差别处理的,CR和native-resource存放的位置都一样,都是存放在etcd中。

但和K8s自带的resource位于Core group不同,CR一般位于第三方自己的Group(Group-Version-Resource中的Group)内。具体到Cilium,它定义了若干个CR,其中一个叫CiliumNodes,位于Group cilium.io,Version v2

你可以通过如下命令获取CiliumNodes这个CRD的详细内容,如果你的环境恰好使用了Cilium的话。

代码语言:javascript
复制
kubectl get crds ciliumnodes.cilium.io -o yaml

CRD的背后有一个叫K8s Controller的服务以Pod方式在K8s环境里运行,以响应K8s外包过来的各种请求。

图 3:Customer Controller内部结构图

如图3所示,对于一个recource,一旦API server端有针对它的实例创建、删除或者更新的操作,Informer都会收到"事件通知"。

于此同时Controller内部会运行有一个Control Loop,这个loop的作用很明显,就是消化掉与此resource相关的各个通知事件。

注意区分resource相关的增加、更新、删除相关的event和top-level Event对象的区别。前者是事件通知机制,而后者则和Pod一样也是一种resource,可以将其看成是一个反映系统运行状态的日志(Log)系统。

IPAM

聊完Controller,我们来看看Cilium是如何利用Controller来完成IP地址管理的。

图 4:Cilium IPAM示意图

图4的右方出现了一个cilium-operator的图示。Operator作为K8s里的一个概念,于2016年被CoreDNS提出。它是一个Controller,它的出现大大简化了“有状态应用”的部署复杂度,我们大致了解到这个地方即可,后续二哥会单独开一篇聊聊Operator。

整个K8s cluster只运行有一份cilium-operator Pod,而cilium-agent则在每个Node上都运行一份。

当cilium-operator发现有一个新的CiliumNodes资源被创建后,它会从它的供货商那里获取一批与此Node相关的IP地址块,Node的如hostname等信息则通过读取CR资源实例得到。

前面我们提到每个Node上都会运行有cilium-agent,它会从这个新建CR的spec.ipam.available这里拿到一个IP地址。这个过程中cilium-operator就像是一个公益超市,批发进货,散卖加回收,还没有赚差价。

你也可以执行下面的命令,看看与每个Node相关的IPAM信息。cilium-agent通过client-go即可非常方便地拿到和你看到的一模一样的数据。二哥为了你能更快速地得到更直观的了解,贴心地截了一张图(下图5)放在这里。你可以看到这个CR的实例大概长什么样子。

代码语言:javascript
复制
# 此处的cn是CiliumNodes的缩写,在CRD的spec.shortNames中定义。
kubectl get cn -o yaml

图 5:kubectl get cn cilium-2 -o yaml 输出截图

图4仅仅是一个示意图,实际上Controller的IP供货商有很多种,除了图中所示的AWS ENI(Elastic Network Interface)之外,还有Azure,GKE等等可供选择。从不同的供货商那里获取IP地址块的方式也不尽相同。

如果你的cluster环境是完全自己管理的,我们知道K8s自身就是可以通过kubeadmin来设置CIDR的,像下面的命令一样,你也可以按照自己的喜好随意设置。

代码语言:javascript
复制
sudo kubeadm init --pod-network-cidr=10.244.0.0/16

图 6:Cilium IPAM时序图

说了这么多,我觉得还是有点抽象,所以我把图6放上来了。因为图4主要涉及到的是AWS ENI,所以我在图6中将涉及到AWS ENI的部分用红框标识出来了。

图6这张时序图初看起来比较复杂,一眼望去不知道重点是什么。因为它是对图4的细节放大,所以包含了很多的信息。放大到什么程度呢?它把从容器创建到IP分配这个过程中所有的参与者和各自参与时机都画出来了。

另外从这张图里面,我们也可以看到在容器创建过程中,kubelet,CRI,还有CNI plugin之间是如何分工的。可以很明显地看到CNI插件其实做的事情非常简单,大部分情况下,它只是个摆设,真正的活还是得靠它背后勤劳的小蜜蜂们来完成,比如这里的cilium-agent。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 二哥聊云原生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CRD
  • IPAM
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档