client-go gin的简单整合七-继续完善

Posted 对你无可奈何

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了client-go gin的简单整合七-继续完善相关的知识,希望对你有一定的参考价值。

背景:

紧接上文:client-go gin的简单整合六-list-watch二(关于Rs与Pod以及Deployment的完善),继续去完善相关的event 以及显示pod ip等相关配置还要继续搞一下指定deployment name显示相关pod信息!

client-go gin的简单整合七-继续完善

为什么要加一下event呢?

举一个例子

cat nginx3.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: 
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        command: ["/abc"]
        resources: 
status: 
[zhangpeng@zhangpeng k8s]$ kubectl apply -f nginx3.yaml 
deployment.apps/nginx3 created
[zhangpeng@zhangpeng k8s]$ kubectl get pods -o wide
NAME                      READY   STATUS             RESTARTS      AGE   IP            NODE    NOMINATED NODE   READINESS GATES
nginx-85b98978db-xk7kc    1/1     Running            0             21d   10.244.1.22   k8s-2   <none>           <none>
nginx1-85b98978db-wmvck   1/1     Running            0             28h   10.244.1.29   k8s-2   <none>           <none>
nginx2-6b5fb95cd4-77lk5   1/1     Running            0             29h   10.244.1.27   k8s-2   <none>           <none>
nginx3-9df8ff7bf-mjb2g    0/1     CrashLoopBackOff   1 (17s ago)   50s   10.244.1.32   k8s-2   <none>           <none>


but!访问:http://127.0.0.1:8080/deployments?ns=default(上一节运行的main.go依然在运行前提

为什么pod明明CrashLoopBackOff 了但是他还显示running......

参照:https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/

解决方式:

想到的是判断pod contonditions中status是否为True,如果不是true则打印message字段,写一个方法:
/src/service/PodUtil.go

package service

import v1 "k8s.io/api/core/v1"

func GetPodMessage(pod v1.Pod) string 
    message := ""
    for _, contition := range pod.Status.Conditions 
        if contition.Status != "True" 
            message += contition.Message
        
    
    return message

Pod的struct ,添加对应字段Message:
/src/service/Pod.go

package service

import (
    "context"
    "fmt"
    "github.com/gin-gonic/gin"
    "k8s-demo1/src/core"
    . "k8s-demo1/src/lib"
    v1 "k8s.io/api/apps/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type Pod struct 
    Namespace  string
    Name       string
    Status     string
    Images     string
    NodeName   string
    CreateTime string
    Message    string
    Labels     map[string]string


func ListallPod(g *gin.Context) 
    ns := g.Query("ns")

    //pods, err := K8sClient.CoreV1().Pods(ns).List(context.Background(), metav1.ListOptions)
    pods, err := core.PodMap.ListByNS(ns)
    if err != nil 
        g.Error(err)
    
    ret := make([]*Pod, 0)
    for _, item := range pods 

        ret = append(ret, &Pod
            Namespace:  item.Namespace,
            Name:       item.Name,
            Status:     string(item.Status.Phase),
            Labels:     item.Labels,
            NodeName:   item.Spec.NodeName,
            Images:     item.Spec.Containers[0].Image,
            Message:    GetPodMessage(*item),
            CreateTime: item.CreationTimestamp.Format("2006-01-02 15:04:05"),
        )

    
    g.JSON(200, ret)
    return

/src/service/Deployment.go

package service

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "k8s-demo1/src/core"
    v1 "k8s.io/api/apps/v1"
    "log"
)

type Deployment struct 
    Namespace           string
    Name                string
    Replicas            int32
    AvailableReplicas   int32
    UnavailableReplicas int32
    Images              string
    CreateTime          string
    Labels              map[string]string
    Pods                []*Pod


func ListDeployment(g *gin.Context) 
    ns := g.Query("ns")
    deplist, _ := core.DepMap.ListByNS(ns)
    //dps, err := K8sClient.AppsV1().Deployments(ns).List(context.Background(), metav1.ListOptions)
    //if err != nil 
    //  g.Error(err)
    //
    ret := make([]*Deployment, 0)
    for _, item := range deplist 
        ret = append(ret, &Deployment
            Namespace:           item.Namespace,
            Name:                item.Name,
            Replicas:            item.Status.Replicas,
            AvailableReplicas:   item.Status.AvailableReplicas,
            UnavailableReplicas: item.Status.UnavailableReplicas,
            Images:              item.Spec.Template.Spec.Containers[0].Image,
            Labels:              item.GetLabels(),
            Pods:                GetPodsByDep(*item),
            CreateTime:          item.CreationTimestamp.Format("2006-01-02 15:03:04"),
        )

    
    g.JSON(200, ret)
    return


func GetLabels(m map[string]string) string 
    labels := ""
    // aa=xxx,xxx=xx
    for k, v := range m 
        if labels != "" 
            labels += ","
        
        labels += fmt.Sprintf("%s=%s", k, v)
    
    return labels

func GetPodsByDep(dep v1.Deployment) []*Pod 
    rsLabelsMap, err := core.RSMap.GetRsLabelsByDeployment(&dep)
    if err != nil 
        log.Fatal(err)
    

    pods, err := core.PodMap.ListByRsLabels(dep.Namespace, rsLabelsMap)
    if err != nil 
        log.Fatal(err)
    
    ret := make([]*Pod, 0)

    for _, pod := range pods 
        if core.RSMap.GetRsLabelsByDeploymentname(&dep) == pod.OwnerReferences[0].Name 
            ret = append(ret, &Pod
                Name:       pod.Name,
                Namespace:  pod.Namespace,
                Images:     pod.Spec.Containers[0].Image,
                NodeName:   pod.Spec.NodeName,
                Labels:     pod.Labels,
                Status:     string(pod.Status.Phase),
                Message:    GetPodMessage(*pod),
                CreateTime: pod.CreationTimestamp.Format("2006-01-02 15:04:05"),
            )
        
    
    return ret

运行mai.go
http://127.0.0.1:8080/deployments?ns=default

http://127.0.0.1:8080/pods?ns=default

list-watch实现一下event

注:抄来的,还要消化一下
/src/core/event_int.go

package core

import (
    "fmt"
    v1 "k8s.io/api/core/v1"
    "sync"
)

var EventMap *EventMapStruct

type EventMapStruct struct 
    data sync.Map


func (eventmap EventMapStruct) GetMessage(ns string, kind string, name string) string 
    key := fmt.Sprintf("%s-%s-%s", ns, kind, name)
    if v, ok := eventmap.data.Load(key); ok 
        return v.(*v1.Event).Message
    
    return ""


type EventHandler struct

func (eventmap *EventHandler) storeData(obj interface, isDelete bool) 
    if event, ok := obj.(*v1.Event); ok 
        key := fmt.Sprintf("%s-%s-%s", event.Namespace, event.InvolvedObject.Kind, event.InvolvedObject.Name)
        if !isDelete 
            EventMap.data.Store(key, event)
         else 
            EventMap.data.Delete(key)
        
    


func (eventmap *EventHandler) OnAdd(obj interface) 
    eventmap.storeData(obj, false)


func (eventmap *EventHandler) OnUpdate(oldObj, newObj interface) 
    eventmap.storeData(newObj, false)


func (eventmap *EventHandler) OnDelete(obj interface) 
    eventmap.storeData(obj, true)


func init() 
    EventMap = &EventMapStruct

在/src/core/deployment_int.go int初始化中添加eventInformer:

func InitDeployment() 
    factory := informers.NewSharedInformerFactory(lib.K8sClient, 0)
    depinformer := factory.Apps().V1().Deployments()
    depinformer.Informer().AddEventHandler(&DepHandler)
    Podinformer := factory.Core().V1().Pods()
    Podinformer.Informer().AddEventHandler(&PodHandler)
    Rsinformer := factory.Apps().V1().ReplicaSets()
    Rsinformer.Informer().AddEventHandler(&RSHandler)
    eventInformer := factory.Core().V1().Events()
    eventInformer.Informer().AddEventHandler(&EventHandler)
    factory.Start(wait.NeverStop)

/src/service/Pod.go

package service

import (
    "context"
    "fmt"
    "github.com/gin-gonic/gin"
    "k8s-demo1/src/core"
    . "k8s-demo1/src/lib"
    v1 "k8s.io/api/apps/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type Pod struct 
    Namespace  string
    Name       string
    Status     string
    Images     string
    NodeName   string
    CreateTime string
    //IsReady    bool
    Message      string
    HostIp       string
    PodIp        string
    RestartCount int32
    Labels       map[string]string


func ListallPod(g *gin.Context) 
    ns := g.Query("ns")

    //pods, err := K8sClient.CoreV1().Pods(ns).List(context.Background(), metav1.ListOptions)
    pods, err := core.PodMap.ListByNS(ns)
    if err != nil 
        g.Error(err)
    
    ret := make([]*Pod, 0)
    for _, item := range pods 

        ret = append(ret, &Pod
            Namespace: item.Namespace,
            Name:      item.Name,
            Status:    string(item.Status.Phase),
            Labels:    item.Labels,
            NodeName:  item.Spec.NodeName,
            Images:    item.Spec.Containers[0].Image,
            //IsReady:   GetPodIsReady(*item),
            //Message: GetPodMessage(*item),
            Message:      core.EventMap.GetMessage(item.Namespace, "Pod", item.Name),
            HostIp:       item.Status.HostIP,
            PodIp:        item.Status.PodIP,
            RestartCount: item.Status.ContainerStatuses[0].RestartCount,
            CreateTime:   item.CreationTimestamp.Format("2006-01-02 15:04:05"),
        )

    
    g.JSON(200, ret)
    return

func ListPodsByLabel(ns string, labels []map[string]string) (ret []*Pod) 
    list, err := core.PodMap.ListByRsLabels(ns, labels)
    if err != nil 
        return nil
    

    for _, item := range list 
        ret = append(ret, &Pod
            Name:      item.Name,
            Namespace: item.Namespace,
            Images:    item.Spec.Containers[0].Image,
            NodeName:  item.Spec.NodeName,
            Status:    string(item.Status.Phase),
            //Message: GetPodMessage(*item),
            Message:      core.EventMap.GetMessage(item.Namespace, "Pod", item.Name),
            RestartCount: item.Status.ContainerStatuses[0].RestartCount,
            CreateTime:   item.CreationTimestamp.Format("2006-01-02 15:22:33"),
        )
    

    return


/src/deployment/Deployment.go中Message也可以修改一下:

package service

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "k8s-demo1/src/core"
    v1 "k8s.io/api/apps/v1"
    "log"
)

type Deployment struct 
    Namespace           string
    Name                string
    Replicas            int32
    AvailableReplicas   int32
    UnavailableReplicas int32
    Images              string
    CreateTime          string
    Labels              map[string]string
    Pods                []*Pod


func ListDeployment(g *gin.Context) 
    ns := g.Query("ns")
    deplist, _ := core.DepMap.ListByNS(ns)
    //dps, err := K8sClient.AppsV1().Deployments(ns).List(context.Background(), metav1.ListOptions)
    //if err != nil 
    //  g.Error(err)
    //
    ret := make([]*Deployment, 0)
    for _, item := range deplist 
        ret = append(ret, &Deployment
            Namespace:           item.Namespace,
            Name:                item.Name,
            Replicas:            item.Status.Replicas,
            AvailableReplicas:   item.Status.AvailableReplicas,
            UnavailableReplicas: item.Status.UnavailableReplicas,
            Images:              item.Spec.Template.Spec.Containers[0].Image,
            Labels:              item.GetLabels(),
            Pods:                GetPodsByDep(*item),
            CreateTime:          item.CreationTimestamp.Format("2006-01-02 15:03:04"),
        )

    
    g.JSON(200, ret)
    return


func GetLabels(m map[string]string) string 
    labels := ""
    // aa=xxx,xxx=xx

    for k, v := range m 
        if labels != "" 
            labels += ","
        
        labels += fmt.Sprintf("%s=%s", k, v)
    
    return labels

func GetPodsByDep(dep v1.Deployment) []*Pod 
    rsLabelsMap, err := core.RSMap.GetRsLabelsByDeployment(&dep)
    if err != nil 
        log.Fatal(err)
    

    pods, err := core.PodMap.ListByRsLabels(dep.Namespace, rsLabelsMap)
    if err != nil 
        log.Fatal(err)
    
    ret := make([]*Pod, 0)

    for _, pod := range pods 
        if core.RSMap.GetRsLabelsByDeploymentname(&dep) == pod.OwnerReferences[0].Name 
            ret = append(ret, &Pod
                Name:      pod.Name,
                Namespace: pod.Namespace,
                Images:    pod.Spec.Containers[0].Image,
                NodeName:  pod.Spec.NodeName,
                Labels:    pod.Labels,
                Status:    string(pod.Status.Phase),
                //IsReady:   GetPodIsReady(*pod),
                //  Message:    GetPodMessage(*pod),
                Message:      core.EventMap.GetMessage(pod.Namespace,"Pod",pod.Name),
                HostIp:       pod.Status.HostIP,
                PodIp:        pod.Status.PodIP,
                RestartCount: pod.Status.ContainerStatuses[0].RestartCount,
                CreateTime:   pod.CreationTimestamp.Format("2006-01-02 15:04:05"),
            )
        
    
    return ret

关于Pod IP

[zhangpeng@zhangpeng k8s]$ kubectl edit pod nginx1-85b98978db-wmvck

pod相关字段有两个 podIP hostIP pod struct 添加相关字段HostIp PodIp:
/src/service/Pod.go

package service

import (
    "context"
    "fmt"
    "github.com/gin-gonic/gin"
    "k8s-demo1/src/core"
    . "k8s-demo1/src/lib"
    v1 "k8s.io/api/apps/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type Pod struct 
    Namespace  string
    Name       string
    Status     string
    Images     string
    NodeName   string
    CreateTime string
    Message    string
    HostIp     string
    PodIp      string
    Labels     map[string]string


func ListallPod(g *gin.Context) 
    ns := g.Query("ns")

    //pods, err := K8sClient.CoreV1().Pods(ns).List(context.Background(), metav1.ListOptions)
    pods, err := core.PodMap.ListByNS(ns)
    if err != nil 
        g.Error(err)
    
    ret := make([]*Pod, 0)
    for _, item := range pods 

        ret = append(ret, &Pod
            Namespace: item.Namespace,
            Name:      item.Name,
            Status:    string(item.Status.Phase),
            Labels:    item.Labels,
            NodeName:  item.Spec.NodeName,
            Images:    item.Spec.Containers[0].Image,
            Message:    GetPodMessage(*item),
            HostIp:     item.Status.HostIP,
            PodIp:      item.Status.PodIP,
            CreateTime: item.CreationTimestamp.Format("2006-01-02 15:04:05"),
        )

    
    g.JSON(200, ret)
    return

func ListPodsByLabel(ns string, labels []map[string]string) (ret []*Pod) 
    list, err := core.PodMap.ListByRsLabels(ns, labels)
    if err != nil 
        return nil
    

    for _, item := range list 
        ret = append(ret, &Pod
            Name:      item.Name,
            Namespace: item.Namespace,
            Images:    item.Spec.Containers[0].Image,
            NodeName:  item.Spec.NodeName,
            Status:    string(item.Status.Phase),
            //Message: GetPodMessage(*item),
            Message:    core.EventMap.GetMessage(item.Namespace, "Pod", item.Name),
            CreateTime: item.CreationTimestamp.Format("2006-01-02 15:22:33"),
        )
    

    return

/src/service/Deployment.go

package service

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "k8s-demo1/src/core"
    v1 "k8s.io/api/apps/v1"
    "log"
)

type Deployment struct 
    Namespace           string
    Name                string
    Replicas            int32
    AvailableReplicas   int32
    UnavailableReplicas int32
    Images              string
    CreateTime          string
    Labels              map[string]string
    Pods                []*Pod


func ListDeployment(g *gin.Context) 
    ns := g.Query("ns")
    deplist, _ := core.DepMap.ListByNS(ns)
    //dps, err := K8sClient.AppsV1().Deployments(ns).List(context.Background(), metav1.ListOptions)
    //if err != nil 
    //  g.Error(err)
    //
    ret := make([]*Deployment, 0)
    for _, item := range deplist 
        ret = append(ret, &Deployment
            Namespace:           item.Namespace,
            Name:                item.Name,
            Replicas:            item.Status.Replicas,
            AvailableReplicas:   item.Status.AvailableReplicas,
            UnavailableReplicas: item.Status.UnavailableReplicas,
            Images:              item.Spec.Template.Spec.Containers[0].Image,
            Labels:              item.GetLabels(),
            Pods:                GetPodsByDep(*item),
            CreateTime:          item.CreationTimestamp.Format("2006-01-02 15:03:04"),
        )

    
    g.JSON(200, ret)
    return


func GetLabels(m map[string]string) string 
    labels := ""
    // aa=xxx,xxx=xx

    for k, v := range m 
        if labels != "" 
            labels += ","
        
        labels += fmt.Sprintf("%s=%s", k, v)
    
    return labels

func GetPodsByDep(dep v1.Deployment) []*Pod 
    rsLabelsMap, err := core.RSMap.GetRsLabelsByDeployment(&dep)
    if err != nil 
        log.Fatal(err)
    

    pods, err := core.PodMap.ListByRsLabels(dep.Namespace, rsLabelsMap)
    if err != nil 
        log.Fatal(err)
    
    ret := make([]*Pod, 0)

    for _, pod := range pods 
        if core.RSMap.GetRsLabelsByDeploymentname(&dep) == pod.OwnerReferences[0].Name 
            ret = append(ret, &Pod
                Name:      pod.Name,
                Namespace: pod.Namespace,
                Images:    pod.Spec.Containers[0].Image,
                NodeName:  pod.Spec.NodeName,
                Labels:    pod.Labels,
                Status:    string(pod.Status.Phase),
                Message:    GetPodMessage(*pod),
                HostIp:     pod.Status.HostIP,
                PodIp:      pod.Status.PodIP,
                CreateTime: pod.CreationTimestamp.Format("2006-01-02 15:04:05"),
            )
        
    
    return ret

http://127.0.0.1:8080/deployments?ns=default

http://127.0.0.1:8080/pods?ns=default

Pod重启次数

[zhangpeng@zhangpeng k8s]$ kubectl edit pod nginx3-9df8ff7bf-mzddn


/src/service/Pod.go,Pod struct增加RestartCount int32,取值字段item.Status.ContainerStatuses[0].RestartCount,如下(多个容器后面是不是要考虑循环取值?以后在说吧......):

type Pod struct 
    Namespace  string
    Name       string
    Status     string
    Images     string
    NodeName   string
    CreateTime string
    //IsReady    bool
    Message      string
    HostIp       string
    PodIp        string
    RestartCount int32
    Labels       map[string]string

func ListallPod(g *gin.Context) 
    ns := g.Query("ns")

    //pods, err := K8sClient.CoreV1().Pods(ns).List(context.Background(), metav1.ListOptions)
    pods, err := core.PodMap.ListByNS(ns)
    if err != nil 
        g.Error(err)
    
    ret := make([]*Pod, 0)
    for _, item := range pods 

        ret = append(ret, &Pod
            Namespace: item.Namespace,
            Name:      item.Name,
            Status:    string(item.Status.Phase),
            Labels:    item.Labels,
            NodeName:  item.Spec.NodeName,
            Images:    item.Spec.Containers[0].Image,
            //IsReady:   GetPodIsReady(*item),
            Message: GetPodMessage(*item),
            //Message:    core.EventMap.GetMessage(item.Namespace, "Pod", item.Name),
            HostIp:       item.Status.HostIP,
            PodIp:        item.Status.PodIP,
            RestartCount: item.Status.ContainerStatuses[0].RestartCount,
            CreateTime:   item.CreationTimestamp.Format("2006-01-02 15:04:05"),
        )

    
    g.JSON(200, ret)
    return

接下来的问题:

先删除nginx3 deployment:

[zhangpeng@zhangpeng k8s]$ kubectl delete -f nginx3.yaml 
deployment.apps "nginx3" deleted

创建一个正常的nginx3.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: 
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: 
status: 
[zhangpeng@zhangpeng k8s]$ kubectl apply -f nginx3.yaml 
deployment.apps/nginx3 created
[zhangpeng@zhangpeng k8s]$ kubectl get pods
NAME                      READY   STATUS              RESTARTS   AGE
nginx-85b98978db-xk7kc    1/1     Running             0          23d
nginx1-85b98978db-wmvck   1/1     Running             0          3d23h
nginx2-6b5fb95cd4-77lk5   1/1     Running             0          4d
nginx3-6f97cd4f65-k7ffx   0/1     ContainerCreating   0          4s

[zhangpeng@zhangpeng k8s]$ cp nginx3.yaml nginx33.yaml

vim nginx33.yaml继续创建一个无法成功启动的Pod:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: 
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        command: ["/abc"]
        resources: 
status: 
[zhangpeng@zhangpeng k8s]$ kubectl apply -f nginx33.yaml 
deployment.apps/nginx3 configured


but:


恩 我这里做的还是有问题,deployment中数量显示了 但是没有能显示那个没有成功的pod......(貌似只有重启后才发现最新的,但是也还是显示一个......).这里没有想好怎么处理......也希望有大佬能给指点迷津!

总结:

  1. event实现了list watch
  2. ip restartcount如何在pod中获取
  3. 怎么样显示nginx3示例中两个pod?要好好想一下!

以上是关于client-go gin的简单整合七-继续完善的主要内容,如果未能解决你的问题,请参考以下文章

client-go gin的简单整合七-继续完善

client-go gin的简单整合七-继续完善

client-go gin的简单整合八Service-list初步收尾

client-go gin的简单整合八Service-list初步收尾

client-go gin的简单整合八Service-list初步收尾

client-go gin的简单整合六-list-watch二(关于Rs与Pod以及Deployment的完善)