如何从Go程序中获取/更新Kubernetes自定义资源?

4

我正在寻找go语言的等效替代:

kubectl get some-custom-resource-kind some-custom-resource -o yaml > file.yaml
Modify the yaml file...
kubectl apply -f file.yaml

Kubernetes为标准资源提供了一个客户端go库。

各种供应商为其自定义资源提供了客户端go库。

但我需要获取/更新一种没有公开可用的客户端go库的资源类型。目前逻辑是在bash脚本中实现的,我正在尝试将该功能移动到go控制器中。

似乎在go中有一种直接进行kubectl等效操作的简单方法。

谢谢,保罗

2个回答

9

对于任何类型,包括您的CRDs,请使用client.Client

从文档中得知:

// Using a typed object.
pod := &corev1.Pod{}
// c is a created client.
_ = c.Get(context.Background(), client.ObjectKey{
    Namespace: "namespace",
    Name:      "name",
}, pod)
pod.SetFinalizers(append(pod.GetFinalizers(), "new-finalizer"))
_ = c.Update(context.Background(), pod)

// Using a unstructured object.
u := &unstructured.Unstructured{}
u.SetGroupVersionKind(schema.GroupVersionKind{
    Group:   "apps",
    Kind:    "Deployment",
    Version: "v1",
})
_ = c.Get(context.Background(), client.ObjectKey{
    Namespace: "namespace",
    Name:      "name",
}, u)
u.SetFinalizers(append(u.GetFinalizers(), "new-finalizer"))
_ = c.Update(context.Background(), u)

你可以轻松地替换为SomeCustomResourceKind:
myCR := &v1alpha1.SomeCustomResourceKind{}

// c is a created client.Client
_ = c.Get(context.TODO(), client.ObjectKey{
  Namespace: "namespace",
  Name:      "some-custom-resource", }, myCR)

myCR.MyProperty = "NewValue"

_ = c.Update(context.TODO(), myCR)

您提到正在将此功能从bash脚本移至Go控制器,因此很值得查看Kubebuilder项目,该项目可以为您搭建一个控制器(以及其他可能需要的API)。它使用controller-runtime Client创建完全功能的控制器,并连接所有协调逻辑以管理您的CRD。


1
以防有人正在寻找相同的解决方案,但不是从Controllers(Operators等)中执行,并且使用go-client包,而是构建本地go二进制文件,请查看dynamic.Interface作为Client Kubernetes的解决方案,https://pkg.go.dev/k8s.io/client-go#readme-whats-included。 - Ualter Jr.

1
我正在创建一个CRD(安全上下文约束),如下所示:
import(
    v1 "github.com/openshift/api/security/v1"
    corev1 "k8s.io/api/core/v1"
    "k8s.io/apimachinery/pkg/api/resource"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func (c *ClusterClient) CreateSCC() {
name := "ssc-test"
scc := v1.SecurityContextConstraints{
    TypeMeta: metav1.TypeMeta{
        Kind:       "SecurityContextConstraints",
        APIVersion: "security.openshift.io/v1",
    },

    ObjectMeta: metav1.ObjectMeta{
        Name: name,
    },
    RequiredDropCapabilities: []corev1.Capability{"KILL", "MKNOD", "SETUID", "SETGID"},
    AllowHostPorts:           false,
    AllowPrivilegedContainer: false,
    AllowHostDirVolumePlugin: false,
    AllowHostIPC:             false,
    ReadOnlyRootFilesystem:   false,
    DefaultAddCapabilities:   nil,
    AllowHostPID:             false,
    AllowHostNetwork:         false,
    AllowedCapabilities:      nil,
    Volumes:                  []v1.FSType{v1.FSTypeConfigMap, v1.FSTypeDownwardAPI, v1.FSTypeEmptyDir, v1.FSTypePersistentVolumeClaim, v1.FSProjected, v1.FSTypeSecret},
    SELinuxContext: v1.SELinuxContextStrategyOptions{
        Type: v1.SELinuxStrategyMustRunAs,
    },
    RunAsUser: v1.RunAsUserStrategyOptions{
        Type: v1.RunAsUserStrategyMustRunAsRange,
    },
    SupplementalGroups: v1.SupplementalGroupsStrategyOptions{
        Type: v1.SupplementalGroupsStrategyRunAsAny,
    },

    Users:  []string{},
    Groups: []string{"system:authenticated"},
}

// To check if scc is already created or not
_, err := c.kubeClient.CoreV1().RESTClient().
    Get().
    AbsPath("/apis/security.openshift.io/v1/securitycontextconstraints/ssc-test").
    DoRaw(context.Background())

// scc is not present in cluster
if err != nil {
    //Creating SCC
    _, err = c.kubeClient.CoreV1().RESTClient().
        Post().
        AbsPath("/apis/security.openshift.io/v1").
        Resource("securitycontextconstraints").
        // VersionedParams(&metav1.CreateOptions{}, scheme.ParameterCodec).
        Body(&scc).
        DoRaw(context.Background())

    if err != nil {
        fmt.Printf("Failed to create SecurityContextConstraints: %v\n", err)
        // return Failure, err
    }
    fmt.Printf("Successfully created SecurityContextConstraints %s\n", name)
}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接