首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >创建k8s资源并等到它完成后再继续到下一个

创建k8s资源并等到它完成后再继续到下一个
EN

Stack Overflow用户
提问于 2021-02-22 18:49:35
回答 3查看 879关注 0票数 3

我需要创建一个k8s资源,它需要一段时间才能可用,为此,我使用以下方法

https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil#example-CreateOrUpdate

代码语言:javascript
运行
复制
op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, func() error {

})

func2()

现在,我需要在对象创建完成后立即调用func2 (可能需要2-3分钟才能完成),我应该怎么做呢?

我发现这个但不知道怎么把它们结合起来..。

https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg#hdr-Watching_and_EventHandling

我正在使用kubebuilder

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-02-23 11:07:26

以上方法更适用于cli的使用。

当您使用kubebuilder或操作符sdk时,您需要在协调函数中处理它。

通常,您有一个自定义资源来触发控制器协调功能。当创建自定义资源时,您将创建部署,而不是返回一个空的reconcile.Result (它将其标记为已完成),您可以返回带有Requeue属性的reconcile.Result。

代码语言:javascript
运行
复制
reconcile.Result{Requeue: true}

因此,在下一次运行期间,您将检查部署是否准备就绪。如果不是,那你就再来一次。一旦准备就绪,您将返回一个空的reconcile.Result结构。

另外,请记住,调节函数始终需要是幂等函数,因为它将在控制器重新启动期间为每个自定义资源再次运行,默认情况下每10个小时运行一次。

或者,您也可以在创建的部署上使用所有者引用,然后设置控制器,以便在拥有的资源(部署)上发生更新时协调所有者资源(您的自定义资源)。使用operator sdk,可以在SetupWithManager函数中进行配置,默认情况下,该函数只使用For选项函数。在这里,您需要添加自己的选项函数。

代码语言:javascript
运行
复制
// SetupWithManager sets up the controller with the Manager.
func (r *YourReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&yourapigroup.YourCustomResource{}).
        Owns(&appv1.Deployment{}).
        Complete(r)
}

我从未使用过这种方法,因此可能需要添加更多代码才能工作。

如果不需要任何终结器代码,使用所有者引用也会派上用场,因为当自定义资源被删除时,kubernetes将自动删除您拥有的资源(部署)。

票数 6
EN

Stack Overflow用户

发布于 2021-02-23 07:46:19

下面是一个示例,如何创建一个部署,并检查它是否至少有一个就绪副本。也许检查状态中的条件并查找可用类型的条件和"True“的状态会更好。

代码语言:javascript
运行
复制
package main

import (
    "context"
    "fmt"
    v1 "k8s.io/api/apps/v1"
    podv1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/fields"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/cache"
    "sigs.k8s.io/controller-runtime/pkg/client"
    "sigs.k8s.io/controller-runtime/pkg/client/config"
    "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
    "time"
)

const (
    namespace      = "default"
    deploymentName = "nginx"
)

func main() {
    cfg, err := config.GetConfig()
    if err != nil {
        panic(err)
    }

    clientset, err := kubernetes.NewForConfig(cfg)
    if err != nil {
        panic(err)
    }

    client, err := client.New(cfg, client.Options{})
    if err != nil {
        panic(err)
    }

    d := &v1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name:      deploymentName,
            Namespace: namespace,
        },
        Spec: v1.DeploymentSpec{
            Replicas: toInt32Ptr(2),
            Selector: &metav1.LabelSelector{
                MatchLabels: map[string]string{
                    "app": "nginx",
                },
            },
            Template: podv1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Labels: map[string]string{
                        "app": "nginx",
                    },
                },
                Spec: podv1.PodSpec{
                    Containers: []podv1.Container{
                        {
                            Name:  "nginx",
                            Image: "nginx",
                        },
                    },
                },
            },
        },
    }

    fmt.Println("Deploying")
    _, err = controllerutil.CreateOrUpdate(context.TODO(), client, d, func() error {
        return nil
    })

    if err != nil {
        panic(err)
    }

    stop := make(chan struct{})

    watchList := cache.NewListWatchFromClient(clientset.AppsV1().RESTClient(), "deployments", namespace, fields.Everything())
    _, ctrl := cache.NewInformer(watchList, &v1.Deployment{}, time.Second, cache.ResourceEventHandlerFuncs{
        UpdateFunc: func(o, n interface{}) {
            newDeployment := n.(*v1.Deployment)
            if newDeployment.Name != deploymentName {
                return
            }

            if newDeployment.Status.ReadyReplicas > 0 {
                close(stop)
                return
            }

            return
        },
    })

    ctrl.Run(stop)
    fmt.Println("Deployment has at least 1 ready replica")
}

func toInt32Ptr(i int32) *int32 {
    return &i
}
票数 3
EN

Stack Overflow用户

发布于 2021-12-03 10:53:05

这个例子,来自operator文档,可能会有所帮助:https://sdk.operatorframework.io/docs/building-operators/golang/references/client/#example-usage。它基于Create()Update()函数,这可能会带来一个更简单的算法。

这一条,来自kubebuilder文档,也提供了一个有趣的轨道,尽管它被废弃了:https://book-v1.book.kubebuilder.io/basics/simple_controller.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66321672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档