开源项目 controller-idioms 使用教程
1. 项目介绍
controller-idioms 是一个用于构建符合 Kubernetes 控制器最佳实践的通用库集合。该项目由 Authzed 开发,旨在扩展 Kubernetes 基础库(如 controller-runtime),以实现 Kubernetes 控制器的最佳实践。这些库最初是为构建 SpiceDB Operator 和 Authzed Dedicated 内部项目而开发的。
controller-idioms 提供了多种实用工具,包括:
- adopt: 高效地监视控制器不拥有的资源(例如,对 secret 或 configmap 的引用)。
- bootstrap: 安装所需的 CRD 和默认 CR,通常用于 CD 管道。
- component: 管理和聚合为其他资源创建的资源。
- fileinformer: 监视本地文件的 InformerFactory,通常用于加载配置而不重启。
- hash: 对资源进行哈希处理以检测修改。
- metrics: 为实现标准
metav1.Condition数组的资源提供指标。 - pause: 允许用户在不停止控制器的情况下停止特定资源的协调处理。
- static: 用于在启动时始终存在的“静态”资源的控制器。
2. 项目快速启动
环境准备
在开始之前,请确保你已经安装了以下工具:
- Go 语言环境
- Kubernetes 集群
kubectl命令行工具
安装依赖
首先,克隆项目到本地:
git clone https://github.com/authzed/controller-idioms.git
cd controller-idioms
然后,安装项目的依赖:
go mod tidy
编写控制器
以下是一个简单的控制器示例,使用 controller-idioms 库来监视和处理 Kubernetes 资源。
package main
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"github.com/authzed/controller-idioms/pkg/manager"
"github.com/authzed/controller-idioms/pkg/typed"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/dynamic/dynamicinformer"
"k8s.io/client-go/tools/cache"
)
func main() {
// 创建 Kubernetes 客户端
client, err := dynamic.NewForConfig(nil)
if err != nil {
panic(err)
}
// 创建 InformerFactory
informerFactory := dynamicinformer.NewFilteredDynamicSharedInformerFactory(client, 0, "", nil)
// 创建 Indexer
indexer := informerFactory.ForResource(corev1.SchemeGroupVersion.WithResource("secrets")).Informer().Indexer()
secretIndexer := typed.NewIndexer[*corev1.Secret](indexer)
// 创建控制器
ctrl := manager.NewBasicController(
"secret-controller",
func(ctx context.Context, obj interface{}) error {
secret, ok := obj.(*corev1.Secret)
if !ok {
return fmt.Errorf("unexpected object type: %v", obj)
}
fmt.Printf("Processing secret: %s\n", secret.Name)
return nil
},
secretIndexer,
)
// 启动控制器
mgr := manager.NewManager()
mgr.AddController(ctrl)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go mgr.Start(ctx)
// 等待中断信号
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
<-sigCh
fmt.Println("Shutting down...")
cancel()
}
运行控制器
编译并运行控制器:
go run main.go
3. 应用案例和最佳实践
案例1:使用 adopt 监视外部资源
在某些情况下,控制器需要监视它不拥有的资源。例如,一个控制器可能需要监视一个 secret 或 configmap,以便在它们发生变化时采取行动。adopt 库可以帮助你高效地实现这一点。
import (
"github.com/authzed/controller-idioms/pkg/adopt"
)
func main() {
// 创建 Adopt 实例
adopter := adopt.NewAdopter(client, "my-namespace")
// 监视 secret
adopter.Watch(ctx, "my-secret", func(obj interface{}) {
secret, ok := obj.(*corev1.Secret)
if !ok {
return
}
fmt.Printf("Secret %s updated\n", secret.Name)
})
}
案例2:使用 bootstrap 安装 CRD 和默认 CR
在 CI/CD 管道中,通常需要在部署控制器之前安装自定义资源定义(CRD)和默认的自定义资源(CR)。bootstrap 库可以帮助你自动化这一过程。
import (
"github.com/authzed/controller-idioms/pkg/bootstrap"
)
func main() {
// 创建 Bootstrap 实例
bootstrapper := bootstrap.NewBootstrapper(client)
// 安装 CRD 和默认 CR
err := bootstrapper.InstallCRDs(ctx, "path/to/crds")
if err != nil {
panic(err)
}
err = bootstrapper.InstallDefaultCRs(ctx, "path/to/default-crs")
if err != nil {
panic(err)
}
}
4. 典型生态项目
controller-idioms 可以与其他 Kubernetes 生态项目结合使用,以实现更复杂的功能。以下是一些典型的生态项目:
- controller-runtime: Kubernetes 官方提供的控制器运行时库,
controller-idioms可以与其结合使用,以实现更高级的控制器功能。 - kubebuilder: 一个用于构建 Kubernetes 控制器的框架,
controller-idioms可以作为其扩展库,提供更多的实用工具。 - client-go: Kubernetes 官方提供的 Go 客户端库,
controller-idioms依赖于client-go来与 Kubernetes API 进行交互。
通过结合这些生态项目,你可以构建出功能强大且符合最佳实践的 Kubernetes 控制器。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



