背景:

后面实现了client-go gin的简略整合五-list-watch deployment利用,进一步把 Rs Pod也实现list-watch!
后面少写的:

/src/core/deployment_init.go

//更新func (depmap *DeploymentMap) Update(dep *v1.Deployment) error {    if list, ok := depmap.data.Load(dep.Namespace); ok {        for i, range_dep := range list.([]*v1.Deployment) {            if range_dep.Name == dep.Name {                list.([]*v1.Deployment)[i] = dep                depmap.data.Store(dep.Namespace, list)            }        }        return nil    }    return fmt.Errorf("deployment-%s not found", dep.Name)}

遗记了Store数据....depmap.data.Store(dep.Namespace, list)!

client-go gin的简略整合六-list-watch二(对于Rs与Pod)

对于Rs list-watch

/src/core/rs_init.go

package coreimport (    "errors"    "fmt"    v1 "k8s.io/api/apps/v1"    "log"    "sync")type RSMapStruct struct {    Data sync.Map}func (rsmap *RSMapStruct) Add(rs *v1.ReplicaSet) {    key := rs.Namespace    if value, ok := rsmap.Data.Load(key); ok {        value = append(value.([]*v1.ReplicaSet), rs)        rsmap.Data.Store(key, value)    } else {        rsmap.Data.Store(key, []*v1.ReplicaSet{rs})    }}func (rsmap *RSMapStruct) Update(rs *v1.ReplicaSet) error {    key := rs.Namespace    if value, ok := rsmap.Data.Load(key); ok {        for index, r := range value.([]*v1.ReplicaSet) {            if r.Name == rs.Name {                value.([]*v1.ReplicaSet)[index] = rs                rsmap.Data.Store(key, value)                return nil            }        }    }    return fmt.Errorf("rs-%s not found", rs.Name)}func (rsmap *RSMapStruct) Delete(rs *v1.ReplicaSet) {    key := rs.Namespace    if value, ok := rsmap.Data.Load(key); ok {        for index, r := range value.([]*v1.ReplicaSet) {            if r.Name == rs.Name {                value = append(value.([]*v1.ReplicaSet)[0:index], value.([]*v1.ReplicaSet)[index+1:]...)                rsmap.Data.Store(key, value)                return            }        }    }}func (rsmap *RSMapStruct) ListByNS(ns string) ([]*v1.ReplicaSet, error) {    if list, ok := rsmap.Data.Load(ns); ok {        return list.([]*v1.ReplicaSet), nil    }    return nil, errors.New("rs record not found")}func (rsmap *RSMapStruct) GetRsLabelsByDeployment(deploy *v1.Deployment) ([]map[string]string, error) {    rs, err := rsmap.ListByNS(deploy.Namespace)    if err != nil {        return nil, err    }    ret := make([]map[string]string, 0)    for _, item := range rs {        //if item.Annotations["deployment.kubernetes.io/revision"] != deploy.Annotations["deployment.kubernetes.io/revision"] {        //    continue        //}        for _, v := range item.OwnerReferences {            if v.Name == deploy.Name {                ret = append(ret, item.Labels)                break            }        }    }    return ret, nil}type RSHandler struct {}func (rsmap *RSHandler) OnAdd(obj interface{}) {    RSMap.Add(obj.(*v1.ReplicaSet))}func (rsmap *RSHandler) OnUpdate(oldObj interface{}, newObj interface{}) {    err := RSMap.Update(newObj.(*v1.ReplicaSet))    if err != nil {        log.Println(err)    }}func (rsmap *RSHandler) OnDelete(obj interface{}) {    RSMap.Delete(obj.(*v1.ReplicaSet))}var RSMap *RSMapStructfunc init() {    RSMap = &RSMapStruct{}}

对于Pod list-watch

先写一个util办法(就为了判断两个label是否雷同!):
/src/core/Util.go

func IsValidLabel(m1, m2 map[string]string) bool {    for key := range m2 {        if m2[key] != m1[key] {            return false        }    }    return true}

根本copy自deployment_init.go:
/src/core/pod_int.go

package coreimport (    "fmt"    corev1 "k8s.io/api/core/v1"    "log"    "sync")type PodMapStruct struct {    data sync.Map}func (podmap *PodMapStruct) Add(pod *corev1.Pod) {    key := pod.Namespace    if value, ok := podmap.data.Load(key); ok {        value = append(value.([]*corev1.Pod), pod)        podmap.data.Store(key, value)    } else {        podmap.data.Store(key, []*corev1.Pod{pod})    }}func (podmap *PodMapStruct) Update(pod *corev1.Pod) error {    key := pod.Namespace    if value, ok := podmap.data.Load(key); ok {        for index, p := range value.([]*corev1.Pod) {            if p.Name == pod.Name {                value.([]*corev1.Pod)[index] = pod                podmap.data.Store(key, value)                return nil            }        }    }    return fmt.Errorf("pod-%s not found", pod.Name)}func (podmap *PodMapStruct) Delete(pod *corev1.Pod) {    key := pod.Namespace    if value, ok := podmap.data.Load(key); ok {        for index, p := range value.([]*corev1.Pod) {            if p.Name == pod.Name {                value = append(value.([]*corev1.Pod)[0:index], value.([]*corev1.Pod)[index+1:]...)                podmap.data.Store(key, value)                return            }        }    }}func (podmap *PodMapStruct) ListByNS(ns string) ([]*corev1.Pod, error) {    if ns != "" {        if list, ok := podmap.data.Load(ns); ok {            return list.([]*corev1.Pod), nil        }    }    return nil, fmt.Errorf("pods not found")}func (podmap *PodMapStruct) ListByLabels(ns string, labels []map[string]string) ([]*corev1.Pod, error) {    pods, err := podmap.ListByNS(ns)    if err != nil {        return nil, err    }    ret := make([]*corev1.Pod, 0)    for _, pod := range pods {        for _, label := range labels {            if IsValidLabel(pod.Labels, label) {                ret = append(ret, pod)            }        }    }    return ret, nil}type PodHandler struct {}var PodMap *PodMapStructfunc init() {    PodMap = &PodMapStruct{}}func (podmap *PodHandler) OnAdd(obj interface{}) {    PodMap.Add(obj.(*corev1.Pod))}func (podmap *PodHandler) OnUpdate(oldObj interface{}, newObj interface{}) {    err := PodMap.Update(newObj.(*corev1.Pod))    if err != nil {        log.Println(err)    }}func (podmap *PodHandler) OnDelete(obj interface{}) {    PodMap.Delete(obj.(*corev1.Pod))}

deployment informer AddEventHandler

/src/core/deployment_init.go

package coreimport (    "fmt"    "k8s-demo1/src/lib"    v1 "k8s.io/api/apps/v1"    "k8s.io/apimachinery/pkg/util/wait"    "k8s.io/client-go/informers"    "log"    "sync")type DeploymentMap struct {    data sync.Map}func (depmap *DeploymentMap) Add(dep *v1.Deployment) {    if list, ok := depmap.data.Load(dep.Namespace); ok {        list = append(list.([]*v1.Deployment), dep)        depmap.data.Store(dep.Namespace, list)    } else {        depmap.data.Store(dep.Namespace, []*v1.Deployment{dep})    }}func (depmap *DeploymentMap) Update(dep *v1.Deployment) error {    if list, ok := depmap.data.Load(dep.Namespace); ok {        for i, range_dep := range list.([]*v1.Deployment) {            if range_dep.Name == dep.Name {                list.([]*v1.Deployment)[i] = dep            }        }        return nil    }    return fmt.Errorf("deployment-%s not found", dep.Name)}// 删除func (depmap *DeploymentMap) Delete(dep *v1.Deployment) {    if list, ok := depmap.data.Load(dep.Namespace); ok {        for i, range_dep := range list.([]*v1.Deployment) {            if range_dep.Name == dep.Name {                newList := append(list.([]*v1.Deployment)[:i], list.([]*v1.Deployment)[i+1:]...)                depmap.data.Store(dep.Namespace, newList)                break            }        }    }}func (depmap *DeploymentMap) ListByNS(ns string) ([]*v1.Deployment, error) {    if list, ok := depmap.data.Load(ns); ok {        return list.([]*v1.Deployment), nil    }    return nil, fmt.Errorf("record not found")}var DepMap *DeploymentMapfunc init() {    DepMap = &DeploymentMap{}}type DepHandler struct {}func (d *DepHandler) OnAdd(obj interface{}) {    //fmt.Println(obj.(*v1.Deployment).Name)    DepMap.Add(obj.(*v1.Deployment))}func (d *DepHandler) OnUpdate(oldObj, newObj interface{}) {    err := DepMap.Update(newObj.(*v1.Deployment))    if err != nil {        log.Println(err)    }}func (d *DepHandler) OnDelete(obj interface{}) {    if d, ok := obj.(*v1.Deployment); ok {        DepMap.Delete(d)    }}func InitDeployment() {    factory := informers.NewSharedInformerFactory(lib.K8sClient, 0)    depinformer := factory.Apps().V1().Deployments()    depinformer.Informer().AddEventHandler(&DepHandler{})    podInformer := factory.Core().V1().Pods().Informer()    podInformer.AddEventHandler(&PodHandler{})    rsInformer := factory.Apps().V1().ReplicaSets().Informer()    rsInformer.AddEventHandler(&RSHandler{})    factory.Start(wait.NeverStop)}

Pod.go

/src/service/Pod.go

package serviceimport (    "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    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,            CreateTime: item.CreationTimestamp.Format("2006-01-02 15:04:05"),        })    }    g.JSON(200, ret)    return}

deployment.go的批改

deployment.go也要批改一下(上次没有将GetPodsByDep等办法批改为list-wath!)
/src/service/deployment.go:

package serviceimport (    "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, err := 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(ns, *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(ns string, dep v1.Deployment) []*Pod {    rsLabelsMap, err := core.RSMap.GetRsLabelsByDeployment(&dep)    if err != nil {        log.Fatal(err)    }    pods, err := core.PodMap.ListByLabels(dep.Namespace, rsLabelsMap)    if err != nil {        log.Fatal(err)    }    ret := make([]*Pod, 0)    for _, pod := range pods {        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),            CreateTime: pod.CreationTimestamp.Format("2006-01-02 15:04:05"),        })    }    return ret}

运行main.go

运行main.go 看是否能拜访pod列表?
http://127.0.0.1:8080/pods?ns...

deployments下的坑......

运行main.go也顺便看了一眼deployment是否失常:
http://127.0.0.1:8080/deploym...

what......deployment的pod串了!想一下也是的:GetRsLabelsByDeployment的时候并没有判断rc与pod的关系,pod的label判断还是不准确的,没有想到好的方法,偷了一个懒:
/src/core/rs_int.go

package coreimport (    "errors"    "fmt"    v1 "k8s.io/api/apps/v1"    "log"    "sync")type RSMapStruct struct {    Data sync.Map}func (rsmap *RSMapStruct) Add(rs *v1.ReplicaSet) {    key := rs.Namespace    if value, ok := rsmap.Data.Load(key); ok {        value = append(value.([]*v1.ReplicaSet), rs)        rsmap.Data.Store(key, value)    } else {        rsmap.Data.Store(key, []*v1.ReplicaSet{rs})    }}func (rsmap *RSMapStruct) Update(rs *v1.ReplicaSet) error {    key := rs.Namespace    if value, ok := rsmap.Data.Load(key); ok {        for index, r := range value.([]*v1.ReplicaSet) {            if r.Name == rs.Name {                value.([]*v1.ReplicaSet)[index] = rs                rsmap.Data.Store(key, value)                return nil            }        }    }    return fmt.Errorf("rs-%s not found", rs.Name)}func (rsmap *RSMapStruct) Delete(rs *v1.ReplicaSet) {    key := rs.Namespace    if value, ok := rsmap.Data.Load(key); ok {        for index, r := range value.([]*v1.ReplicaSet) {            if r.Name == rs.Name {                value = append(value.([]*v1.ReplicaSet)[0:index], value.([]*v1.ReplicaSet)[index+1:]...)                rsmap.Data.Store(key, value)                return            }        }    }}func (rsmap *RSMapStruct) ListByNS(ns string) ([]*v1.ReplicaSet, error) {    if list, ok := rsmap.Data.Load(ns); ok {        return list.([]*v1.ReplicaSet), nil    }    return nil, errors.New("rs record not found")}func (rsmap *RSMapStruct) GetRsLabelsByDeployment(deploy *v1.Deployment) ([]map[string]string, error) {    rs, err := rsmap.ListByNS(deploy.Namespace)    if err != nil {        return nil, err    }    ret := make([]map[string]string, 0)    for _, item := range rs {        //if item.Annotations["deployment.kubernetes.io/revision"] != deploy.Annotations["deployment.kubernetes.io/revision"] {        //    continue        //}        for _, v := range item.OwnerReferences {            if v.Name == deploy.Name {                ret = append(ret, item.Labels)                break            }        }    }    return ret, nil}func (rsmap *RSMapStruct) GetRsLabelsByDeploymentname(deploy *v1.Deployment) string {    rs, err := rsmap.ListByNS(deploy.Namespace)    if err != nil {        fmt.Println(err)    }    for _, item := range rs {        //if item.Annotations["deployment.kubernetes.io/revision"] != deploy.Annotations["deployment.kubernetes.io/revision"] {        //    continue        //}        for _, v := range item.OwnerReferences {            if v.Name == deploy.Name {                return item.Name            }        }    }    return ""}type RSHandler struct {}func (rsmap *RSHandler) OnAdd(obj interface{}) {    RSMap.Add(obj.(*v1.ReplicaSet))}func (rsmap *RSHandler) OnUpdate(oldObj interface{}, newObj interface{}) {    err := RSMap.Update(newObj.(*v1.ReplicaSet))    if err != nil {        log.Println(err)    }}func (rsmap *RSHandler) OnDelete(obj interface{}) {    RSMap.Delete(obj.(*v1.ReplicaSet))}var RSMap *RSMapStructfunc init() {    RSMap = &RSMapStruct{}}

模拟GetRsLabelsByDeployment写了一个GetRsLabelsByDeploymentname办法,恩返回rc的name 等于pod的OwnerReferences字段中的name字段!

/src/service/deployment.go

package serviceimport (    "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),                CreateTime: pod.CreationTimestamp.Format("2006-01-02 15:04:05"),            })        }    }    return ret}

运行mai.go,拜访http://127.0.0.1:8080/deploym...

算是精准匹配了,还不晓得会不会有什么坑......

总结:

总结一下这过程学到的:

  1. deployment rs pod之间的关系
  2. OwnerReferences的匹配
  3. 上面还是持续crud吧......这个中央让我了解的有点长list-watch