扩展 Kubernetes Controller 的三种方式

扩展 Kubernetes Controller 的三种方式

一、Operator 方式

1.1 Operator 简介

Operator 是 Kubernetes 中的一种高级扩展模式,结合了 CRD 和自定义控制器,扩展了 Kubernetes API 资源。用户可以通过 Operator 像管理 Kubernetes 内置资源一样创建、配置和管理应用程序。

Operator 是一个特定应用程序的控制器,通过扩展 Kubernetes API 资源来代表 Kubernetes 用户创建、配置和管理复杂应用程序的实例。通常,Operator 包含资源模型定义和控制器,用于实现某种特定软件(通常是有状态服务)的自动化运维。

1.2 Operator 的核心概念

  • 自定义资源(CRD):通过 CRD,可以在 Kubernetes 中定义新的资源类型,这些资源可以表示任何你想要管理的对象(例如数据库、有状态应用等)。
  • 自定义控制器:自定义控制器通过 watch Kubernetes API 服务器中的资源变化,根据这些变化触发相应的逻辑(例如创建、更新或删除 Pods、Services 等)。

1.3 Operator 的优势

  • 领域特定知识:Operator 可以封装特定领域的知识,简化用户的使用。
  • 自动化运维:通过 Operator,用户可以自动化部署、配置和管理复杂的应用。
  • 声明式 API:提供声明式的接口,用户只需定义期望状态,Operator 负责实现。

1.4 Operator 的实现框架

  • kubebuilder:一个用于快速开发 Operator 的工具链。
  • Operator Framework:提供 Operator 开发的工具和库,支持 Go、Java 等多种语言。

1.5 Operator 的工作流程

  1. 定义 CRD:通过 kubectl 或 API 创建一个 CRD,定义新的资源类型。

    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      name: example.com
    spec:
      group: example.com
      versions:
        - name: v1
          served: true
          storage: true
      scope: Namespaced
      names:
        plural: examples
        singular: example
        kind: Example
    
  2. 实现 Operator 控制器:编写一个控制器,监听 CRD 的变化。当 CRD 被创建、更新或删除时,控制器会触发相应的逻辑。

    package main
    
    import (
        "fmt"
        "os"
        "sigs.k8s.io/controller-runtime/pkg/client"
        "sigs.k8s.io/controller-runtime/pkg/controller"
        "sigs.k8s.io/controller-runtime/pkg/handler"
        "sigs.k8s.io/controller-runtime/pkg/manager"
        "sigs.k8s.io/controller-runtime/pkg/reconcile"
        "sigs.k8s.io/controller-runtime/pkg/source"
    )
    
    func main() {
        mgr, err := manager.New(cfg, manager.Options{})
        if err != nil {
            fmt.Printf("无法创建管理器:%v", err)
            os.Exit(1)
        }
    
        err = mgr.AddController(&controller.Controller{
            Name:    "example-controller",
            Reconciler: &reconcile.Reconciler{
                Reconcile: reconcileExample,
            },
            Watchers: []source.Source{
                &source.Kind{Type: &v1.Example{}},
            },
            Options: controller.Options{},
        })
        if err != nil {
            fmt.Printf("无法添加控制器:%v", err)
            os.Exit(1)
        }
    
        err = mgr.Start(ctrl.SetupSignalHandler())
        if err != nil {
            fmt.Printf("无法启动管理器:%v", err)
            os.Exit(1)
        }
    }
    
  3. 部署 Operator:将 Operator 作为一个 Kubernetes 部署(Deployment)或守护进程集(DaemonSet)运行在集群中。

二、扩展 API Server

2.1 查询所有 API Resources

查看所有类型的 api-resources,包括自己创建的 CR。

kubectl api-resources

2.2 API Service 详解

在 Kubernetes 中,API Service(APIService)是一个用于扩展 Kubernetes API 的机制。它允许你在 Kubernetes 集群中注册和发现自定义的 API 服务器(Custom API Server),从而扩展 Kubernetes 的功能。

2.2.1 APIService 的核心概念
  1. API 聚合层:Kubernetes 的 API 聚合层允许将多个 API 服务器聚合到一起,形成一个统一的 API 网关。
  2. APIService 资源:APIService 是 Kubernetes 的一个资源类型,用于定义如何访问一个外部的 API 服务器。
  3. 自定义 API 服务器:自定义 API 服务器是一个独立的组件,提供新的 API 资源类型。
2.2.2 查询 APIService
kubectl get apiservice
2.2.3 APIService 的结构

一个 APIService 的配置文件通常包含以下字段:

apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  name: <api-service-name>
spec:
  group: <api-group>
  version: <api-version>
  groupPriorityMinimum: <priority>
  versionPriority: <version-priority>
  service:
    name: <service-name>
    namespace: <service-namespace>
  # 可选字段
  insecureSkipTLSVerify: <bool>
  caBundle: <base64-encoded-certificate>

2.3 API Server 详解

2.3.1 Kubernetes API Server(kube-apiserver)的作用
  • 处理 API 请求:接收并处理来自客户端的所有 API 请求。
  • 数据存储:维护集群的状态数据,通常使用 etcd 作为底层存储。
  • 认证与授权:验证客户端的身份和权限。
  • API 聚合:支持聚合多个 API 服务,形成一个统一的 API 网关。
2.3.2 kube-apiserver 与客户端的交互
  1. 请求方式:客户端通过 HTTP 协议与 kube-apiserver 进行交互。
  2. 请求格式:客户端发送的请求通常遵循 RESTful API 的规范。
  3. 认证与授权:客户端需要提供身份凭证,kube-apiserver 使用 RBAC 来验证权限。
  4. 示例请求
    kubectl get pods
    
2.3.3 kube-apiserver 与 Local APIService 的交互
  1. APIService 的概念:Local 类型的 APIService 表示这些 API 服务是由 kube-apiserver 本身提供的。
  2. 交互机制:kube-apiserver 的聚合层会将所有注册的 APIService 聚合到一起,形成一个统一的 API 网关。
  3. 数据流动:客户端发送请求,kube-apiserver 根据请求的路径和版本,确定对应的 APIService。
  4. 示例
    kubectl get deployment my-deployment
    

2.4 API 聚合层详解

API 聚合层(Aggregation Layer)是 Kubernetes 的一个高级功能,允许用户通过扩展 Kubernetes 的 API,添加新的 API 路径和功能。

2.4.1 API 聚合层的工作原理

要使用聚合层,用户需要创建一个 APIService 对象。APIService 是 Kubernetes 的一个资源对象,用于声明一个 API 的路径。

2.4.2 API 聚合层的运行

聚合层在 kube-apiserver 进程内运行。当一个 API 请求到达 kube-apiserver 时,聚合层会检查请求的路径。如果路径匹配某个已注册的 APIService 对象,聚合层会将请求转发到对应的外部 API 服务器。

2.4.3 API 聚合层与 CRD 的区别
  • 编程需求:API 聚合层需要编程,CRD 无需编程。
  • API 服务器:API 聚合层需要一个独立的 API 服务器,CRD 不需要。
  • API 版本控制:API 聚合层支持多个 API 版本,CRD 的版本控制相对简单。
  • 支持的操作:API 聚合层支持所有 CRUD 操作,CRD 仅支持基本的 CRUD 操作。
  • 维护成本:API 聚合层维护成本较高,CRD 维护成本较低。
  • 适用场景:API 聚合层适用于需要高度灵活性和自定义行为的场景,CRD 适用于需要快速扩展 Kubernetes 功能的场景。

2.5 扩展 API Server

扩展 API Server 是另一种扩展 Kubernetes 的方式,允许你在 Kubernetes 集群中添加新的 API 组(API Group),从而支持新的资源类型和操作。

2.5.1 扩展 API Server 的核心概念
  • API 组:通过扩展 API Server,可以定义一个新的 API 组(如 example.com),并在其中添加新的资源类型。
  • 资源实现:扩展 API Server 需要实现对新资源的 CRUD 操作(创建、读取、更新、删除)。
2.5.2 实现扩展 API Server 的步骤
  1. 定义 APIService

    apiVersion: apiregistration.k8s.io/v1
    kind: APIService
    metadata:
      name: v1.example.com
    spec:
      group: example.com
      version: v1
      groupPriorityMinimum: 100
      versionPriority: 10
      service:
        name: example-api-server
        namespace: default
      insecureSkipTLSVerify: true
    
  2. 创建 Service

    apiVersion: v1
    kind: Service
    metadata:
      name: example-api-server
    spec:
      selector:
        app: example-api-server
      ports:
        - name: http
          port: 80
          targetPort: 8080
    
  3. 实现 API Server

    package main
    
    import (
        "context"
        "flag"
        "github.com/go-logr/logr"
        "k8s.io/apimachinery/pkg/runtime"
        "k8s.io/apimachinery/pkg/util/validation/field"
        "k8s.io/apiserver/pkg/endpoints/request"
        "k8s.io/apiserver/pkg/server"
        "k8s.io/apiserver/pkg/server/routes"
        "k8s.io/client-go/rest"
    )
    
    func main() {
        // 配置 API Server
        config := server.NewConfig()
        config.Version = "v1"
        config.Handler = newHandler()
        config.Authentication = authentication.NewConfig()
        config.Authorization = authorization.NewConfig()
    
        // 启动 API Server
        server, err := server.New(config)
        if err != nil {
            log.Error(err, "无法创建 API Server")
            os.Exit(1)
        }
    
        if err := server.Start(); err != nil {
            log.Error(err, "无法启动 API Server")
            os.Exit(1)
        }
    }
    
    func newHandler() http.Handler {
        mux := http.NewServeMux()
        mux.HandleFunc("/example", handleExample)
        return mux
    }
    
    func handleExample(w http.ResponseWriter, r *http.Request) {
        // 实现 CRUD 逻辑
    }
    
  4. 部署自定义 API 服务器

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: example-api-server
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: example-api-server
      template:
        metadata:
          labels:
            app: example-api-server
        spec:
          containers:
            - name: example-api-server
              image: your-custom-api-server:latest
              ports:
                - containerPort: 8080
    
  5. 应用配置

    kubectl apply -f apiservice.yaml
    kubectl apply -f service.yaml
    kubectl apply -f deployment.yaml
    

三、Admission Controller(准入控制器)

Admission Controller 是 Kubernetes 中一个强大的扩展机制,允许用户在 API 请求被处理之前对请求进行验证、修改或拒绝。Kubernetes 提供了两种主要的准入控制器实现方式:Server-Side Admission 和 Webhook Admission。

3.1 Server-Side Admission

  • 开发语言:使用 Go 语言编写插件。
  • 插件开发:开发者需要实现 Kubernetes 的准入控制器接口。
  • 编译与部署:插件需要编译成共享库,并在 API Server 的配置文件中加载。

3.2 Webhook Admission

  • 开发语言:允许使用任何语言编写 Webhook 服务。
  • 服务暴露:开发者需要编写一个独立的 Web 服务。
  • 配置与注册:在 Kubernetes API Server 的配置文件中注册 Webhook 服务。

3.3 准入控制器的工作流程

  1. 请求到达 API Server:客户端发送一个 API 请求到 Kubernetes API Server。
  2. 准入控制器拦截请求:API Server 调用所有已注册的准入控制器对请求进行处理。
  3. 准入控制器处理逻辑
    • Server-Side Admission:插件在 API Server 内部对请求进行处理。
    • Webhook Admission:API Server 将请求转发到 Webhook 服务。
  4. 处理结果
    • 允许:API Server 继续处理请求。
    • 拒绝:API Server 返回错误信息给客户端。
    • 修改:准入控制器可以对请求进行修改。
  5. 响应客户端:API Server 将处理结果返回给客户端。

3.4 准入控制的优缺点

Server-Side Admission 的优缺点
  • 优点
    • 性能:处理速度较快,延迟较低。
    • 权限:插件可以访问 Kubernetes API Server 的所有内部功能。
    • 稳定:插件的运行状态直接影响 API Server 的性能。
  • 缺点
    • 耦合性:插件与 API Server 有较强的耦合性。
    • 复杂性:开发和维护成本较高。
Webhook Admission 的优缺点
  • 优点
    • 解耦:Webhook 服务独立于 Kubernetes API Server。
    • 灵活性:可以使用任何语言开发 Webhook 服务。
    • 易于扩展:可以根据需要动态扩展 Webhook 服务的处理能力。
  • 缺点
    • 延迟:可能会增加请求的处理时间。
    • 复杂性:需要管理 Webhook 服务的部署、可用性和安全性。

3.5 实际应用中的注意事项

  • 性能考虑:对于高负载的集群,Server-Side Admission 通常比 Webhook Admission 更优。
  • 安全性:确保 Webhook 服务的安全性,使用 TLS 加密通信。
  • 可靠性:确保准入控制器的稳定性和可靠性。
  • 监控与日志:配置监控工具,启用详细的日志记录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值