好久没有写博客了。 借着春节有点时间,补充一些内容。
近期关于k8s的都是非常基础的内容,基本上都是k8s client api的基础使用,仅供参考。没有架构和设计精髓的讨论。

环境

我Windows上安装了2台linux虚拟机,然在linux上安装 1.15.0版本的k8s, 开发环境在Windows7上。

工程结构

非常简单的一个go工程,没有输入参数, 默认从当前用户的.kube目录读取config文件访问k8s,具体代码可以参看https://github.com/yqbjtu/mygotutorials/tree/master/k8spodget

在这里插入图片描述

获取clientset

k8sclient.go

package common

import (
	"flag"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"os"
	"path/filepath"
)

func homeDir() string {
	if h := os.Getenv("HOME"); h != "" {
		return h
	}
	return os.Getenv("USERPROFILE") // windows
}
func GetClient() (clientset *kubernetes.Clientset, err error) {
	var kubeconfig *string
	if home := homeDir(); home != "" {
		kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
	}
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		panic(err.Error())
	}

	// create the clientset
	clientset, err = kubernetes.NewForConfig(config)
	return
}

watch pod, 查询node , deployment

getResource.go

package resource

import (
	"context"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/klog"
	"time"

	"k8s.io/client-go/kubernetes"
)

type MyResource struct {
	Clientset *kubernetes.Clientset
}

func (s *MyResource) GetNode() {
	opts := v1.ListOptions{
		Limit: 100,
	}

	nodes, err := s.Clientset.CoreV1().Nodes().List(context.TODO(), opts)
	if err != nil {
		klog.Error("failed to get node list ,err:%v", err)
		return
	}

	for _, node := range nodes.Items {
		klog.Infof("name:%s, Status:%v", node.Name, node.Status.NodeInfo.OSImage)
	}
}

func (s *MyResource) GetPod() {
	opts := v1.ListOptions{
		Limit: 100,
	}

	podwatch, err := s.Clientset.CoreV1().Pods("default").Watch(context.TODO(), opts)
	if err != nil {
		klog.Error("failed to watch pod list, err:%v", err)
		return
	}

	for {
		select {
		case e, ok := <-podwatch.ResultChan():
			if !ok {
				// 说明该通道已经被close掉了
				klog.Warning("podWatch chan has been close!")
				time.Sleep(time.Second * 5)
			}
			if e.Object != nil {
				klog.Infof("chan is ok. type:%v", e.Type)
				klog.Info(e.Object.DeepCopyObject())
			}
		}
	}
}

func (s *MyResource) GetDeployment(ns string) {
	deploy, err := s.Clientset.AppsV1().Deployments(ns).List(context.TODO(), v1.ListOptions{})
	if err != nil {
		klog.Error("failed to get deploy list ,err:%v", err)
		return
	}

	for _, deploy := range deploy.Items {
		klog.Infof("deployName:%s,  replicas:%d, status.UnavailableReplicas:%d,", deploy.Name, *deploy.Spec.Replicas, deploy.Status.UnavailableReplicas)
	}
}

主程序

package main

import (
	"flag"
	"k8s.io/klog"
	"k8spodget/pkg/common"
	"k8spodget/pkg/resource"
)

func main() {
	klog.InitFlags(nil)
	flag.Set("log_file", "C:\\F\\myfilek8spod.log")
	flag.Parse()
	klog.Info("start to get k8s client")
	clientSet, err := common.GetClient()
	if err != nil {
		klog.Warningf("failed to get k8s clientSet, err:%v", err)
	}
	myResource := resource.MyResource{Clientset: clientSet}
	myResource.GetNode()
	myResource.GetDeployment("default")
	//会一直运行
	myResource.GetPod()
	klog.Flush()
}

运行效果

在运行本程序前,请确保执行kubectl get nodes可以正常运行。如果kubectl get nodes可以运行, 基本上就保证程序能在本地访问到kube config文件。

在这里插入图片描述

备注

一开始我们没有限定引入module的版本,然后运行程序报错:

C:\F\GoLandProjects\mygotutorials\k8spodget>go run main.go
build command-line-arguments: cannot load k8s.io/api/auditregistration/v1alpha1: module k8s.io/api@latest found (v0.20.2), but does not contain package k8s.io/api/
auditregistration/v1alpha1

最后根据https://github.com/kubernetes/client-go/issues/874 建议方法,在go.mod中强制加上了replace k8s.io/client-go => k8s.io/client-go v0.19.2 才让程序通过编译的。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐