---
title: Golang client
---

如果要在一个 Golang 项目中对 OpenKruise 的资源做 create/get/update/delete 这些操作、或者通过 informer 做 list-watch，你需要一个支持 OpenKruise 的 client。

你需要在你的项目中引入 [kruise-api](https://github.com/openkruise/kruise-api) 仓库，它包含了 Kruise 的 schema 定义以及 clientset 等工具。

**不要**直接引入整个 [kruise](https://github.com/openkruise/kruise) 仓库作为依赖。

## 使用方式

首先，在你的 `go.mod` 中引入 `kruise-api` 依赖 （版本号最好和你安装的 Kruise 版本相同）：

```
require github.com/openkruise/kruise-api v1.1.0
```

| Kubernetes Version in your Project | Import Kruise-api < v0.10    | Import Kruise-api >= v0.10   |
| ---------------------------------- | ---------------------------- | ---------------------------- |
| < 1.18                             | v0.x.y (x <= 9)              | v0.x.y-legacy (x >= 10)      |
| >= 1.18                            | v0.x.y-1.18 (7 <= x <= 9)    | v0.x.y (x >= 10)             |

然后，有两种方式在你的代码中使用 `kruise-api`：直接使用 或 通过 `controller-runtime` 使用。

如果你的项目是通过 [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder) 或 [operator-sdk](https://github.com/operator-framework/operator-sdk) 生成的，
那么建议你通过 `controller-runtime` 使用。否则，你可以直接使用。

### 直接使用

1. New Kruise client using your rest config:

```go
import kruiseclientset "github.com/openkruise/kruise-api/client/clientset/versioned"

// cfg is the rest config defined in client-go, you should get it using kubeconfig or serviceaccount
kruiseClient := kruiseclientset.NewForConfigOrDie(cfg)
```

2. Get/List Kruise resources:

```go
cloneSet, err := kruiseClient.AppsV1alpha1().CloneSets(namespace).Get(name, metav1.GetOptions{})
cloneSetList, err := kruiseClient.AppsV1alpha1().CloneSets(namespace).List(metav1.ListOptions{})
```

3. Create/Update Kruise resources:

```go
import kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"

cloneSet := kruiseappsv1alpha1.CloneSet{
    // ...
}
err = kruiseClient.AppsV1alpha1().CloneSets(namespace).Create(&cloneSet, metav1.CreateOptions)
```

```go
// Get first
cloneSet, err := kruiseClient.AppsV1alpha1().CloneSets(namespace).Get(name, metav1.GetOptions{})
if err != nil {
    return err
}

// Modify object, such as replicas or template
cloneSet.Spec.Replicas = utilpointer.Int32Ptr(5)

// Update
// This might get conflict, should retry it
if err = kruiseClient.AppsV1alpha1().CloneSets(namespace).Update(&cloneSet, metav1.UpdateOptions); err != nil {
    return err
}
```

4. Watch Kruise resources:

```go
import kruiseinformer "github.com/openkruise/kruise-api/client/informers/externalversions"

kruiseInformerFactory := kruiseinformer.NewSharedInformerFactory(kruiseClient, 0)
kruiseInformerFactory.Apps().V1alpha1().CloneSets().Informer().AddEventHandler(...)
kruiseInformerFactory.Start(...)
```

### 通过 controller-runtime 使用

1. Add kruise apis into the scheme in your `main.go`

```go
import kruiseapi "github.com/openkruise/kruise-api"

// ...
_ = kruiseapi.AddToScheme(scheme)
```

2. New client

This is needed when use controller-runtime client directly.

If your project is generated by [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder) or [operator-sdk](https://github.com/operator-framework/operator-sdk),
you should get the client from `mgr.GetClient()` instead of the example below.

```go
import "sigs.k8s.io/controller-runtime/pkg/client"

apiClient, err := client.New(c, client.Options{Scheme: scheme})
```

3. Get/List

```go
import (
    kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
    "sigs.k8s.io/controller-runtime/pkg/client"
)

cloneSet := kruiseappsv1alpha1.CloneSet{}
err = apiClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: name}, &cloneSet)

cloneSetList := kruiseappsv1alpha1.CloneSetList{}
err = apiClient.List(context.TODO(), &cloneSetList, client.InNamespace(instance.Namespace))
```

4. Create/Update/Delete

Create a new CloneSet:

```go
import kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"

cloneSet := kruiseappsv1alpha1.CloneSet{
    // ...
}
err = apiClient.Create(context.TODO(), &cloneSet)
```

Update an existing CloneSet:

```go
import kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"

// Get first
cloneSet := kruiseappsv1alpha1.CloneSet{}
if err = apiClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: name}, &cloneSet); err != nil {
    return err
}

// Modify object, such as replicas or template
cloneSet.Spec.Replicas = utilpointer.Int32Ptr(5)

// Update
// This might get conflict, should retry it
if err = apiClient.Update(context.TODO(), &cloneSet); err != nil {
    return err
}
```

5. List watch and informer

If your project is generated by [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder) or [operator-sdk](https://github.com/operator-framework/operator-sdk) and get the client from `mgr.GetClient()`,
then methods like `Get`/`List` have already queried from informer instead of apiserver.
