使用Go SDK操作Istio资源

通过集成对应语言的SDK Client,您可以在代码中直接操作Istio资源。本文以Go 1.18和SDK istio.io/client-go v1.14.0版本为例,介绍如何使用Go SDK操作Istio资源。

前提条件

准备工作

安装依赖

  1. 在项目路径下启动命令行终端。
  2. 可选:如果项目中未创建go.mod文件,请执行以下命令。
    go mod init [模块名]
  3. 执行以下命令,安装依赖包。
    go get github.com/ghodss/yaml istio.io/client-go/pkg/apis/networking/v1beta1 istio.io/client-go/pkg/clientset/versioned k8s.io/apimachinery/pkg/apis/meta/v1 k8s.io/client-go/tools/clientcmd

配置连接

  1. 登录ASM控制台

  2. 在左侧导航栏,选择服务网格 > 网格管理

  3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理

  4. 在网格详情页面左侧导航栏单击基本信息,然后在右侧页面单击连接配置
  5. 连接配置面板,复制文件内容到$HOME/.kube/config路径下。

生成配置文件

在代码中使用SDK操作Istio资源页面创建的virtualService.yaml和gateway.yaml文件保存到项目文件夹中。

操作步骤

创建虚拟服务

执行以下代码,在default命名空间创建virtualService.yaml指定的虚拟服务。

package main

import (
    "context"
    "fmt"
    "io/ioutil"

    "github.com/ghodss/yaml"
    "istio.io/client-go/pkg/apis/networking/v1beta1"
    versionedclient "istio.io/client-go/pkg/clientset/versioned"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    const NAMESPACE = "default"
    restConfig, err := clientcmd.BuildConfigFromFlags("", "{path to kube config file}") // 将{}内容替换成Kube Config实际路径,默认是$HOME/.kube/config。
    if err != nil {
        fmt.Println("获取连接配置失败")
        return
    }
    clientset, err := versionedclient.NewForConfig(restConfig)
    if err != nil {
        fmt.Println("创建客户端失败")
        return
    }
    // 此处通过YAML反序列化构造VirtualService结构体,也可以直接构造。
    virtualService := &v1beta1.VirtualService{}
    bytes, err := ioutil.ReadFile("virtualService.yaml")
    if err != nil {
        fmt.Println("读取yaml文件失败")
        return
    }
    err = yaml.Unmarshal(bytes, &virtualService)
    if err != nil {
        fmt.Println("反序列化失败")
        return
    }
    _, err = clientset.NetworkingV1beta1().VirtualServices(NAMESPACE).Create(context.TODO(), virtualService, metav1.CreateOptions{})
    if err != nil {
        fmt.Println("创建虚拟服务失败")
    }
    printAllVisualServices(clientset, NAMESPACE)
}

// 打印命名空间下全部的虚拟服务。
func printAllVisualServices(clientset *versionedclient.Clientset, namespace string) {
    vsList, err := clientset.NetworkingV1beta1().VirtualServices(namespace).List(context.TODO(), metav1.ListOptions{})
    if err != nil {
        fmt.Println("获取虚拟服务失败")
    }
    for _, vs := range vsList.Items {
        fmt.Println(vs)
    }
}

创建网关规则

执行以下代码,在default命名空间创建gateway.yaml指定的网关规则。

package main

import (
    "context"
    "fmt"
    "io/ioutil"

    "github.com/ghodss/yaml"
    "istio.io/client-go/pkg/apis/networking/v1beta1"
    versionedclient "istio.io/client-go/pkg/clientset/versioned"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    const NAMESPACE = "default"
    restConfig, err := clientcmd.BuildConfigFromFlags("", "{path to kube config file}") // 将{}内容替换成Kube Config实际路径,默认是$HOME/.kube/config。
    if err != nil {
        fmt.Println("获取连接配置失败")
        return
    }
    clientset, err := versionedclient.NewForConfig(restConfig)
    if err != nil {
        fmt.Println("创建客户端失败")
        return
    }
    // 此处通过YAML反序列化构造Gateway结构体,也可以直接构造。
    gateway := &v1beta1.Gateway{}
    bytes, err := ioutil.ReadFile("gateway.yaml")
    if err != nil {
        fmt.Println("读取yaml文件失败")
        return
    }
    err = yaml.Unmarshal(bytes, &gateway)
    if err != nil {
        fmt.Println("反序列化失败")
        return
    }
    _, err = clientset.NetworkingV1beta1().Gateways(NAMESPACE).Create(context.TODO(), gateway, metav1.CreateOptions{})
    if err != nil {
        fmt.Println("创建网关规则失败")
    }
    printAllGateways(clientset, NAMESPACE)
}

// 打印命名空间下全部的网关规则。
func printAllGateways(clientset *versionedclient.Clientset, namespace string) {
    gwList, err := clientset.NetworkingV1beta1().Gateways(namespace).List(context.TODO(), metav1.ListOptions{})
    if err != nil {
        fmt.Println("获取网关规则失败")
    }
    for _, gw := range gwList.Items {
        fmt.Println(gw)
    }
}
            

后续步骤

虚拟服务和网关规则创建完成后,您可以在浏览器中访问http://{入口网关服务的IP地址}/productpage,查看Bookinfo应用。