【Sigma敏捷版系列文章】如何利用apiserver-builder自定义Kubernetes API

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: apiserver-builder提供了一套标准的k8s API构建规范,构建的API可以通过k8s汇聚层实现对k8s API的扩展,另外我们可以看到通过apiserver-builder来构建出来的项目完全可以作为一个独立系统运行。

背景知识

了解一下k8s API

k8s中的API可以抽象为两个阶段:存储和调和。
存储(Storage):
Kubernetes API公开了用于存储声明期望集群状态的资源对象的操作
调和(Reconciliation):
通常称为控制器(controller)的进程集合监视写入资源的对象进行调和
如图:
undefined
API具有如下特征:
1、Declarative(声明式)
Kubernetes API被设计为:对象的期望状态被发送到API服务器,该服务器集群用于协调实际状态与期望的状态
2、Level based (基于等级)
基于等级的实现会依据当前最新的状态,而忽略先前的期望状态。例如执行Deployment更新镜像的时候,如果当前设置的是镜像A没有更新完成时,这时候又更新Deployment设置为镜像B,则会按照最新的B进行更新。
3、Asynchronous (异步)
API是按照异步方式执行,在按照期望值进行调和的过程中,已经返回了请求的结果信息。这就意味着用户请求时候不会返回错误的信息。如果调和的过程中发生错误(如镜像版本错误),则会设置到状态的信息字段上面。

K8s中自定义资源

Kubernetes提供了两种向群集添加自定义资源的方法:
1、自定义资源定义(CRD):更易于使用,在某些情况下,它们不需要任何编程。
自定义资源定义(CRDS)允许用户创建新类型的资源而无需添加其他API服务器。您不需要了解API Aggregation就可以使用CRD。
2、API聚合:需要编程,但允许更多的API行为控制,如数据如何存储以及API版本之间的转换。
Kubernetes提供了这两种选择来满足不同用户的需求,从而既不易于使用又不会降低灵活性。

无论是通过CRD还是API聚合安装,新资源都称为“自定义资源”,以将它们与内置Kubernetes资源(如Pod)区分开来。
今天我们介绍就是汇聚层API的构建方案:apiserver-builder。同时也是一种可以独立部署k8s式API服务的自动构建方式

概述

apiserver-builder基于k8s中的api-machinery之上开发全功能Kubernetes API,同时具备项目独立部署的特点。 这意味着允许扩展API在Kubernetes之外开发,并作为一个包单独安装。
功能特点:
1、可以作为新资源的类型定义,控制器,测试和文档的工具
2、可以作为独立构建和运行扩展控制平面的工具。
3、从控制器轻松list-watch和更新Kubernetes API类型
4、轻松添加新资源和子资源
5、为大多数接口属性提供了默认值,并且可以被覆盖

开发实践

安装apiserver构建工具

1.下载最新的alpha版本:
https://github.com/kubernetes-incubator/apiserver-builder/releases/download/v1.9-alpha.4/apiserver-builder-v1.9-alpha.4-linux-amd64.tar.gz
2.export PATH=$PATH:/root/apiserver-builder/bin
3.创建一个Go工程(demo)在GOPATH/src/目录下
4.创建copyright
在GOPATH/src/demo工程目录下创建文件boilerplate.go.txt
内容:

/*
Copyright 2017 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

初始化工程

初始化工程中将会设置apiserver最初的代码结构,包括go vendor库,这个是从下载的apiserver-builder二进制tar包复制过来的。
1.设置domin作为api group

#apiserver-boot init repo --domain demo.alibaba.com

我们可以看到生成的代码结构:
undefined

2.开始创建API资源:
API 资源定义包括group (类似package),version (版本:v1alpha1, v1beta1, v1),和Kind (资源类型)
运行“apiserver-boot create group version resource” 命令进行创建

#apiserver-boot create group version resource --group demo --version v1alpha1  --kind Bird

注意:资源类型需要首字母大写
undefined
3.本地可以运行apiserver和controller:

#apiserver-boot run local

undefined
4.通过kubectl验证:

kubectl --kubeconfig=kubeconfig api-versions

undefined

5.创建示例资源

kubectl --kubeconfig=kubeconfig create -f sample/bird.yaml

undefined

这样我们通过apiserver-builder轻松的扩展了k8s资源接口

扩展资源说明

资源定义

资源定义主要包括3部分
1、Metadata:元数据信息
Name (唯一key值)
Annotations (描述信息key-value键值对)
Labels (用于查询的key-value键值对)
2、Spec: 期望的状态信息
用来设置期望的状态字段,调和器(controller)依据这些期望的属性更新集群内部或外部的对象
3、Status: 结果状态信息
用来设置结果属性的状态字段
构建代码如下:

// Bird
// +k8s:openapi-gen=true
// +resource:path=birds,strategy=BirdStrategy
type Bird struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   BirdSpec   `json:"spec,omitempty"`
    Status BirdStatus `json:"status,omitempty"`
}

// BirdSpec defines the desired state of Bird
type BirdSpec struct {
}

// BirdStatus defines the observed state of Bird
type BirdStatus struct {
}

资源存储

在资源存储操作执行期间,我们可以通过如下几种方式验证或者修改存储的对象。
undefined

创建操作

1.DefaultingFunction:可以设置默认值

// DefaultingFunction sets default Bird field values
func (BirdSchemeFns) DefaultingFunction(o interface{}) {
    obj := o.(*Bird)
    // set default field values here
    log.Printf("Defaulting fields for Bird %s\n", obj.Name)
}

2.PrepareForCreate:修改对象属性,设置初始化或者资源回收
如下面的代码展示了k8s中pod资源通过PrepareForCreate方法设置Pending状态

// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (podStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) {
    pod := obj.(*api.Pod)
    pod.Status = api.PodStatus{
        Phase:    api.PodPending,
        QOSClass: qos.GetPodQOS(pod),
    }

    podutil.DropDisabledAlphaFields(&pod.Spec)
}

如果代码中没有显示的定义PrepareForCreate方法,会默认执行apiserver-builder的该方法

func (DefaultStorageStrategy) PrepareForCreate(ctx request.Context, obj runtime.Object) {
    switch t := obj.(type) {
    default:
    case HasObjectMetaSpecStatus:
        // Clear the status if the resource has a Status
        t.GetObjectMeta().Generation = 1
        t.SetStatus(t.NewStatus())
    }
}

3.Validate:验证值的合法性,如果不合法可以直接拒绝创建请求

// Validate checks that an instance of Bird is well formed
func (BirdStrategy) Validate(ctx request.Context, obj runtime.Object) field.ErrorList {
    o := obj.(*demo.Bird)
    log.Printf("Validating fields for Bird %s\n", o.Name)
    errors := field.ErrorList{}
    // perform validation here and add to errors using field.Invalid
    return errors
}

4.Canonicalize(规范化):对象存储前最后一道修改的入口,用于将存储对象进行规范化,如将一些无序的数据进行排列以利于分析预测。

func (DefaultStorageStrategy) Canonicalize(obj runtime.Object) {}

更新操作:

包括ValidateUpdate和PrepareForUpdate,分别用于更新是的验证和预处理

删除操作

Finalizers: 需要通过Controller手动回收下游资源.
如果在对象上指定了回收器(例如PrepareForCreate),则删除对象将使用宽限期设置对象上的DeletionTimestamp字段。 控制器接收到该对象已被删除信息后,对创建的资源进行清理。
OwnerReference:通过apiserver自动回收下游资源

资源调和(Reconciliation)

undefined
通过控制器,实现调和

控制器初始化

在controller.go中我们可以看到初始化方法


// Init initializes the controller and is called by the generated code
// Register watches for additional resource types here.
func (c *BirdControllerImpl) Init(arguments sharedinformers.ControllerInitArguments) {
    // Use the lister for indexing birds labels
    c.lister = arguments.GetSharedInformers().Factory.Demo().V1alpha1().Birds().Lister()
}

调和

通过watch资源变化,对资源进行调和操作

// Reconcile handles enqueued messages
func (c *BirdControllerImpl) Reconcile(u *v1alpha1.Bird) error {
    // Implement controller logic here
    log.Printf("Running reconcile Bird for %s\n", u.Name)
    return nil
}

调和操作包括:
1.更新对象属性metadata, spec or status
2.创建、更新、删除k8s中其它资源(如pod)
3.创建、更新、删除k8s外的其它资源(如cloudprovider提供的云盘存储等)

总结

apiserver-builder提供了一套标准的k8s API构建规范,构建的API可以通过k8s汇聚层实现对k8s API的扩展,另外我们可以看到通过apiserver-builder来构建出来的项目完全可以作为一个独立系统运行。试想一下当你可以自动构建一个拥有面向终态的设计模式加上支持k8s生态组件(kubectl等)的工程的时候,it's amazing!
在近期的项目中我们也是采用了apiserver-builder构建了一套独立的系统,为用户提供了k8s式的服务访问模式,有兴趣的欢迎一起交流。

参考

1、https://github.com/kubernetes-incubator/apiserver-builder/blob/master/docs/concepts/api_building_overview.md
2、https://kubernetes.io/docs/concepts/api-extension/custom-resources/
3、https://github.com/kubernetes-incubator/apiserver-builder/blob/master/docs/tools_user_guide.md

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
1月前
|
Kubernetes 安全 Cloud Native
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
本文介绍了云原生环境下Kubernetes集群的安全问题及攻击方法。首先概述了云环境下的新型攻击路径,如通过虚拟机攻击云管理平台、容器逃逸控制宿主机等。接着详细解释了Kubernetes集群架构,并列举了常见组件的默认端口及其安全隐患。文章通过具体案例演示了API Server 8080和6443端口未授权访问的攻击过程,以及Kubelet 10250端口未授权访问的利用方法,展示了如何通过这些漏洞实现权限提升和横向渗透。
151 0
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
|
2月前
|
JSON API 数据库
从零到英雄?一篇文章带你搞定Python Web开发中的RESTful API实现!
在Python的Web开发领域中,RESTful API是核心技能之一。本教程将从零开始,通过实战案例教你如何使用Flask框架搭建RESTful API。首先确保已安装Python和Flask,接着通过创建一个简单的用户管理系统,逐步实现用户信息的增删改查(CRUD)操作。我们将定义路由并处理HTTP请求,最终构建出功能完整的Web服务。无论是初学者还是有经验的开发者,都能从中受益,迈出成为Web开发高手的重要一步。
59 4
|
3月前
|
域名解析 网络协议 API
【API管理 APIM】APIM集成内部VNet时,常遇见的关于自定义DNS服务问题。
【API管理 APIM】APIM集成内部VNet时,常遇见的关于自定义DNS服务问题。
|
3月前
|
资源调度 Kubernetes API
在K8S中,能否实现不通过api-Server创建Pod?
在K8S中,能否实现不通过api-Server创建Pod?
|
3月前
|
SQL Shell API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
|
3月前
|
中间件 API 网络架构
Django后端架构开发:从匿名用户API节流到REST自定义认证
Django后端架构开发:从匿名用户API节流到REST自定义认证
41 0
|
3月前
|
SQL 网络协议 安全
【Azure API 管理】APIM集成内网虚拟网络后,启用自定义路由管理外出流量经过防火墙(Firewall),遇见APIs加载不出来问题
【Azure API 管理】APIM集成内网虚拟网络后,启用自定义路由管理外出流量经过防火墙(Firewall),遇见APIs加载不出来问题
|
3月前
|
Kubernetes 负载均衡 API
在K8S中,api-service 和 kube-schedule 高可用原理是什么?
在K8S中,api-service 和 kube-schedule 高可用原理是什么?
|
3月前
|
Kubernetes 监控 API
在k8S中,各模块如何与API Server进行通信的?
在k8S中,各模块如何与API Server进行通信的?
|
3月前
|
存储 Kubernetes 负载均衡
在K8S中,api-server究竟是如何实现高可用?
在K8S中,api-server究竟是如何实现高可用?

推荐镜像

更多