目录

说明

可以调取k8s api 接口的工具有很多,这里我就介绍下client-go

gitlab上client-go项目地址: https://github.com/kubernetes/client-go  

这个工具是由kubernetes官方指定维护的,大家可以放心使用

效果

运行完成后,可以直接获取k8s集群信息等

实现

1、拉取工具源码

注意事项:https://github.com/kubernetes/client-go/blob/master/install.md

总结:一定要拉取跟集群对应版本的工具源码,比如我这里集群是1.17版本,那我就拉取17版本

go get

我是1.17版本的集群,所有依赖文件放在这了,可以直接使用client-go k8s1.17 api

2、创建目录结构

集群的角色配置文件(默认在/root/.kube/config)
kube/config

查询代码实例

查询pod信息

查看ferry命名空间下pod的信息,pod名字、pod的ip

vim kube-api.go

package main

import (
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"k8s.io/client-go/kubernetes"

	"k8s.io/client-go/tools/clientcmd"
)

func main() {

	config, err := clientcmd.buildconfigfromflags("", "kube/config")
	if err != nil {
		panic(err)
	}
	client, _ := kubernetes.newforconfig(config)
	pods ,err := client.corev1().pods("ferry").list(metav1.listoptions{})
	if err != nil {
		fmt.println(err)
		return
	}

	for _,v := range  pods.items {
		fmt.printf(" 命名空间是:%v\n pod名字:%v\n ip:%v\n\n",v.namespace,v.name,v.status.podip)
	}
}

自动关联依赖

go mod tidy

运行结果

$ go run kube-api.go

 命名空间是:ferry
 pod名字:ferry-backend-7949596679-h8lxb
 ip:10.42.1.14

 命名空间是:ferry
 pod名字:ferry-mysql-8db8d49f7-6psbv
 ip:10.42.1.11

查询一个pod是否在一个命名空间下

https://github.com/kubernetes/client-go/blob/master/examples/in-cluster-client-configuration/main.go
每3秒检查下nginx-74959fc858-cp48w是否在default命名空间下

package main

import (
	"context"
	"fmt"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"time"
)

func main() {

	config, err := clientcmd.buildconfigfromflags("", "kube/config")
	if err != nil {
		panic(err)
	}
	clientset, err := kubernetes.newforconfig(config)
	if err != nil {
		panic(err.error())
	}
	for {
		// get pods in all the namespaces by omitting namespace
		// or specify namespace to get pods in particular namespace
		pods, err := clientset.corev1().pods("").list(context.todo(), metav1.listoptions{})
		if err != nil {
			panic(err.error())
		}
		fmt.printf("there are %d pods in the cluster\n", len(pods.items))

		// examples for error handling:
		// - use helper functions e.g. errors.isnotfound()
		// - and/or cast to statuserror and use its properties like e.g. errstatus.message
		_, err = clientset.corev1().pods("default").get(context.todo(), "nginx-74959fc858-cp48w", metav1.getoptions{})
		if errors.isnotfound(err) {
			fmt.printf("pod nginx-74959fc858-cp48w not found in default namespace\n")
		} else if statuserror, isstatus := err.(*errors.statuserror); isstatus {
			fmt.printf("error getting pod %v\n", statuserror.errstatus.message)
		} else if err != nil {
			panic(err.error())
		} else {
			fmt.printf("found nginx-74959fc858-cp48w pod in default namespace\n")
		}

	 time.sleep(3 * time.second)
	}
}

运行结果

$ go run kube-api.go
there are 22 pods in the cluster
found nginx-74959fc858-cp48w pod in default namespace
there are 22 pods in the cluster
found nginx-74959fc858-cp48w pod in default namespace
there are 22 pods in the cluster
found nginx-74959fc858-cp48w pod in default namespace
there are 23 pods in the cluster
found nginx-74959fc858-cp48w pod in default namespace
there are 22 pods in the cluster
found nginx-74959fc858-cp48w pod in default namespace
there are 22 pods in the cluster
found nginx-74959fc858-cp48w pod in default namespace
there are 21 pods in the cluster
\\在集群种手动删除了这个pod
pod nginx-74959fc858-cp48w not found in default namespace
there are 21 pods in the cluster
pod nginx-74959fc858-cp48w not found in default namespace

查询deployment服务类型信息

查询default命名空间下的deployment服务信息,服务名字、服务副本数

package main

import (
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"k8s.io/client-go/kubernetes"

	"k8s.io/client-go/tools/clientcmd"
)

func main() {

	config, err := clientcmd.buildconfigfromflags("", "kube/config")
	if err != nil {
		panic(err)
	}
	client, _ := kubernetes.newforconfig(config)
	deploymentlist, err := client.appsv1().deployments("default").list(metav1.listoptions{})
	if err != nil {
		fmt.println(err)
		return
	}

	for _,v := range deploymentlist.items {
		fmt.printf(" 命名空间是:%v\n deployment服务名字:%v\n 副本个数:%v\n\n",v.namespace,v.name,v.status.replicas)
	}

}

运行结果

$ go run kube-api.go
 命名空间是:default
 deployment服务名字:nginx
 副本个数:2

创建deployment资源

https://github.com/kubernetes/client-go/blob/master/examples/create-update-delete-deployment/main.go

复制一个config文件到当前目录下

创建一个deployment类型的nginx服务

vim deployment-create.go

package main

import (
	"context"
	"flag"
	"fmt"

	"path/filepath"

	appsv1 "k8s.io/api/apps/v1"
	apiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	//
	// uncomment to load all auth plugins
	// _ "k8s.io/client-go/plugin/pkg/client/auth"
	//
	// or uncomment to load specific auth plugins
	// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
	// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
	// _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
	// _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
)

func main() {
	var kubeconfig *string
	if home := homedir.homedir(); home != "" {
		kubeconfig = flag.string("kubeconfig", filepath.join("config"), "(optional) absolute path to the kubeconfig file")
	} else {
		kubeconfig = flag.string("kubeconfig", "", "absolute path to the kubeconfig file")
	}
	flag.parse()

	config, err := clientcmd.buildconfigfromflags("", *kubeconfig)
	if err != nil {
		panic(err)
	}
	clientset, err := kubernetes.newforconfig(config)
	if err != nil {
		panic(err)
	}

	deploymentsclient := clientset.appsv1().deployments(apiv1.namespacedefault)

	deployment := &appsv1.deployment{
		objectmeta: metav1.objectmeta{
			name: "nginx-deployment",
		},
		spec: appsv1.deploymentspec{
			replicas: int32ptr(2),
			selector: &metav1.labelselector{
				matchlabels: map[string]string{
					"app": "nginx",
				},
			},
			template: apiv1.podtemplatespec{
				objectmeta: metav1.objectmeta{
					labels: map[string]string{
						"app": "nginx",
					},
				},
				spec: apiv1.podspec{
					containers: []apiv1.container{
						{
							name:  "web",
							image: "nginx:1.12",
							ports: []apiv1.containerport{
								{
									name:          "http",
									protocol:      apiv1.protocoltcp,
									containerport: 80,
								},
							},
						},
					},
				},
			},
		},
	}

	// create deployment
	fmt.println("creating deployment nginx...")
	result, err := deploymentsclient.create(context.todo(), deployment, metav1.createoptions{})
	if err != nil {
		panic(err)
	}
	fmt.printf("created deployment %q.\n", result.getobjectmeta().getname())

}

运行结果

$ go run deployment-create.go
creating deployment nginx…
created deployment “nginx-deployment”.

更新deployment类型服务

https://github.com/kubernetes/client-go/blob/master/examples/create-update-delete-deployment/main.go
更改服务的副本数,由上一步创建的2修改成1,并修改镜像由nginx1.12–>nginx1.13

package main

import (
	"context"
	"flag"
	"fmt"
	"path/filepath"

	apiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	"k8s.io/client-go/util/retry"
	//
	// uncomment to load all auth plugins
	// _ "k8s.io/client-go/plugin/pkg/client/auth"
	//
	// or uncomment to load specific auth plugins
	// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
	// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
	// _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
	// _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
)

func main() {
	var kubeconfig *string
	if home := homedir.homedir(); home != "" {
		kubeconfig = flag.string("kubeconfig", filepath.join("config"), "(optional) absolute path to the kubeconfig file")
	} else {
		kubeconfig = flag.string("kubeconfig", "", "absolute path to the kubeconfig file")
	}
	flag.parse()

	config, err := clientcmd.buildconfigfromflags("", *kubeconfig)
	if err != nil {
		panic(err)
	}
	clientset, err := kubernetes.newforconfig(config)
	if err != nil {
		panic(err)
	}

	deploymentsclient := clientset.appsv1().deployments(apiv1.namespacedefault)

	retryerr := retry.retryonconflict(retry.defaultretry, func() error {
		// retrieve the latest version of deployment before attempting update
		// retryonconflict uses exponential backoff to avoid exhausting the apiserver
		result, geterr := deploymentsclient.get(context.todo(), "nginx-deployment", metav1.getoptions{})
		if geterr != nil {
			panic(fmt.errorf("failed to get latest version of deployment: %v", geterr))
		}

		result.spec.replicas = int32ptr(1)                           // reduce replica count
		result.spec.template.spec.containers[0].image = "nginx:1.13" // change nginx version
		_, updateerr := deploymentsclient.update(context.todo(), result, metav1.updateoptions{})
		return updateerr
	})
	if retryerr != nil {
		panic(fmt.errorf("update failed: %v", retryerr))
	}
	fmt.println("updated deployment nginx")

}
func int32ptr(i int32) *int32 { return &i }

运行结果

$ go run deployment-update.go
updated deployment nginx

删除deployment类型服务

删除上面创建的nginx-deployment资源,删除之前添加了确认语句

package main

import (
	"bufio"
	"context"
	"flag"
	"fmt"
	"os"
	"path/filepath"

	apiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	//
	// uncomment to load all auth plugins
	// _ "k8s.io/client-go/plugin/pkg/client/auth"
	//
	// or uncomment to load specific auth plugins
	// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
	// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
	// _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
	// _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
)

func main() {
	var kubeconfig *string
	if home := homedir.homedir(); home != "" {
		kubeconfig = flag.string("kubeconfig", filepath.join( "config"), "(optional) absolute path to the kubeconfig file")
	} else {
		kubeconfig = flag.string("kubeconfig", "", "absolute path to the kubeconfig file")
	}
	flag.parse()

	config, err := clientcmd.buildconfigfromflags("", *kubeconfig)
	if err != nil {
		panic(err)
	}
	clientset, err := kubernetes.newforconfig(config)
	if err != nil {
		panic(err)
	}

	deploymentsclient := clientset.appsv1().deployments(apiv1.namespacedefault)

     prompt()
	fmt.println("deleting deployment nginx...")
	deletepolicy := metav1.deletepropagationforeground
	if err := deploymentsclient.delete(context.todo(), "nginx-deployment", metav1.deleteoptions{
		propagationpolicy: &deletepolicy,
	}); err != nil {
		panic(err)
	}
	fmt.println("deleted deployment.")
}

func prompt() {
	fmt.printf("-> press return key to continue, will delete!")
	scanner := bufio.newscanner(os.stdin)
	for scanner.scan() {
		break
	}
	if err := scanner.err(); err != nil {
		panic(err)
	}
	fmt.println()
}

func int32ptr(i int32) *int32 { return &i }

运行结果

$ go run deployment-delete.go
-> press return key to continue, will delete! 这里点击回车后继续删除资源

deleting deployment nginx…
deleted deployment.

到此这篇关于使用client-go工具调kubernetes api接口(v1.17版本)的文章就介绍到这了,更多相关client-go调用kubernetes api内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!