好久没有写博客了。 借着春节有点时间,补充一些内容。
近期关于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
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
}
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 才让程序通过编译的。