用client-go调用Kubernetes API

背景

client-go是go语言访问Kubernetes API的一种新的框架。本文记录client-go访问Kubernetes的过程。最终实现了给服务器端发送container ID,服务器端会返回该container所在pod的pod Name与Spacename。我们Kubernetes集群中一个pod都只运行了一个container。
程序用httprouter包来作为http的访问接口。返回的值编码为Json文件,客户拿到Json之后再进行解析,最终拿到需要的信息。如图:
用client-go调用Kubernetes API_第1张图片
程序实现基本功能之后,用Dockerfile将程序打包成docker镜像。

源代码

package main

import (
    "flag"
    "fmt"
    "github.com/julienschmidt/httprouter"
    "net/http"
    "io"
    "io/ioutil"
    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"
    "encoding/json"
)

type Container_msg struct {
    Name string
    Namespace string
}

func main() {
    router := httprouter.New()

    kubeconfig := flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
    flag.Parse()

    if *kubeconfig == "" {
        panic("-kubeconfig not specified")
    }

    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
        panic(err)
    }

    clientset, err := kubernetes.NewForConfig(config)

    if err != nil {
        panic(err)
    }

    router.POST("/api/v1/containerID",func(w http.ResponseWriter, r *http.Request, _ httprouter.Params){

        podsClient := clientset.Pods(apiv1.NamespaceAll)

        // List Pods
        list, err := podsClient.List(metav1.ListOptions{
        })
        if err != nil {
            panic(err)
        }

        body,_ := ioutil.ReadAll(io.LimitReader(r.Body,1122334))


        for _, d := range list.Items {
            containerID := d.Status.ContainerStatuses[0].ContainerID[9:]
            if string(body)==containerID{
                container_msg := Container_msg{
                    d.Name,
                    d.Namespace,
                }

                c,err := json.Marshal(container_msg)

                if err != nil{
                    panic(err)
                }

                fmt.Fprintf(w,"%v", c)
            }
        }
    })
        http.ListenAndServe(":8082", router)
}

具体实现

上面我已经先把程序的源代码贴出来了,接下来就进行逐步分析

1.获取第三方包client-go与httprouter

https://github.com/kubernetes/client-go
https://github.com/julienschmidt/httprouter
进入它们的github中看使用说明按步骤安装即可。
简单来说,就是分别使用go get k8s.io/client-go/…与go get github.com/julienschmidt/httprouter命令即可。
不过要记得在安装之前配置GOPATH环境变量。比如我的项目是放在naruto目录中的,所以我的GOPATH设置为naruto目录。
配置完GOPATH环境变量,安装完第三方包,我们就可以直接使用它们了。

2.使用httprouter包中的方法获取客户发来的container ID

router := httprouter.New()
建立http连接

http.ListenAndServe(":8082", router)
在8082端口进行监听

router.POST
获取客户端POST的数据

3.用client-go获取Kubernetes集群中pod信息

clientset, err := kubernetes.NewForConfig(config)
使用config建立client-go与Kubernetes集群的关系
config文件是Kubernetes集群的配置文件,存放在集群Master节点的~/.kube/config中
建立好连接之后, 我们就可以使用clientset的对应方法来获取pod或deployment等对象资源的信息。

4.比较获取到的container ID与集群中各pod的container ID

因为我们集群中一个pod仅运行着一个container,所以,我们只需要将pod中container的ID得到之后与获取到的客户发来了container ID做比较即可。假如相等,就可以把此pod的信息返回给客户端。

body,_ := ioutil.ReadAll(io.LimitReader(r.Body,1122334))

for _, d := range list.Items {
    containerID := d.Status.ContainerStatuses[0].ContainerID[9:]
    if string(body)==containerID{
     container_msg := Container_msg{
               d.Name,
               d.Namespace,
           }

     c,err := json.Marshal(container_msg)

      if err != nil{
             panic(err)
           }

     fmt.Fprintf(w,"%v", c)

打包成docker镜像

通过编写Dockerfile文件来建立一个新的镜像。

FROM img.reg.3g:15000/go:1.8     //以这个镜像为基础镜像
COPY naruto /pf      //将naruto目录下的文件复制到容器中文件系统/目录下的pf目录中
ENV GOPATH /pf          //配置环境变量
RUN go build /pf/main_v1.go   //编译写好的程序
CMD /main_v1 -kubeconfig=/pf/config   //以运行该程序的进程为容器的主进程

我们需要将main.go、config、第三方包、Dockerfile都放在同一目录下。通过docker build命令建立镜像。

你可能感兴趣的:(kubernetes)