K8S的client-go与Informer机制

一、介绍

client-go是一个包含KubernetesAPI的SDK,它在整个k8s源码中发挥着不可或缺的作用。

二、KubernetesAPIs

2.1 规范

2.1.1 RESTful

REST,即Representational State Transfer的缩写。这个词组可以翻译为"表现层状态转化"。

  1. 每一个URI代表一种资源;
  2. 客户端和服务器之间,传递这种资源的某种表现层;
  3. 客户端通过五个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。
    提问:注册登录场景的相关API如何用RESTful的方式设计?
2.1.2 GVK®

apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
namespace: default
spec:
replicas: 1

  • apiVersion ≈ apiGroupVersion = Group/Version
  • GVK = Group Version Kind
  • GVR = Group Version Resources

提问:Resource和Kind有什么区别?
答:Resource是一个对象,Kind是一个对象的类型名称

提问:一个标准的K8S资源的API长什么样?
在这里插入图片描述

2.2 实战调用

2.2.1 跳过鉴权

因为本次分享的API只是个引子,我们就不讲鉴权了。kubectl有个proxy的子命令可以实现在本地搭建一个具备kubectl同等权限的代理。这里我们通过这种方式跳过鉴权。
kubectl proxy --port=6443

2.2.2 几个例子
  • 获取当前版本信息
    • http://localhost:6443/version
  • 获取APIServer支持的所有APIGroup
    • http://localhost:6443/apis
  • 获取全部命名空间的Deployment列表
    • http://localhost:6443/apis/apps/v1/deployments
  • 获取命名空间default下的Deployment列表
    • http://localhost:6443/apis/apps/v1/namespaces/default/deployments
  • 获取命名空间default下的一个Deployment对象
    • http://localhost:6443/apis/apps/v1/namespaces/default/deployments/httpbin
  • 获取Pod列表
    • http://localhost:6443/api/v1/namespaces/default/pods
      提问:获取rollout列表的接口是什么样
      http://localhost:6443/apis/argoproj.io/v1alpha1/rollouts

三、client-go源码

3.1 实战调用

clientset

clientset.AppsV1().Deployments(apiv1.NamespaceDefault).Create(context.TODO(), deployment, metav1.CreateOptions{})

dynamic

deploymentRes := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}
dynamicClient.Resource(deploymentRes).Namespace(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{})

restclient

c.client.Post().
   Namespace(c.ns).
   Resource("deployments").
   VersionedParams(&opts, scheme.ParameterCodec).
   Body(deployment).
   Do(ctx).
   Into(result)

https://github.com/kubernetes/client-go/tree/master/examples

3.2 Package介绍

无法复制加载中的内容

client-go源码目录结构

  • discovery:用于发现APIs的相关资源
  • kubernetes(clientset):基于rest封装的包含所有k8s内置资源的client集合
  • informers:基于clientset实现了一个资源缓存池,封装了所有资源的list和get操作
  • dynamic:基于rest实现了一个动态的client,支持所有类型的资源进行操作
  • dynamic/dynamicinformer:为dynamic实现的informer
  • tools/cache:informer的底层实现
  • tools/watch:informer的watch实现,使用它可以watch到informer的资源变化
  • transport:用作初始化一个http连接,AA也是在这里完成的

3.3 核心Package走读

3.3.1 kubernetes(clientset)

在这里插入图片描述

3.3.2 dynamic

在这里插入图片描述

3.3.3 transport

在这里插入图片描述

3.4 Informer

informer实际上是为controller服务的,所以这里我们先了解下k8s的controller的设计理念。

3.4.1 控制循环

在这里插入图片描述
控制论图解
在这里插入图片描述

Kubernetes中的控制循环
通常,控制环路如下所示:

  1. 阅读资源的状态
  2. 更改群集或群集外部世界中对象的状态
  3. 通过etcd中的API服务器更新步骤1中的资源状态
  4. 重复循环;返回步骤1。

提问:在控制循环中要求近乎实时的获取资源状态,如何实现?
在这里插入图片描述

边沿触发与电平触发
提问:事件驱动如何保证不丢数据?
在这里插入图片描述

这张图里展示了三种策略:

  1. edge-driven-only,错过了第二状态改变
  2. edge-triggered,不依赖事件的数据而是自行获取数据
  3. edge-triggered with resync,在上一个策略的基础上增加resync

3.4.2 ListWatch

list-watch,顾名思义由list和watch组成。list调用资源的list API获取所有资源,watch调用资源的watch API监听资源变更事件。
在这里插入图片描述

提问:如何实现watch?

  • 方案1:短轮训
  • 方案2:长轮训
  • 方案3:chunked

普通HTTP响应体

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 25
Mozilla Developer Network         ——> body 数据内容,大小为25字节

chunked的HTTP响应体


```bash
HTTP/1.1 206 OK
Content-Type: text/plain
Transfer-Encoding: chunked

7                            ——> 第一个chunk块,大小为7字节
Mozilla                      ——> 第一个chunk块内容
9                            ——> 第二个chunk块,大小为9字节
Developer                    ——> 第二个chunk块内容
7                            ——> 第三个chunk块,大小为7字节
Network                      ——> 第三个chunk块内容
0                            ——> 标记性终止块,大小为0字节

普通HTTP请求响应处理
在这里插入图片描述
chunked的HTTP请求处理
在这里插入图片描述
informer中的chunk
在这里插入图片描述

抓包观察watch机制

3.4.3 核心代码走读
无法复制加载中的内容

Informer组件:

  • Controller
  • Reflector:通过Kubernetes Watch API监听resource下的所有事件
  • Lister:用来被调用List/Get方法
  • Processor:记录并触发回调函数
  • DeltaFIFO
  • LocalStore
    在这里插入图片描述
    在这里插入图片描述

四、实现一个简单的Controller

在这里插入图片描述
参考文档
https://github.com/kubernetes/client-go
https://qiankunli.github.io/2020/07/20/client_go.html
https://zh.wikipedia.org/wiki/%E6%8E%A7%E5%88%B6%E8%AE%BA
深入理解k8s中的list-watch机制

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐