使用 go-client 在 Istio-resource 上设置 ObjectMeta

Set ObjectMeta on Istio-resource with go-client

我正在尝试使用 Go 中的 Istio,并且正在使用 Kubernetes 和 Istio go-client 代码。

我遇到的问题是我无法在 Istio-ServiceRole 对象中指定 ObjectMetaTypeMeta。我只能指定 rules,它们在 spec.

下面你可以看到我的工作:

import (
    v1alpha1 "istio.io/api/rbac/v1alpha1"
)


func getDefaultServiceRole(app nais.Application) *v1alpha1.ServiceRole {
    return &v1alpha1.ServiceRole{
        Rules: []*v1alpha1.AccessRule{
            {
                Ports: []int32{2},
            },
        },
    }
}

我想做的是让这段代码起作用:

func getDefaultServiceRole(app *nais.Application) *v1alpha1.ServiceRole {
    return &v1alpha1.ServiceRole{
        TypeMeta: metav1.TypeMeta{
            Kind:       "ServiceRole",
            APIVersion: "v1alpha1",
        },
        ObjectMeta: metav1.ObjectMeta{
            Name:      app.Name,
            Namespace: app.Namespace,
        },
        Spec: v1alpha1.ServiceRole{
            Rules: []*v1alpha1.AccessRule{
                {
                    Ports: []int32{2},
                },
            },
        },
    },
}

谁能指出我正确的方向?

啊 - 这是一个非常痛苦的点:Istio 需要 Kubernetes CRD 包装器元数据(主要是 namenamespace 字段),但这些字段不是 API 的一部分objects 他们自己也没有出现在原型中。 (这随着用于配置组件的新 MCP API 而改变 - Galley 使用 - does encode these fields as protobufs but that doesn't help for your use case.) Instead, you should use the types in istio.io/istio/pilot/pkg/config/kube/crd,它实现了 K8s CRD 接口。

在 golang 中使用 Istio objects 最简单的方法是使用 Pilot 的库,特别是 istio.io/istio/pilot/pkg/model and istio.io/istio/pilot/pkg/config/kube/crd packages, as well as the model.Config struct. You can either pass around the full model.Config (not great because spec has type proto.Message so you need type assertions to extract the data you care about), or pass around the inner object wrap it in a model.Config before you push it. You can use the model.ProtoSchema type to help with conversion to and from YAML and JSON. Pilot only defines ProtoSchema objects for the networking API,类型是 public,您可以为任意类型创建它们.

所以,使用您的示例代码,我可能会尝试类似的方法:

import (
    v1alpha1 "istio.io/api/rbac/v1alpha1"
   "istio.io/istio/pilot/pkg/model"
)


func getDefaultServiceRole() *v1alpha1.ServiceRole {
    return &v1alpha1.ServiceRole{
        Rules: []*v1alpha1.AccessRule{
            {
                Ports: []int32{2},
            },
        },
    }
}

func toConfig(app *nais.Application, role *v1alpha1.ServiceRole) model.Config {
    return &model.Config{
        ConfigMeta: model.ConfigMeta{
            Name:      app.Name,
            Namespace: app.Namespace,
        },
        Spec: app,
    }
}

type Client model.ConfigStore
func (c Client) CreateRoleFor(app nais.Application, role *v1alpha1.ServiceRole) error {
    cfg := toConfig(app, role)
    _, err := c.Create(cfg)
    return err
}

作为一个更完整的示例,我们以这种方式构建了 Istio CloudMap 运算符。 Here's the core of it that pushes config to K8s with Pilot libraries. Here's the incantation to create an instance of model.ConfigStore to use to create objects。最后,我想明确指出,因为它仅隐含在示例中:当您在 model.ConfigStore 上调用 Create 时,ConfigStore 依赖于 ProtoSchema objects 用于创建它。因此,请务必为您将使用的所有类型使用 ProtoSchema objects 初始化商店。


您可以仅使用 K8s 客户端库和 istio.io/istio/pilot/pkg/config/kube/crd 包实现相同的效果,但我没有亲身体验过,也没有方便的示例。

Istio 现在支持:

import (
    istiov1alpha3 "istio.io/api/networking/v1alpha3"
    istiogov1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
)

VirtualService := istiogov1alpha3.VirtualService{
        TypeMeta:   metav1.TypeMeta{
            Kind: "VirtualService",
            APIVersion: "networking.istio.io/v1alpha3",
        },
        ObjectMeta: metav1.ObjectMeta{
            Name: "my-name",
        },
        Spec:       istiov1alpha3.VirtualService{},
}

其中 istiov1alpha3.VirtualService{} 是一个 istio 对象。