k8s :kube-apiserver Legacy API 初始化

xingpingz · · 1005 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

前言

看 k8s 源代码有一段时间,总感觉在迷宫里乱窜,有时候觉得终于找到出口了,一下子又撞墙了,总结下来还是自己的内功不够深厚,本文是对 kube-apiserver Legacy(遗留,即将废弃)API 初始化流程(以及数据结构)的一个梳理,算是做个"路标",便于以后在"迷宫"中还能找到回来的路

kube-apiserver 主要功能是提供 api 接口给客户端访问 后端 etcd 存储,当然这中间不光是简单的 key/value 存储,为了方便扩展,kube-apiserver 设计了一套代码框架将 "资源对象" 映射到 RESTful API

本文梳理了一下 legacy api 即 /api 打头的那些 api 初始化流程及相关的数据结构

k8s 代码更新比较快,本文基于 k8s release-1.9.x 代码

数据结构

kube-apiserver 启动流程相关的(主要)数据结构

  • XXXOptions 命令行参数相关的类
  • XXXConfig 配置相关的类
  • XXXServer kube-apiserver 服务对象
  • XXXStorage 资源对象,比如 PosStorage,通过 XXXStorage 操作后端存储(etcd)

Options,Config 和 Server 对象的(大致)关系:
由 Options 对象创建 Config 对象,然后由 Config 对象创建 Server 对象

ServerRunOptions

ServerRunOptions 类封装了 kube-apiserver 命令行参数,这些参数按照不同的类别进行分组

// kubernetes/cmd/kube-apiserver/app/options/options.go
import (
    ...
    genericoptions "k8s.io/apiserver/pkg/server/options"
    ...
)

type ServerRunOptions struct {
    GenericServerRunOptions *genericoptions.ServerRunOptions
    Etcd                    *genericoptions.EtcdOptions
    SecureServing           *genericoptions.SecureServingOptions
    InsecureServing         *kubeoptions.InsecureServingOptions
    ...
}

我们重点看看 EtcdOptions,etcd 存储相关的配置,它和 kube-apiserver 如何访问后端 etcd 存储密切相关

EtcdOptions

StorageConfig 定义了 etcd 详细配置,比如 etcd 版本,key 公共前缀等

// kubernetes/vendor/k8s.io/apiserver/pkg/server/options/etcd.go
type EtcdOptions struct {
    StorageConfig storagebackend.Config
    EncryptionProviderConfigFilepath string
    ...
}

// kubernetes/vender/k8s.io/apiserver/storage/storagebackend/config.o
type Config struct {
    // Type defines the type of storage backend, e.g. "etcd2", "etcd3"
    Type string
    // Prefix is the prefix to all keys passed to storage.Interface methods.
    Prefix string
    // ServerList is the list of storage servers to connect with
    ...
}

创建

工厂方法 NewEtcdOptions 用于创建 EtcdOptions

// kubernetes/cmd/kube-apiserver/app/options/options.go
func NewServerRunOptions() *ServerRunOptions {
    s := ServerRunOptions {
        ...
        Etcd: genericoptions.NewEtcdOptions(
            storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, nil))
        ...
    }
}

ApplyWithStorageFactoryTo

EtcdOptions 有一个重要方法 ApplyWithStorageFactoryTo 用于初始化 server.Config(服务配置类,见下文)的 RESTOptionsGetter 属性,该属性用于创建 etcd 后端存储(见下文)

// kubernetes/vendor/k8s.io/apiserver/pkg/server/options/etcd.go
func (s *EtcdOptions) ApplyWithStorageFactoryTo(

factory server storage.StorageFactory, c *server.Config) error {
s.RESTOptionsGetter = &storageFactoryRestOptionsFactory{
    Options: *s,
    StorageFactory: factory
}

}


// kubernetes/pkg/kubeapiserver/options/storage_versions.go
const (
    DefaultEtcdPathPrefix = "/registry"
)

GenericAPIServer

GenericAPIServer contains state for a Kubernetes cluster api server

type GenericAPIServer struct {
    ...
}

Master

Master contains state for a Kubernetes cluster master/api server

type Master struct {
    GenericAPIServer *genericapiserver.GenericAPIServer
    ClientCARegistrationHook ClientCARegistrationHook
}

流程

每个 k8s 服务或实用程序在 kubernetes/cmd 目录下都有一个对应的文件夹,里面放着这些服务或实用程序的入口,顺便提一下,通过一下命令可以单独构建 kube-apiserver

# export GOPATH=/opt/kubernetes-src/
# cd $GOPATH/src/k8s.io/kubernetes
# make WHAT=cmd/kube-apiserver all

kube-apiserver 的入口(main 函数,main package)

// kubernetes/cmd/kube-apiserver/apiserver.go
func main() {
    rand.Seed(time.Now().UTC().UnixNano())

    // 解析命令行参数
    s := options.NewServerRunOptions()
    s.AddFlags(pflag.CommandLine)
    flag.InitFlags()

    // 初始化 log
    logs.InitLogs()
    defer logs.FlushLogs()

    ...

    stopCh := server.SetupSignalHandler()
    if err := app.Run(s, stopCh); err != nil {
        fmt.FPrintf(os.Stderr, "%v\n", err)
        os.Exit(1)
    }
}

main 函数只是个壳子,解析完命令行参数后会调用 app 包中的 Run 函数

// kubernetes/cmd/kube-apiserver/app.server.go
func Run(runOptions *options.ServerRunOptions, stopCh <-chan struct{}) error {
    ...
    server, err := CreateServerChain(runOptions, stopCh)
    if err != nil {
        return err
    }
    return server.PrepareRun().Run(stopCh)
}

CreateServerChain 函数使用了《责任链》设计模式,多个 Server 组成一个 List 处理客户端请求,Run 函数最后调用 server 的 PrepareRun 和 Run 方法启动 kube-apiserver 服务


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:xingpingz

查看原文:k8s :kube-apiserver Legacy API 初始化

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1005 次点击  
加入收藏 微博
上一篇:golang
下一篇:go语言学习2
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传