Kubernetes CLI-Runtime 详解
约 1297 字大约 4 分钟
2025-09-08
k8s.io/cli-runtime 是 Kubernetes 官方提供的一个 Go 库,专门用于构建 Kubernetes 命令行工具。它为 kubectl 等工具提供了核心的运行时功能,包括资源发现、对象操作、输出格式化等。
什么是 CLI-Runtime
CLI-Runtime 是 Kubernetes 生态系统中的一个重要组件,它提供了:
- 统一的命令行接口:为所有 Kubernetes 工具提供一致的命令行体验
- 资源发现机制:自动发现集群中的 API 资源和版本
- 对象操作抽象:提供统一的资源创建、读取、更新、删除操作
- 输出格式化:支持多种输出格式(JSON、YAML、表格等)
- 配置管理:处理 kubeconfig 文件和认证
核心组件
1. RESTClient 和 DynamicClient
import (
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
)
// 创建配置
configFlags := genericclioptions.NewConfigFlags(true)
config, err := configFlags.ToRESTConfig()
if err != nil {
return err
}
// 创建动态客户端
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
return err
}2. Resource Builder
import "k8s.io/cli-runtime/pkg/resource"
// 创建资源构建器
builder := resource.NewBuilder(configFlags).
Unstructured().
ContinueOnError().
Local().
Flatten()
// 从文件读取资源
result := builder.FilenameParam(false, &resource.FilenameOptions{
Recursive: false,
Filenames: []string{"deployment.yaml"},
}).Do()
// 获取资源对象
infos, err := result.Infos()
if err != nil {
return err
}3. 输出格式化
import "k8s.io/cli-runtime/pkg/printers"
// 创建打印机
printer := &printers.YAMLPrinter{}
// 打印资源
for _, info := range infos {
if err := printer.PrintObj(info.Object, os.Stdout); err != nil {
return err
}
}使用示例
基本用法
package main
import (
"fmt"
"os"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/cli-runtime/pkg/printers"
)
func main() {
// 1. 创建配置标志
configFlags := genericclioptions.NewConfigFlags(true)
// 2. 获取 REST 配置
config, err := configFlags.ToRESTConfig()
if err != nil {
fmt.Printf("Error getting config: %v\n", err)
os.Exit(1)
}
// 3. 创建资源构建器
builder := resource.NewBuilder(configFlags).
Unstructured().
ContinueOnError().
Local().
Flatten()
// 4. 从文件读取资源
result := builder.FilenameParam(false, &resource.FilenameOptions{
Recursive: false,
Filenames: []string{"deployment.yaml"},
}).Do()
// 5. 获取资源信息
infos, err := result.Infos()
if err != nil {
fmt.Printf("Error getting infos: %v\n", err)
os.Exit(1)
}
// 6. 打印资源
printer := &printers.YAMLPrinter{}
for _, info := range infos {
fmt.Printf("Resource: %s/%s\n", info.Namespace, info.Name)
if err := printer.PrintObj(info.Object, os.Stdout); err != nil {
fmt.Printf("Error printing object: %v\n", err)
}
}
}动态资源操作
import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// 创建动态客户端
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
return err
}
// 定义资源组版本
gvr := schema.GroupVersionResource{
Group: "apps",
Version: "v1",
Resource: "deployments",
}
// 获取资源
obj, err := dynamicClient.Resource(gvr).
Namespace("default").
Get(context.TODO(), "my-deployment", metav1.GetOptions{})
if err != nil {
return err
}
// 修改资源
unstructuredObj := obj.(*unstructured.Unstructured)
unstructured.SetNestedField(unstructuredObj.Object, 3, "spec", "replicas")
// 更新资源
_, err = dynamicClient.Resource(gvr).
Namespace("default").
Update(context.TODO(), unstructuredObj, metav1.UpdateOptions{})
if err != nil {
return err
}核心原理
1. 资源发现机制
CLI-Runtime 通过以下步骤发现集群中的资源:
// 1. 获取 API 组列表
apiGroups, err := discoveryClient.ServerGroups()
if err != nil {
return err
}
// 2. 获取每个组的资源
for _, group := range apiGroups.Groups {
groupVersion := group.PreferredVersion.GroupVersion
resources, err := discoveryClient.ServerResourcesForGroupVersion(groupVersion)
if err != nil {
continue
}
// 处理资源
for _, resource := range resources.APIResources {
// 构建 GVR
gvr := schema.GroupVersionResource{
Group: group.Name,
Version: groupVersion,
Resource: resource.Name,
}
}
}2. 资源构建器模式
Resource Builder 使用建造者模式来构建资源操作:
type Builder struct {
configFlags *genericclioptions.ConfigFlags
unstructured bool
continueOnError bool
local bool
flatten bool
filenames []string
}
func (b *Builder) Unstructured() *Builder {
b.unstructured = true
return b
}
func (b *Builder) FilenameParam(recursive bool, options *FilenameOptions) *Builder {
b.filenames = options.Filenames
return b
}
func (b *Builder) Do() *Result {
// 执行资源构建逻辑
return &Result{builder: b}
}3. 输出格式化系统
CLI-Runtime 提供了灵活的打印系统:
type Printer interface {
PrintObj(obj runtime.Object, w io.Writer) error
}
// 内置打印机类型
type JSONPrinter struct{}
type YAMLPrinter struct{}
type TablePrinter struct{}
type NamePrinter struct{}高级特性
1. 自定义资源支持
// 注册自定义资源
scheme := runtime.NewScheme()
scheme.AddKnownTypes(schema.GroupVersion{
Group: "mycompany.com",
Version: "v1",
}, &MyCustomResource{})
// 使用自定义 scheme
codecFactory := serializer.NewCodecFactory(scheme)
decoder := codecFactory.UniversalDecoder()2. 批量操作
// 批量创建资源
visitor := resource.NewFlattenListVisitor(infos, resourceMapper)
err := visitor.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
// 创建资源
obj, err := resource.NewHelper(info.Client, info.Mapping).
Create(info.Namespace, true, info.Object)
if err != nil {
return err
}
info.Refresh(obj, true)
return nil
})3. 错误处理
// 继续处理错误
builder := resource.NewBuilder(configFlags).
ContinueOnError() // 遇到错误时继续处理其他资源
result := builder.Do()
errs := []error{}
err := result.Visit(func(info *resource.Info, err error) error {
if err != nil {
errs = append(errs, err)
return nil // 继续处理
}
// 处理资源
return nil
})
// 处理所有错误
if len(errs) > 0 {
for _, err := range errs {
fmt.Printf("Error: %v\n", err)
}
}最佳实践
1. 配置管理
// 使用环境变量和配置文件
configFlags := genericclioptions.NewConfigFlags(true)
configFlags.AddFlags(flagSet)
// 支持多种配置源
// 1. 命令行参数
// 2. 环境变量
// 3. kubeconfig 文件
// 4. 集群内配置(in-cluster)2. 资源验证
// 验证资源
validator := validation.NewSchemaValidator(schema, nil, nil, false)
errs := validator.Validate(obj)
if len(errs) > 0 {
return fmt.Errorf("validation failed: %v", errs)
}3. 并发处理
// 使用工作池处理大量资源
type Worker struct {
id int
workChan <-chan *resource.Info
resultChan chan<- error
}
func (w *Worker) process() {
for info := range w.workChan {
err := w.processResource(info)
w.resultChan <- err
}
}总结
k8s.io/cli-runtime 是构建 Kubernetes 命令行工具的核心库,它提供了:
- 统一的接口:为所有 K8s 工具提供一致的开发体验
- 资源抽象:简化了 Kubernetes 资源的操作
- 灵活的配置:支持多种配置方式和认证机制
- 强大的输出:提供多种输出格式和自定义选项
- 错误处理:完善的错误处理和恢复机制
通过使用 CLI-Runtime,开发者可以快速构建出功能强大、用户友好的 Kubernetes 命令行工具,而无需关心底层的复杂实现细节。
更新日志
2025/9/8 11:04
查看所有更新日志
b0257-add client runtime于
