client-go gin的简单整合五-list-watch deployment应用

从来好事天生俭,自古瓜儿苦后甜。这篇文章主要讲述client-go gin的简单整合五-list-watch deployment应用相关的知识,希望能为你提供帮助。
背景:紧接client-go gin的简单整合四-list-watch初探,list-watch的模式都在测试文件中写的,现在修改一下前面做的deploymentpod namespace 等等的api!
client-go gin的简单整合五-list-watch deployment应用src目录下创建core文件夹,并创建deployment_init.go文件,将test1.go中相关deployment配置迁移过来!(默认test1.go中内容迁移过来)
/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.Deploymentdep)//更新 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] = depreturn nilreturn 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) breakfunc (depmap *DeploymentMap) ListByNS(ns string) ([]*v1.Deployment, error) if list, ok := depmap.data.Load(ns); ok return list.([]*v1.Deployment), nilreturn nil, fmt.Errorf("record not found")var DepMap *DeploymentMapfunc init() DepMap = & DeploymentMaptype 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) factory.Start(wait.NeverStop)

/src/service/deployment.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 Deployment struct Namespacestring Namestring Replicasint32 AvailableReplicasint32 UnavailableReplicas int32 Imagesstring CreateTimestring Labelsmap[string]string Pods[]*Podfunc 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), )g.JSON(200, ret) returnfunc GetDeployment(g *gin.Context) ns := g.Query("ns") name := g.Query("name") ctx := context.Background() getopt := metav1.GetOptions dps, err := K8sClient.AppsV1().Deployments(ns).Get(ctx, name, getopt) if err != nil g.Error(err)ret := make([]*Deployment, 0) ret = append(ret, & Deployment Namespace:dps.Namespace, Name:dps.Name, Replicas:dps.Status.Replicas, AvailableReplicas:dps.Status.AvailableReplicas, UnavailableReplicas: dps.Status.UnavailableReplicas, Images:dps.Spec.Template.Spec.Containers[0].Image, CreateTime:dps.CreationTimestamp.Format("2006-01-02 15:03:04"), Labels:dps.Labels, Pods:GetPodsByDep(ns, dps), ) g.JSON(200, ret) returnfunc 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 labelsfunc GetPodsByDep(ns string, dep *v1.Deployment) []*Pod ctx := context.Background() listopt := metav1.ListOptions LabelSelector: GetLabels(dep.Spec.Selector.MatchLabels),list, err := K8sClient.CoreV1().Pods(ns).List(ctx, listopt) if err != nil panic(err.Error())pods := make([]*Pod, len(list.Items)) for i, pod := range list.Items pods[i] = & Pod Namespace:pod.Namespace, Name:pod.Name, //获取 pod名称 Status:string(pod.Status.Phase), Images:pod.Spec.Containers[0].Image, NodeName:pod.Spec.NodeName, //所属节点 Labels:pod.Labels, CreateTime: pod.CreationTimestamp.Format("2006-01-02 15:04:05"), //创建时间return pods

go run main.go 启动应用浏览器访问http://127.0.0.1:8080/deployments?ns=default
client-go gin的简单整合五-list-watch deployment应用

文章图片

继续完善deployment的程序 问题复现: nginx.yaml
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: nginx name: nginx 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 nginx.yaml deployment.apps/nginx created

nginx1.yaml
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: nginx name: nginx1 spec: replicas: 1 selector: matchLabels: app: nginx strategy: template: metadata: creationTimestamp: null labels: app: nginx spec: containers: - image: nginx name: nginx1 resources: status:

[zhangpeng@zhangpeng k8s]$ kubectl apply -f nginx1.yaml deployment.apps/nginx1 created

client-go gin的简单整合五-list-watch deployment应用

文章图片

浏览器继续访问http://127.0.0.1:8080/deployments?ns=default
见证奇迹的时候到了!为什么deployments中出现了另外一个deployment中的pod了呢?
client-go gin的简单整合五-list-watch deployment应用

文章图片

client-go gin的简单整合五-list-watch deployment应用

文章图片

Deploymentrepliceset and Pods这是因为我们前面将Pod与Deployment绑定使用了(其实我的个人环境完全可以这样,因为我的标签没有重复使用的都区分了不同的名称)
关于deployment与RepliceSet:
https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/
https://kubernetes.io/zh/docs/concepts/workloads/controllers/replicaset/#how-a-replicaset-works
deployment管理pod的机制:
client-go gin的简单整合五-list-watch deployment应用

文章图片

[root@k8s-master-01 test]# kubectl get deployments NAMEREADYUP-TO-DATEAVAILABLEAGE nginx1/1112m40s nginx11/1112m16s [root@k8s-master-01 test]# kubectl get pods NAMEREADYSTATUSRESTARTSAGE nginx-6799fc88d8-sbrcd1/1Running02m46s nginx1-6dc5c6d499-bzhgn1/1Running02m22s [root@k8s-master-01 test]# kubectl get rs NAMEDESIREDCURRENTREADYAGE nginx-6799fc88d81113m42s nginx1-6dc5c6d4991113m18s

注:非前面集群 ,远程办公在家演示.....故pod名称 主机名可能不相同,忽略......
首先写一个方法根据deployment名称取repliceset标签:
client-go gin的简单整合五-list-watch deployment应用

文章图片

client-go gin的简单整合五-list-watch deployment应用

文章图片

/src/common/common.go
package commonimport ( "context" "k8s-demo1/src/lib" v1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" )func GetRsLableByDeployment(dep *v1.Deployment) string selector, _ := metav1.LabelSelectorAsSelector(dep.Spec.Selector) listOpt := metav1.ListOptions LabelSelector: selector.String(),rs, _ := lib.K8sClient.AppsV1().ReplicaSets(dep.Namespace).List(context.Background(), listOpt) for _, item := range rs.Items if IsCurrentRsByDep(dep, item) s, err := metav1.LabelSelectorAsSelector(item.Spec.Selector) if err != nil return ""return s.String()return ""func IsCurrentRsByDep(dep *v1.Deployment, rs v1.ReplicaSet) bool if rs.ObjectMeta.Annotations["deployment.kubernetes.io/revision"] != dep.ObjectMeta.Annotations["deployment.kubernetes.io/revision"] return falsefor _, ref := range rs.OwnerReferences if ref.Kind == "Deployment" & & ref.Name == dep.Name return truereturn false

/src/service/deployment.go
package serviceimport ( "context" "fmt" "github.com/gin-gonic/gin" "k8s-demo1/src/common" "k8s-demo1/src/core" . "k8s-demo1/src/lib" v1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" )type Deployment struct Namespacestring Namestring Replicasint32 AvailableReplicasint32 UnavailableReplicas int32 Imagesstring CreateTimestring Labelsmap[string]string Pods[]*Podfunc 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, CreateTime:item.CreationTimestamp.Format("2006-01-02 15:03:04"), Labels:item.GetLabels(), Pods:GetPodsByDep(ns, item), )g.JSON(200, ret) returnfunc GetDeployment(g *gin.Context) ns := g.Query("ns") name := g.Query("name") ctx := context.Background() getopt := metav1.GetOptions dps, err := K8sClient.AppsV1().Deployments(ns).Get(ctx, name, getopt) if err != nil fmt.Println(err)ret := make([]*Deployment, 0) ret = append(ret, & Deployment Namespace:dps.Namespace, Name:dps.Name, Replicas:dps.Status.Replicas, AvailableReplicas:dps.Status.AvailableReplicas, UnavailableReplicas: dps.Status.UnavailableReplicas, Images:dps.Spec.Template.Spec.Containers[0].Image, CreateTime:dps.CreationTimestamp.Format("2006-01-02 15:03:04"), Labels:dps.Labels, Pods:GetPodsByDep(ns, dps), ) //fmt.Println(ret) g.JSON(200, ret) returnfunc 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 labelsfunc GetPodsByDep(ns string, dep *v1.Deployment) []*Pod ctx := context.Background() listopt := metav1.ListOptions LabelSelector: common.GetRsLableByDeployment(dep),list, err := K8sClient.CoreV1().Pods(ns).List(ctx, listopt) if err != nil panic(err.Error())pods := make([]*Pod, len(list.Items)) for i, pod := range list.Items pods[i] = & Pod Namespace:pod.Namespace, Name:pod.Name, //获取 pod名称 Status:string(pod.Status.Phase), Images:pod.Spec.Containers[0].Image, NodeName:pod.Spec.NodeName, //所属节点 Labels:pod.Labels, CreateTime: pod.CreationTimestamp.Format("2006-01-02 15:04:05"), //创建时间return pods

/src/main.go
package mainimport ( "github.com/gin-gonic/gin" "k8s-demo1/src/core" "k8s-demo1/src/service" //"k8s.io/client-go/informers/core" )func main() r := gin.Default() r.GET("/", func(context *gin.Context) context.JSON(200, "hello") ) r.GET("/namespaces", service.ListNamespace) r.GET("/deployments", service.ListDeployment) r.GET("/service", service.ListService) r.GET("/deployment", service.GetDeployment) r.GET("pods", service.ListallPod) //r.GET("deployment1", service.GetDeployment1) core.InitDeployment() r.Run()

【client-go gin的简单整合五-list-watch deployment应用】http://127.0.0.1:8080/deployments?ns=default
注:远程测试的用内网集群(前面做实验yaml开始有写错的,测试怀疑人生了。远程测试的!)
client-go gin的简单整合五-list-watch deployment应用

文章图片

收获:
  1. 代码好多https://github.com/cleverhu/k8s-manger-v1中copy来的。
  2. deployment repliceset pods之间的关系还要深究一下。kubernetes基础知识还是要更深入一下
  3. 代码写的还是很不顺畅......一步一步来吧

    推荐阅读