背景:
紧接上文:client-go gin的简单整合六-list-watch二(关于Rs与Pod以及Deployment的完善),继续去完善相关的event 以及显示pod ip等相关配置还要继续搞一下指定deployment name显示相关pod信息!
client-go gin的简单整合七-继续完善
为什么要加一下event呢?
举一个例子
cat nginx3.yaml
代码语言:txt复制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: {}
代码语言:txt复制[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
代码语言:txt复制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
代码语言:txt复制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
代码语言:txt复制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
代码语言:txt复制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:
代码语言:txt复制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
代码语言:txt复制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也可以修改一下:
代码语言:txt复制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
代码语言:txt复制[zhangpeng@zhangpeng k8s]$ kubectl edit pod nginx1-85b98978db-wmvck
/src/service/Pod.go
代码语言:txt复制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
代码语言:txt复制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
Pod重启次数
代码语言:txt复制[zhangpeng@zhangpeng k8s]$ kubectl edit pod nginx3-9df8ff7bf-mzddn
/src/service/Pod.go,Pod struct增加RestartCount int32,取值字段item.Status.ContainerStatuses0.RestartCount,如下(多个容器后面是不是要考虑循环取值?以后在说吧......):
代码语言:txt复制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:
代码语言:txt复制[zhangpeng@zhangpeng k8s]$ kubectl delete -f nginx3.yaml
deployment.apps "nginx3" deleted
创建一个正常的nginx3.yaml
代码语言:txt复制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: {}
代码语言:txt复制[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
代码语言:txt复制[zhangpeng@zhangpeng k8s]$ cp nginx3.yaml nginx33.yaml
vim nginx33.yaml继续创建一个无法成功启动的Pod:
代码语言:txt复制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: {}
代码语言:txt复制[zhangpeng@zhangpeng k8s]$ kubectl apply -f nginx33.yaml
deployment.apps/nginx3 configured
but:
恩 我这里做的还是有问题,deployment中数量显示了 但是没有能显示那个没有成功的pod......(貌似只有重启后才发现最新的,但是也还是显示一个......).这里没有想好怎么处理......也希望有大佬能给指点迷津!
总结:
- event实现了list watch
- ip restartcount如何在pod中获取
- 怎么样显示nginx3示例中两个pod?要好好想一下!