Dynamic Client 动态客户端
适用场景
- 操作 CRD(自定义资源),编译时不知道类型
- 编写通用工具(如 kubectl、Helm)
- 处理任意 K8s 资源
基本使用
go
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
)
dynamicClient, err := dynamic.NewForConfig(config)
// 定义 GVR(Group/Version/Resource)
deployGVR := schema.GroupVersionResource{
Group: "apps",
Version: "v1",
Resource: "deployments",
}
// 列出资源
list, err := dynamicClient.Resource(deployGVR).Namespace("default").List(ctx, metav1.ListOptions{})
for _, item := range list.Items {
name, _, _ := unstructured.NestedString(item.Object, "metadata", "name")
replicas, _, _ := unstructured.NestedInt64(item.Object, "spec", "replicas")
fmt.Printf("Deployment: %s, Replicas: %d\n", name, replicas)
}
// 获取单个资源
obj, err := dynamicClient.Resource(deployGVR).Namespace("default").Get(ctx, "my-app", metav1.GetOptions{})
// 创建 CRD 资源
crdObj := &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "mygroup.io/v1",
"kind": "MyResource",
"metadata": map[string]interface{}{
"name": "my-resource",
"namespace": "default",
},
"spec": map[string]interface{}{
"replicas": int64(3),
"image": "my-app:v1",
},
},
}
myGVR := schema.GroupVersionResource{Group: "mygroup.io", Version: "v1", Resource: "myresources"}
_, err = dynamicClient.Resource(myGVR).Namespace("default").Create(ctx, crdObj, metav1.CreateOptions{})Unstructured 操作
go
// 读取嵌套字段
name, found, err := unstructured.NestedString(obj.Object, "metadata", "name")
replicas, found, err := unstructured.NestedInt64(obj.Object, "spec", "replicas")
labels, found, err := unstructured.NestedStringMap(obj.Object, "metadata", "labels")
containers, found, err := unstructured.NestedSlice(obj.Object, "spec", "template", "spec", "containers")
// 设置嵌套字段
unstructured.SetNestedField(obj.Object, int64(5), "spec", "replicas")
unstructured.SetNestedStringMap(obj.Object, map[string]string{"version": "v2"}, "metadata", "labels")
// 转换为具体类型
var deploy appsv1.Deployment
err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deploy)
// 转换为 Unstructured
unstructuredObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&deploy)服务端应用(Server-Side Apply)
go
// 使用 SSA 进行声明式更新(推荐)
patch := &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "my-app",
"namespace": "default",
},
"spec": map[string]interface{}{
"replicas": int64(5),
},
},
}
data, _ := json.Marshal(patch.Object)
_, err = dynamicClient.Resource(deployGVR).Namespace("default").Patch(
ctx, "my-app",
types.ApplyPatchType,
data,
metav1.PatchOptions{
FieldManager: "my-controller",
Force: pointer.Bool(true),
},
)