当前位置:网站首页>Simple integration of client go gin six list watch two (about the improvement of RS, pod and deployment)
Simple integration of client go gin six list watch two (about the improvement of RS, pod and deployment)
2022-06-11 06:42:00 【saynaihe】
background :
The front is finished client-go gin Simple integration of five -list-watch deployment application , Go one step further Rs Pod It also realizes list-watch!
Less written before :
/src/core/deployment_init.go
// to update
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)
}
Forget the Store data …depmap.data.Store(dep.Namespace, list)!
client-go gin Simple integration of six -list-watch Two ( About Rs And Pod)
About Rs list-watch
/src/core/rs_init.go
package core
import (
"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 *RSMapStruct
func init() {
RSMap = &RSMapStruct{}
}
About Pod list-watch
Write a first util Method ( Just to judge two label Are they the same? !):
/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
}
basic copy since deployment_init.go:
/src/core/pod_int.go
package core
import (
"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 *PodMapStruct
func 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 core
import (
"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)
}
// Delete
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 *DeploymentMap
func 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 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
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 Modification of
deployment.go We need to revise it ( Last time I didn't put GetPodsByDep And other methods are modified as list-wath!)
/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, 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
}
function main.go
function main.go See if you can access pod list ?
http://127.0.0.1:8080/pods?ns=default
deployments Pit under …
function main.go I also took a look at it deployment If there is something wrong :
http://127.0.0.1:8080/deployments?ns=default
what…deployment Of pod Yes ! Think about it :GetRsLabelsByDeployment I didn't judge rc And pod The relationship between ,pod Of label The judgment is still imprecise , Did not think of a good way , Stole a lazy :
/src/core/rs_int.go
package core
import (
"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 *RSMapStruct
func init() {
RSMap = &RSMapStruct{}
}
imitation GetRsLabelsByDeployment Wrote a **GetRsLabelsByDeploymentname Method ,** EN return rc Of name be equal to pod Of OwnerReferences In the field name Field !
/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),
CreateTime: pod.CreationTimestamp.Format("2006-01-02 15:04:05"),
})
}
}
return ret
}
function mai.go, visit http://127.0.0.1:8080/deployments?ns=default
It is an accurate match , I don't know if there will be any pits …
summary :
Sum up the lessons learned in this process :
- deployment rs pod The relationship between
- OwnerReferences The matching of
- Let's continue crud Well … This place is a little long for me to understand list-watch
边栏推荐
- Learn C language well from keywords
- A promise with bare hands
- What are the differences and usages of break and continue?
- [reading this article is enough!!! Easy to understand] confidence level understanding (95% confidence level and confidence interval)
- Detailed installation instructions for MySQL
- Illustrate the principle of one-way linked list and the method of JS to realize linked list [with source code]
- QT socket setting connection timeout
- Shandong University machine learning experiment 5 SVM
- JVM from getting started to giving up 2: garbage collection
- How to arrange the dataframe from small to large according to the absolute value of a column?
猜你喜欢
![Illustrate the principle of one-way linked list and the method of JS to realize linked list [with source code]](/img/0d/2de3413fcb77ac2bd093677035f2e7.jpg)
Illustrate the principle of one-way linked list and the method of JS to realize linked list [with source code]

Convert multiple pictures into one NPY file storage

Analyze the principle of configuration center from the perspective of Nacos client

The nearest common ancestor of 235 binary search tree

网狐游戏服务器房间配置约战定制功能实现

Training and testing of super score model in mmediting

Multimedia框架解析之MediaExtractor源码分析(一)

C language war "minesweeping"

Convert text label of dataset to digital label

Do you use typescript or anyscript
随机推荐
Mediaextractor source code analysis of multimedia framework analysis (1)
Convert text label of dataset to digital label
jenkins-不同风格的项目构建
关于parseInt()
The nearest common ancestor of 235 binary search tree
Error code in ijkplayer
617. merge binary tree
Handwritten a message queue in two ways
Scripy web crawler series tutorials (I) | construction of scripy crawler framework development environment
修复鼠标右键没有vscode快捷入口的问题
Fix the problem that the right mouse button does not have a vscode shortcut
Simple knapsack problem
021 mongodb database from getting started to giving up
The realization of online Fox game server room configuration battle engagement customization function
Detailed installation instructions for MySQL
Shandong University machine learning final 2021
必读1:格局越大的人,越懂得说话
instanceof到底是怎样判断引用数据类型的!
Handwritten promise [04] - then method chain call to recognize promise object self return
End of 2021 graphics of Shandong University