从来好事天生俭,自古瓜儿苦后甜。这篇文章主要讲述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
文章图片
继续完善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
文章图片
浏览器继续访问http://127.0.0.1:8080/deployments?ns=default
见证奇迹的时候到了!为什么deployments中出现了另外一个deployment中的pod了呢?
文章图片
文章图片
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的机制:
文章图片
[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标签:
文章图片
文章图片
/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开始有写错的,测试怀疑人生了。远程测试的!)
文章图片
收获:
- 代码好多https://github.com/cleverhu/k8s-manger-v1中copy来的。
- deployment repliceset pods之间的关系还要深究一下。kubernetes基础知识还是要更深入一下
- 代码写的还是很不顺畅......一步一步来吧
推荐阅读
- 腾讯地图定位
- input的radio实现点击文字,后面的框框也选中的效果
- 火狐浏览器滚动条的样式问题
- 没网的苦恼
- 隐藏个人设置邮件跟踪选项中的所有邮件这个选项的方法
- Power Apps component framework (PCF) 手把手入门实例
- 常见的通过Web API执行associate和disassociate消息示例
- 用户离职后如何删除其个人视图(Personal View)()
- Power Apps原生支持富文本展示和编辑文本字段了