1. 简单办法:使用apiserver-boot添加子资源

注意:

在版本 v0.1-alpha.11 中添加

1.1使用 apiserver-boot 创建子资源定义

要为资源Group/Version/Kind创建子资源,请从根目录运行以下命令(例如包含glide.yaml的命令)

apiserver-boot create subresource --subresource <subresource> --group <resource-group> --version <resource-version> --kind <resource-kind>

上面操作将会经历步骤:

  • 创建pkg/apis/<group>/<version>/<subresource>_<kind>_types.go,包含子资源类型的定义
  • 创建pkg/apis/<group>/<subresource>_<kind>_rest.go,包含rest接口实现
  • 创建pkg/apis/<group>/<version>/<subresource>_<kind>_types_test.go,包含一个简单的测试来调用子资源并确保它返回 200
  • 更新pkg/apis/<group>/<version>/<kind>_types.go,将子资源注释指令添加到资源

1.2 重新生成的代码以连接子资源

apiserver-boot build generated

1.3 运行测试

go test ./pkg/...

1.4 通过发现服务查找子资源端点:

# shell #1
apiserver-boot run local

# shell #2
kubectl --kubeconfig kubeconfig proxy

# shell #3
curl 127.0.0.1:8001/
curl 127.0.0.1:8001/apis/<group>.<domain>/<version>

2. 手动创建子资源

手动创建子资源定义

2.1 更新子资源定义

pkg/apis/<group>/<version>/<resource>_types.go创建子资源

// +k8s:openapi-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// +resource:path=bars
// +subresource:request=Status,path=status,rest=BarStatusREST
type Bar struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   BarSpec   `json:"spec,omitempty"`
	Status BarStatus `json:"status,omitempty"`

下面的代码告诉代码生成器怎样为此资源生成一个子资源

  • bar/status
  • 使用Status请求类型
  • 通过go类型BarStatusRest实现

Status和BarStatusREST位于版本化包中(与版本化资源定义相同)

// +subresource:request=Status,path=status,rest=BarStatusREST

2.2 创建子资源请求

在同一个 _types.go 文件中定义请求类型

// +genclient=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// +subresource-request
type Status struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Faculty int `json:"faculty,omitempty"`
}

注意:

// +subresource-request

这告诉代码生成器这是一个子资源类型并在连接中注册它。

2.3 创建REST实现

在未版本化的包中创建其余实现。

实例:

// +k8s:deepcopy-gen=false
type BarStatusREST struct {
	Registry BarRegistry
}

// Status Subresource
var _ rest.CreaterUpdater = &BarStatusREST{}
var _ rest.Patcher = &BarStatusREST{}

func (r *BarStatusREST) Create(ctx request.Context, obj runtime.Object) (runtime.Object, error) {
	status := obj.(*Status)
	b, err := r.Registry.GetBar(ctx, status.Name, &metav1.GetOptions{})
	if err != nil {
		return nil, err
	}
    // Do something with b...

    // Save the udpated b
	return r.Registry.UpdateBar(ctx, b)
}

// Get retrieves the object from the storage. It is required to support Patch.
func (r *BarStatusREST) Get(ctx request.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
	return nil, nil
}

// Update alters the status subset of an object.
func (r *BarStatusREST) Update(ctx request.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
	return nil, false, nil
}

func (r *BarStatusREST) New() runtime.Object {
	return &Status{}
}

Note:

当集成scale子资源进k8s HP系统时,你必须自定义REST 接口实现

// work around for scaling client
func (r *BarScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind {
	return autoscalingv1.SchemeGroupVersion.WithKind("Scale")
}

3. REST 实现剖析

定义实现REST api struct 类型,Registry字段是必需的,它提供了一个类型安全的库来从存储中读/写 Bar 的实例。

// +k8s:deepcopy-gen=false
type BarStatusREST struct {
	Registry BarRegistry
}

强制执行本地编译时检查结构是否实现了所需的 REST 方法

// Status Subresource
var _ rest.CreaterUpdater = &BarStatusREST{}
var _ rest.Patcher = &BarStatusREST{}

使用注册表实现创建和更新方法以更新父资源。

func (r *BarStatusREST) Create(ctx request.Context, obj runtime.Object) (runtime.Object, error) {
    ...
}

// Update alters the status subset of an object.
func (r *BarStatusREST) Update(ctx request.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
	...
}

使用注册表实现读取方法以读取父资源。

// Get retrieves the object from the storage. It is required to support Patch.
func (r *BarStatusREST) Get(ctx request.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
	...
}

实现一个创建请求的新实例的方法。

func (r *BarStatusREST) New() runtime.Object {
	return &Status{}
}

注意 :如果您正在尝试扩展长时间运行的流式子资源,请参阅miskatonic.students/pencil或中的示例miskatonic.students/book

4. 从测试中调用您的子资源

使用 RESTClient 调用您的子资源。不会为子资源生成客户端go,因此您需要手动调用子资源。

client.RESTClient()
	err := restClient.Post().Namespace("default").
		Name("name").
		Resource("bars").
		SubResource("status").
		Body(status).Do().Error()
	...
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐