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

使用 Golang 操作 Istio 和其他自定义 Kubernetes 资源

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2018年10月9日

CPOL

3分钟阅读

viewsIcon

4859

在本文中,我将演示如何使用 Golang 操作 Kubernetes 自定义资源,以 Istio 为例。 不需要了解 Istio,我只是用它来演示这些概念!

Manipulating Istio and other Custom Kubernetes Resources in Golang

在本文中,我将演示如何使用 Golang 操作 Kubernetes 自定义资源,以 Istio 为例。 不需要了解 Istio,我只是用它来演示这些概念!

Manipulating Istio and other Custom Kubernetes Resources in Golang

Istio 是一个非常流行的服务网格平台,它允许工程师快速地为基于服务的应用程序添加遥测、高级流量管理等。

Istio 工作方式的一个有趣之处在于,当部署到 Kubernetes 集群中时,许多关键配置对象被处理为 自定义资源。 自定义资源是一个非常强大的 Kubernetes 特性,它允许您创建自己的“一级”资源(就像 Pod、ReplicaSet、Deployment 或其他任何资源),然后使用 kubectl 或 Kubernetes API 与它们交互。

在本文中,我将向您展示如何使用 Golang Kubernetes 客户端与这些自定义资源交互。

CRD:快速概述

当您为您的集群设置 Istio 时,您可能会做的一件事是指定您将如何路由流量。 这可能非常复杂,如下所示

Manipulating Istio and other Custom Kubernetes Resources in Golang

图 1:Istio 流量管理示例,来自 istio.io

像这样的系统可以配置的一种方法是使用一个包含服务路由定义信息的 ConfigMap

然而,Istio 实际上注册了新的资源类型(自定义资源定义),这些资源代表网关或服务等。 我们可以像操作任何其他 Kubernetes 对象一样创建/更新/删除/操作它们。

例如,我可以为上面的示例创建一个虚拟服务,类似于这样

cat << EOF | kubectl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: service2
spec:
  hosts:
  - "*"
  gateways:
  - demo1-gateway
  http:
  - route:
    - destination:
        host: service2
        subset: v1
      weight: 95
    - destination:
        host: service2
        subset: v2
      weight: 5
EOF

同样,重要的是,我可以使用我的 Istio 资源就像使用任何其他 Kubernetes 对象一样

$ kubectl get virtualservices.networking.istio.io
NAME       AGE
service2   93s

或者

$ kubectl delete virtualservices.networking.istio.io/service2

我可以使用 editdescribe,注册生命周期事件,监视更改等等。

在 Golang 中使用 CRD

Golang Kubernetes 客户端允许您创建强定义的类型,然后可以使用这些类型与 CRD 交互。 一个例子可以在 Red Hat 博客文章 Kubernetes 深度探讨:自定义资源的 代码生成中找到。

这是一种极好的方法,但如果您想快速访问一些数据,并且不想生成大量代码,可能会感觉很重。

还有另一种选择,即使用 DynamicClient首选的方法似乎是第一种,涉及代码生成,因此关于第二种方法的文档很少。 然而,它实际上非常简单。

以下是如何列出所有 Istio VirtualService 资源的示例,无需生成任何代码

//  Create a Dynamic Client to interface with CRDs.
dynamicClient, _ := dynamic.NewForConfig(config)

//  Create a GVR which represents an Istio Virtual Service.
virtualServiceGVR := schema.GroupVersionResource{
	Group:    "networking.istio.io",
	Version:  "v1alpha3",
	Resource: "virtualservices",
}

//  List all of the Virtual Services.
virtualServices, _ := dynamicClient.Resource(virtualServiceGVR).Namespace("default").
                      List(metav1.ListOptions{})
for _, virtualService := range virtualServices.Items {
	fmt.Printf("VirtualService: %s\n", virtualService.GetName())
}

此代码片段省略了设置和错误处理,以求清晰,完整的示例在 k8s-list-virtualservices.go gist 中。

在 Golang 中修补 CRD

您可能已经注意到,.Resource().Namespace().List() 代码看起来与使用 Kubernetes Clientset 时进行 API 调用的结构非常相似。 事实上,它基本上是相同的。 查看 该接口,您可以看到您拥有所有期望的操作

  • Create
  • 更新
  • 删除
  • Get

等等。 这很好,因为您可以在我的文章“在 Golang 中修补 Kubernetes 资源”中使用相同的技巧来操作这些实体,而无需创建表示它的结构。

这里是另一个简短的示例,这次展示了我们如何将服务路由的权重调整为 50%/50%

//  Create a GVR which represents an Istio Virtual Service.
virtualServiceGVR := schema.GroupVersionResource{
	Group:    "networking.istio.io",
	Version:  "v1alpha3",
	Resource: "virtualservices",
}

//  Weight the two routes - 50/50.
patchPayload := make([]PatchUInt32Value, 2)
patchPayload[0].Op = "replace"
patchPayload[0].Path = "/spec/http/0/route/0/weight"
patchPayload[0].Value = 50
patchPayload[1].Op = "replace"
patchPayload[1].Path = "/spec/http/0/route/1/weight"
patchPayload[1].Value = 50
patchBytes, _ := json.Marshal(patchPayload)

//  Apply the patch to the 'service2' service.
_, err := dynamicClient.Resource(virtualServiceGVR).Namespace("default").Patch
         ("service2", types.JSONPatchType, patchBytes)

请参阅 gist k8s-patch-virtualservice.go 中的完整示例。

运行示例后,您可以使用 Kubernetes CLI 来验证更改

$ kubectl get virtualservices.networking.istio.io/service2 -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  clusterName: ""
  creationTimestamp: 2018-10-08T09:53:16Z
  generation: 0
  name: service2
  namespace: default
  resourceVersion: "487435"
  selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/virtualservices/service2
  uid: fac5930c-cadf-11e8-90a2-42010a94005b
spec:
  gateways:
  - demo1-gateway
  hosts:
  - '*'
  http:
  - route:
    - destination:
        host: service2
        subset: v1
      weight: 50
    - destination:
        host: service2
        subset: v2
      weight: 50

保持简单!

就是这样! 这个技巧让我在做的事情变得容易很多,但要做好它需要一些实验。 我希望您觉得这种方法有用。 请在评论中分享任何想法/问题。

延伸阅读

以下文章用于研究这种方法

© . All rights reserved.