kubectl其实通过集成对应语言的Istio Client,我们可以通过对应语言的代码中直接操作Istio定制资源。
本文介绍如何使用Go语言的SDK client-go在ASM中创建istio资源。
前提条件首先当然需要准备好kubernetes集群并安装好Istio。文本中代码基于go1.18与istio.io/client-go v1.14.0版本编写。
安装依赖- 在项目路径下启动命令行终端
- 如果项目中尚未创建go.mod文件,运行
go mod init [模块名]
- 安装依赖包
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配置连接
kubeconfigkubeconfig生成配置文件virtualService.yamlgateway.yamlapiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"创建虚拟服务virtualService.yamlpackage 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)
}
}gateway.yamlpackage 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)
}
}