zoukankan      html  css  js  c++  java
  • 使用client-go连接k8s集群

    说明:k8s官方维护的客户端库只有go和python版本,所以为了稳定性建议使用这两个版本,考虑到k8s是go实现的,我这里也就选择go版本。至于客户端连接k8s集群,在具体的生产环境中不建议外部连接访问。原因一是生产环境中的k8s配置文件重要,一般如果对接其他公司的业务,虽然有鉴权,人家也不愿意把配置文件拷贝给你,因为有了集群的配置文件,外部的这个项目的权限就很大,相当于给集群开了一个隐患口子,要知道k8s集群中有可能是该公司的整个业务。原因二集群内部访问不需要那么复杂的鉴权,反而更省事点,只需要写个小应用部署到k8s集群中即可。应用已经在集群内部了,就没有鉴权的概念了,其他三方服务只需要调用小应用的api即可操作k8s。

    1. 构建goWeb小应用导入依赖:

      a. 不管是走go的代理还是其他办法,这里默认能搭建goWeb项目,并且能够使用go mod tidy拉取包

      b. 按照官方文档导入依赖这里我用的是0.17.0版本,此处有坑,不仅仅这个版本有这个坑,其他版本很有可能也有,完全正常的导入但是会存在jar包之间版本不一致问题,这个问题会导致go build无法构建,是官方自身的兼容问题,报错信息为:

      # k8s.io/client-go/rest
      ../../../../goworkspace/pkg/mod/k8s.io/client-go@v11.0.0+incompatible/rest/request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
      have (*versioned.Decoder)
      want (watch.Decoder, watch.Reporter)

      c. 可以尝试手动替换k8s.io/apimachinery@v0.17.0为k8s.io/apimachinery@release-1.14来解决。在终端执行# go mod download -json k8s.io/apimachinery@release-1.14最终gomod的关于k8s的所有依赖文件如下所示:

    require (
      k8s.io/api v0.17.0 // indirect
      k8s.io/apimachinery v0.17.0
      k8s.io/client-go v11.0.0+incompatible
      k8s.io/utils v0.0.0-20191114184206-e782cd3c129f // indirect
      sigs.k8s.io/yaml v1.1.0 // indirect
    )
    
    replace (
        k8s.io/api => k8s.io/api v0.0.0-20191004102349-159aefb8556b
        k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20191004105649-b14e3c49469a
        k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191004074956-c5d2f014d689
        sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.3.0
    )

    2.使用 client-go 在 k8s 集群外操作资源:

    代码如下:

    package main
    
    /*
    参考:
    https://studygolang.com/articles/31750
    https://github.com/owenliang/k8s-client-go
    https://yuerblog.cc/2018/12/12/k8s-client-go-setup-and-basic-usage/
    https://www.cnblogs.com/darope/p/12097013.html
    https://www.cnblogs.com/wuchangblog/p/14208555.html
    https://www.cnblogs.com/Dev0ps/p/14919838.html
    https://www.cnblogs.com/rancherlabs/p/11888065.html
    */
    
    
    import (
        "flag"
        "fmt"
        "os"
        "path/filepath"
    
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/client-go/kubernetes"
        "k8s.io/client-go/rest"
        "k8s.io/client-go/tools/clientcmd"
    )
    
    // 2.定义一个函数用来在操作系统中获取目录路径
    func homeDir() string{
        if h:=os.Getenv("HOME");h!=""{
            return h
        }
        return os.Getenv("USERPROFILE")  //windows
    }
    
    func main(){
        // 1.声明三个变量
        var err error
        var config *rest.Config
        // inCluster(Pod).kuberconfig(kubectl)
        var kubeconfig *string
    
    
        //3.在k8s的环境中kubectl配置文件一般存放在用户目录的.kube文件中
        if home:=homeDir();home!=""{
            kubeconfig=flag.String("kubeconfig",filepath.Join(home,".kube","config"),"(可选)kubeconfig 文件的绝对路径")
            fmt.Println(home)
        }else{
            kubeconfig=flag.String("kubeconfig","","kubeconfig 文件的绝对路径")
            fmt.Println(kubeconfig)
            fmt.Println("##################")
        }
        flag.Parse()
        // 4.创建集群配置,首先使用 inCluster 模式(需要区配置对应的RBAC 权限,默认的sa是default-->是没有获取deployment的List权限)
        if config,err =rest.InClusterConfig();err!=nil{
            // 使用Kubeonfig文件配置集群配置Config对象
            if config,err=clientcmd.BuildConfigFromFlags("",*kubeconfig);err!=nil{
                panic(err.Error())
            }
        }
    
        //5.在获取到使用Kubeonfig文件配置的Config对象之后,创建Clientset对象,并对其进行操作
        // 已经获得了rest.Config对象
        // 创建Clientset对象
        clientset,err:=kubernetes.NewForConfig(config)
        if err !=nil{
            panic(err.Error())
        }
    
        // 6.就可以使用Clientset对象获取资源对象,进行增删改查
        // 想要获取default命令空间下面的Deployment的列表
        //deployment,err:=clientset.AppsV1().Deployments("default").List(metav1.ListOptions{})
        deployment,err:=clientset.AppsV1().Deployments("kubernetes-dashboard").List(metav1.ListOptions{})
        if err!=nil{
            panic(err.Error())
        }
    
        for idx,deploy:=range deployment.Items{
            fmt.Printf("%d-%s
    ",idx,deploy.Name)
        }
    
    }

    参考:

    https://studygolang.com/articles/31750

    https://www.cnblogs.com/darope/p/12097013.html

  • 相关阅读:
    常见压缩/解压缩及打包命令
    黑盒测试和白盒测试
    基础命令的操作

    转]DLL-多个进程间共享动态链接库的原理
    Ansi UNICODE,GBK,UTF-8区别
    Cppunit 源码 SynchronizedObject
    二分查找实现
    Androdi 开发学习四 Activity和Intent
    Android开发学习三:adb启动失败
  • 原文地址:https://www.cnblogs.com/sfnz/p/15176306.html
Copyright © 2011-2022 走看看