前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【K8s】api-server 源码分析 01-02

【K8s】api-server 源码分析 01-02

原创
作者头像
Librant
修改2022-06-19 15:41:39
3700
修改2022-06-19 15:41:39
举报
文章被收录于专栏:跟我一起学 K8s跟我一起学 K8s

【注】源码分析均以 k8s 的第一个 commit 代码分析;

接上一篇 01-01 接着说;

上一篇主要是讲 pkg/registry 中的代码,这一节将主要讲 pkg/apiserver 中的代码实现;

通过上一篇的讲解,整个 api-server 的整体架构有一个简单的认识;

api-server 下的 RESTStorage 接口,有六个方法;

代码语言:go
复制
// RESTStorage is a generic interface for RESTful storage services
type RESTStorage interface {
	List(*url.URL) (interface{}, error)
	Get(id string) (interface{}, error)
	Delete(id string) error
	Extract(body string) (interface{}, error)
	Create(interface{}) error
	Update(interface{}) error
}

还有个

代码语言:go
复制
// TODO: consider migrating this to go-restful which is a more full-featured version of the same thing.
type ApiServer struct {
	prefix  string
	storage map[string]RESTStorage
}

ApiServer 的结构体,主要是用于 resetful 的请求:

  • prefix 是请求的 URL 路径;
  • storage 是实现的 RESTStorage 接口;

pkg/registry

reistry 目录中的注册表:

先来分析下目录下提供的接口信息:

代码语言:go
复制
type TaskRegistry interface {}
type ControllerRegistry interface {}
type ServiceRegistry interface {}

主要是这三个接口:

  • task
  • controller
  • service

再来看下,这些接口都有哪些实现:

1)TaskRegistry

代码语言:go
复制
// TaskRegistryStorage implements the RESTStorage interface in terms of a TaskRegistry
type TaskRegistryStorage struct {
	registry      TaskRegistry
	containerInfo client.ContainerInfo
	scheduler     Scheduler
}

2)ControllerRegistry

代码语言:go
复制
// Implementation of RESTStorage for the api server.
type ControllerRegistryStorage struct {
	registry ControllerRegistry
}

3)ServiceRegistry

代码语言:go
复制
type ServiceRegistryStorage struct {
	registry ServiceRegistry
}

再重新分析 main() 函数中的这些接口的实例化:

代码语言:go
复制
if len(etcdServerList) > 0 {
	log.Printf("Creating etcd client pointing to %v", etcdServerList)
	etcdClient := etcd.NewClient(etcdServerList)
	taskRegistry = registry.MakeEtcdRegistry(etcdClient, machineList)
	controllerRegistry = registry.MakeEtcdRegistry(etcdClient, machineList)
	serviceRegistry = registry.MakeEtcdRegistry(etcdClient, machineList)
} else {
	taskRegistry = registry.MakeMemoryRegistry()
	controllerRegistry = registry.MakeMemoryRegistry()
	serviceRegistry = registry.MakeMemoryRegistry()
}

1)传入了 etcd 节点的初始化:

这里可以看出,三个接口都是通过 MakeEtcdRegistry() 函数进行实例化,这个返回的实例实现了这个三个接口;

代码语言:go
复制
pkg/registry/etcd_registry.go

func MakeEtcdRegistry(client EtcdClient, machines []string) *EtcdRegistry {}

这里最重要的就是 EtcdRegistry{} 结构体:

代码语言:go
复制
// EtcdRegistry is an implementation of both ControllerRegistry and TaskRegistry which is backed with etcd.
type EtcdRegistry struct {
	etcdClient      EtcdClient
	machines        []string
	manifestFactory ManifestFactory
}

通过上面的注释也可以看出,这个结构体实现了这几个接口;(包括 ServiceRegistry{} 接口)

- ListTasks():列出所有节点上符合标签的任务信息;

代码语言:go
复制
ListTasks(query *map[string]string) ([]Task, error)

(每个任务都有 label 标签)

这个方式是通过

代码语言:go
复制
key := "/registry/hosts/" + machine + "/tasks"

从 etcd 中查询每个 machine 下的任务信息;每个节点的任务信息都是会同步到 etcd 中;

- GetTask():根据任务 ID 获取单个任务信息;

代码语言:go
复制
GetTask(taskID string) (*Task, error)

任务都是存在 etcd 中,根据 key 获取:

代码语言:go
复制
"/registry/hosts/" + machine + "/tasks/" + taskID

这里简单介绍下这里的实现逻辑:

-- 首先遍历每个节点下的所有任务信息;

-- 根据任务 ID 拼接的 key 查询 etcd 中的写任务信息;

-- 将当前查询到的节点 IP 信息填入 Task 中并返回;

- ListControllers():获取 controller 列表信息;

代码语言:go
复制
ListControllers() ([]ReplicationController, error)

首先根据 key, 列出所有 Node(etcd 中存储的节点) 信息:

代码语言:go
复制
key := "/registry/controllers"
  • CreateTask():创建任务
代码语言:go
复制
CreateTask(machineIn string, task Task) error {}

传入节点信息和 task 信息;

-- 判断任务是否在存在,存在直接报错返回;

代码语言:go
复制
registry.findTask(task.ID)

-- 运行任务

代码语言:go
复制
registry.runTask(task, machineIn)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档