Kubernetes对外暴露了很多REST API,有些公司会使用这些API来二次开发或者结合自身的系统进行一些二次开发,毕竟从CI/CD的角度讲,k8s只是提供了CD这一块的功能,CI是缺失的。

但如果你调用过k8s的REST API,你会发现对接上比较费劲,一是每个API都需要在header里面带上Access Token,二是很多API返回的内容多到无法直视,导致你不知道怎么从返回结果中解析出需要的内容。

我这里给大家提供另外一种思路,k8s的源代码其实是基于很多依赖包完成的,其中就有client SDK,代码库地址是:

​https://github.com/kubernetes/client-go.git​​ 如果你会写GO的话就可以直接导入以上代码库到你的项目中使用,版本请选择对应的版本。

SDK使用示例
这里举几个例子来介绍其用法。获取某个应用中的pod列表
 

func (c *Client) ListPodsPerApp(w http.ResponseWriter, r *http.Request) {
k8sClient, err := kubernetes.NewForConfig(c.Config)
if err != nil {
config.Error.Printf(err.Error())
config.ResponseWriter(w, config.STATUSINTERNALERROR, err.Error(), err.Error())
return
}
opts := metav1.ListOptions{}
// make sure that this label is marked in YAML template
opts.LabelSelector = strings.Join([]string{"name", r.URL.Query().Get("app")}, "=")
result, err := k8sClient.CoreV1().Pods(r.URL.Query().Get("project")).List(opts)
if err != nil {
config.Error.Printf(err.Error())
if err.Error() == "Unauthorized" {
config.ResponseWriter(w, config.STATUSUNAUTHORIZEDERROR, err.Error(), err.Error())
return
}
config.ResponseWriter(w, config.STATUSINTERNALERROR, err.Error(), err.Error())
return
}
var pods Pods
for _, e := range result.Items {
pod := Pod{PodName:e.Name, HostIP:e.Status.HostIP, Status:e.Status.Phase}
pods = append(pods, pod)

}
config.ResponseWriter(w, config.STATUSOK, pods, pods)
return
}

创建service
 

func (c *Client) CreateService(w http.ResponseWriter, r *http.Request)  {
k8sClient, err := kubernetes.NewForConfig(c.Config)
if err != nil {
config.Error.Printf(err.Error())
config.ResponseWriter(w, config.STATUSINTERNALERROR, err.Error(), err.Error())
return
}

// Payload field must start with Upper Case, and Request Body must start with Lower Case
type Payload struct {
Project string
Name string
// Labels should always be name: xxxx, app: xxxx
Labels map[string]string
Ports []corev1.ServicePort
Selector map[string]string
Type corev1.ServiceType
}
decoder := json.NewDecoder(r.Body)
var payload Payload
err = decoder.Decode(&payload)
if err != nil {
config.Error.Printf(err.Error())
config.ResponseWriter(w, config.STATUSINTERNALERROR, err.Error(), err.Error())
return
}

params := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: payload.Name,
Labels: payload.Labels,
},
Spec: corev1.ServiceSpec{
Ports: payload.Ports,
Selector: payload.Selector,
Type: payload.Type,
},
}

result, err := k8sClient.CoreV1().Services(payload.Project).Create(params)
if err != nil {
config.Error.Printf(err.Error())
if err.Error() == "Unauthorized" {
config.ResponseWriter(w, config.STATUSUNAUTHORIZEDERROR, err.Error(), err.Error())
return
}
config.ResponseWriter(w, config.STATUSINTERNALERROR, err.Error(), err.Error())
return
}
config.ResponseWriter(w, config.STATUSOK, result, result)
return
}

通过调用SDK,你可以很方便的获取自己想要返回的内容。

上面代码片段中的c.Config是读取.kube/config的内容,.kube/config里面包含了k8s Master的地址和Access Token,但是Access Token每隔24小时需要更新一次,为了解决这个问题我们可以采用证书的方式来认证k8s Master,具体的内容请查看k8s Master节点里面.kube/config的内容。

读取.kube/config的代码如下:

type Client struct {
Config *restclient.Config
}

func LoadConfig() *restclient.Config {
var kubeconfig string
if home := homeDir(); home != "" {
kubeconfig = filepath.Join(home, ".kube", "config")
}
// use the current context in kubeconfig
openshiftClientKubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
fmt.Printf("Read kubeconfig Error:\n %s", err )
os.Exit(1)
}
return openshiftClientKubeConfig
}

func homeDir() string {
if h := os.Getenv("HOME"); h != "" {
return h
}
return os.Getenv("USERPROFILE") // windows
}

在实际开发过程中你可以按照以上思路实现你的二次开发。