k8s的APIServer流程介绍

声明式API介绍

    所谓“声明式” 指的就是我只需要提交一个定义好的API对象来“声明”,我所期望的状态是什么样子

   “声明式 API”允许有多个 API写端,以PATCH的方式对API对象进行修改而无需关心本地原始YAML文件的内容.自动对多个写进行Merge操作

    有了上述两个能力Kubernetes才可以基于对 API 对象的增、删、改、查.在完全无需外界干预的情况下完成对“实际状态”和“期望状态”的调谐(Reconcile)过程

    声明式 API才是 Kubernetes项目编排能力“赖以生存”的核心所在   

APIServer介绍

     k8s的API对象的组织方式是一个层层递进的方式来组织的          api组/api版本/资源类型

    

     把一个YAML 文件提交给Kubernetes之后创建出一个API对象的流程:

       1. Kubernetes 会匹配 API对象的组

       2. Kubernetes 会进一步匹配到 API对象的版本号

       3. Kubernetes 会匹配 API 对象的资源类型

       4. kubernetes匹配到正确的资源类型后,就可以开始创建API对象.APIServer执行流程如下:

          1.APIServer首先过滤这个请求并完成一些前置性工作.   如:授权,超时处理,审计

          2.然后请求进入MUX和Routers流程.这个步骤是APIServer完成URL和Handler绑定的场所.APIServer的Handler的功能就是找到用户提交资源对应的类型定义

          3.API根据对应的类型定义配合用户提交的YAML文件里的字段.在内存中创建出一个相应的对象.在创建的过程中APIServer会进行一个Convert操作,把用户提交的YAML文件转换成一个叫Super Version的对象.它是该API资源类型所有版本字段的全集.这样用户提交不同的版本的YAML文件就都可以使用Super Version对象来处理

          4.APIServer会对内存中的对象进行Admission()操作,如Admission Controller和Initializer步骤都属于Admission阶段

          5.APIServer会把对象进行Validation操作,它负责验证这个对象里的各个字段是否合法.验证通过后的API对象都会保存到APIServer中一个叫 Registry的数据结构中

          6.APIServer会把验证过的Super API对象转换用户最初提交的版本进行序列化操作并保存到Etcd中.至此整个API对象创建完毕

         

     APIServer要同时要兼顾性能、API 完备性、版本化、向后兼容等很多工程化指标

 Custom Resource Definition(CRD)定义

      它指的就是允许用户在Kubernetes中添加一个跟Pod、Node 类似的、新的 API 资源类型 即:自定义 API 资源

      使用code-generator生成代码的时候跟宿主机安装的go版本有很大的关系 如在go1.12和go1.13执行go build的时候对代码的要求就不一样

      go1.13上引入mod的名称不是标准的域名也会报错。而在go1.12版本上就不会报错

     

    解决办法:

       1.修改code-generator项目下的go.mod

          k8s.io/k8s_customize_controller/pkg/apis/bolingcavalry => /root/gopath/src/k8s.io/k8s_customize_controller/pkg/apis/bolingcavalry

// This is a generated file. Do not edit directly.

go 1.13

require (
        github.com/emicklei/go-restful v2.11.2+incompatible // indirect
        github.com/go-openapi/jsonreference v0.19.3 // indirect
        github.com/spf13/pflag v1.0.5
        github.com/stretchr/objx v0.2.0 // indirect
        golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 // indirect
        golang.org/x/net v0.0.0-20200226121028-0de0cce0169b // indirect
        golang.org/x/tools v0.0.0-20200226224502-204d844ad48d // indirect
        k8s.io/apimachinery v0.17.3 // indirect
        k8s.io/gengo v0.0.0-20200205140755-e0e292d8aa12
        k8s.io/k8s_customize_controller/pkg/apis/bolingcavalry v0.0.0-00010101000000-000000000000 // indirect
        k8s.io/klog v1.0.0
        k8s.io/kube-openapi v0.0.0-20200204173128-addea2498afe
        sigs.k8s.io/yaml v1.2.0 // indirect
)

replace (
        golang.org/x/sys => golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // pinned to release-branch.go1.13
        golang.org/x/tools => golang.org/x/tools v0.0.0-20190821162956-65e3620a7ae7 // pinned to release-branch.go1.13

//告诉go不要使用去远程服务器下载 直接使用本地目录
        k8s.io/k8s_customize_controller/pkg/apis/bolingcavalry => /root/gopath/src/k8s.io/k8s_customize_controller/pkg/apis/bolingcavalry
)
go.mod

创建CRD流程 

     1.创建自定义API对象定义(CRD)

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  # metadata.name的内容是由"复数名.分组名"构成,如下,students是复数名,bolingcavalry.k8s.io是分组名
  name: students.bolingcavalry.k8s.io
spec:
  # 分组名,在REST API中也会用到的,格式是: /apis/分组名/CRD版本
  group: bolingcavalry.k8s.io
  # list of versions supported by this CustomResourceDefinition
  versions:
    - name: v1
      # 是否有效的开关.
      served: true
      # 只有一个版本能被标注为storage
      storage: true
  # 范围是属于namespace的
  scope: Namespaced
  names:
    # 复数名
    plural: students
    # 单数名
    singular: student
    # 类型名
    kind: Student
    # 简称,就像service的简称是svc
    shortNames:
    - stu
资源类
apiVersion: bolingcavalry.k8s.io/v1
kind: Student
metadata:
  name: object-student
spec:
  name: "bbb"
  school: "aaa"
资源实例

     2.用code-generator生成informer和client相关代码    

/root/gopath/src/k8s.io/k8s_customize_controller/pkg/apis/bolingcavalry/v1/register.go


package v1

import (
   metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
   "k8s.io/apimachinery/pkg/runtime"
   "k8s.io/apimachinery/pkg/runtime/schema"

   "k8s.io/k8s_customize_controller/pkg/apis/bolingcavalry"
)
vi v1/register.go

              go.mod是个空文件,但必须要创建 .否则go build的时候会提示找不到此文件

             ./generate-groups.sh all k8s.io/k8s_customize_controller/pkg/client k8s.io/k8s_customize_controller/pkg/apis bolingcavalry:v1

   3.创建并运行自定义控制器,k8s中所有对CR对象的相关操作都会被控制器监听到,可以根据实际需求在控制器中编写自己的业务逻辑

      1.在项目根目录下创建controller.go
      2.在项目根目录下的pkg目录下创建signals目录
      3.在项目根目录下创建main.go
      4.编译构建和启动
         1.安装go build的依赖模块
         2.在根目录执行go build成功后会生成一个二进制可执行文件
         3.从我的src目录中删除../../../k8s.io
            通过在go.mod文件中显式声明版本,避免使用客户端go的最新主分支,重新运行构建获取了新的源和客户端的稳定版本.生成没有错误地执行
     5.k8s项目出现问题一定要用google搜索 用百度根本搜索不到相关问题

 修改依赖的包名

 

 klog这个包源码不能下载最新版本,下载一个旧的版本klog包并且上传的指定目录

 

   在项目根目录下执行go build.执行成功后会在当前目录生成一个二进制可执行文件

   启动自定义控制器命令       ./k8s_customize_controller -kubeconfig=$HOME/.kube/config -alsologtostderr=true

整个流程全部执行完毕

原文地址:https://www.cnblogs.com/yxh168/p/12360059.html