65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Golang 修补 Kubernetes 资源

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2018 年 7 月 24 日

CPOL

2分钟阅读

viewsIcon

8066

补丁资源比获取资源并整体更新 spec 更快速、更简单。然而,文档略显不足。经过一些试验和错误,我成功了,这里是解决方案。我想分享给其他人,希望能有所帮助!

最近,我需要能够快速调整 Kubernetes 副本控制器中的副本数量。我之前看到的一个解决方案是获取 spec,修改它,然后更新它。有一个更好的方法!

存在一个 Kubernetes 资源的补丁 API。 补丁资源比获取资源并整体更新 spec 更快速、更简单。然而,文档略显不足。

经过一些试验和错误,我成功了,这里是解决方案。我想分享给其他人,希望能有所帮助!

解决方案

我将从解决方案开始。如果这就是你所需要的,那么你可以直接使用。该方案的工作原理的细节将在之后介绍。在这个例子中,我将更新 my-rc 控制器中的副本数量

package main

import (
	"encoding/json"
	"fmt"

	types "k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/kubernetes"
	_ "k8s.io/client-go/plugin/pkg/client/auth"
	"k8s.io/client-go/tools/clientcmd"
)

var (
	//  Leave blank for the default context in your kube config.
	context = ""

	//  Name of the replication controller to scale, and the desired number of replicas.
	replicationControllerName = "my-rc"
	replicas                  = uint32(3)
)

//  patchStringValue specifies a patch operation for a string.
type patchStringValue struct {
	Op    string `json:"op"`
	Path  string `json:"path"`
	Value string `json:"value"`
}

//  patchStringValue specifies a patch operation for a uint32.
type patchUInt32Value struct {
	Op    string `json:"op"`
	Path  string `json:"path"`
	Value uint32 `json:"value"`
}

func scaleReplicationController(clientSet *kubernetes.Clientset, 
                 replicasetName string, scale uint32) error {
	payload := []patchUInt32Value{{
		Op:    "replace",
		Path:  "/spec/replicas",
		Value: scale,
	}}
	payloadBytes, _ := json.Marshal(payload)
	_, err := clientSet.
		CoreV1().
		ReplicationControllers("default").
		Patch(replicasetName, types.JSONPatchType, payloadBytes)
	return err
}

func main() {
	//  Get the local kube config.
	fmt.Printf("Connecting to Kubernetes Context %v\n", context)
	config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
		clientcmd.NewDefaultClientConfigLoadingRules(),
		&clientcmd.ConfigOverrides{CurrentContext: context}).ClientConfig()
	if err != nil {
		panic(err.Error())
	}

	// Creates the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err.Error())
	}

	//  Scale our replication controller.
	fmt.Printf("Scaling replication controller %v to %v\n", replicationControllerName, replicas)
	err = scaleReplicationController(clientset, replicationControllerName, replicas)
	if err != nil {
		panic(err.Error())
	}
}

此代码也作为 gist 提供

机制

Kubernetes 补丁 API 支持几种不同的方法来修改资源。重要的是要意识到,在 REST API 中,没有普遍接受的“标准”方法来表示对资源的更改

你可以使用三种策略进行补丁

  1. merge:遵循 JSON Merge Patch Spec (RFC 7386)
  2. strategic:一种战略合并,解决了合并补丁的一些限制(在 此文档中说明)。
  3. json:遵循 JSON Patch Spec (RFC 6902)

这些在以下位置有详细的文档说明

我在这里使用的机制是 json,我认为这对于读者来说是最清晰的。要使用此策略,我们需要构建一个 payload,描述我们要更改的内容。它可能如下所示

{
    "op": "replace",
    "path": "/spec/replicas",
    "value": 4
}

op 字段可以是 removereplaceadd 等(所有细节都在 RFC 6902 中),或者更易读的 jsonpatch.com)。这使得操作对读者来说非常明确,这很有帮助。我们创建一个 struct,它表示对 string 或整数(或我们需要的任何数据类型)的操作,对其进行序列化并传递给 API。

在底层,Golang 客户端会将此简单地转换为类似于以下内容的 HTTP 调用

PATCH /api/v1/namespaces/default/replicationcontrollers/app-server-blue HTTP/1.1
Host: 127.0.0.1
Content-Type: application/json-patch+json
Content-Length: 70

[{
	"op": "replace",
  	"path": "/spec/replicas",
  	"value": 4
}]

这对应于 Patch Operations 上的文档。请注意,补丁操作类型在 Content-Type 标头中指定。

希望这能帮助你,如果你需要补丁资源,正在与文档作斗争,并且像我一样是 Go 新手! 欢迎提出任何关于如何使代码更简洁或更符合惯例的建议。

感谢以下文章和 issue 帮助我理解了这一点

© . All rights reserved.