【GO】 K8s 管理系统项目[API部分--Pod]

K8s 管理系统项目[API部分–Pod]

前端: Vue+element plus
后端: go+gin

1. 功能设计

请添加图片描述

2. 初始化

2.1创建项目

请添加图片描述

2.2 配置goproxy

GOPROXY=https://goproxy.cn

请添加图片描述

2.3 添加格式化工具

请添加图片描述

2.4 安装模块

go get k8s.io/client-go/tools/clientcmd
go get k8s.io/api/core/v1
go get k8s.io/apimachinery/pkg/apis/meta/v1
go get github.com/gin-gonic/gin
go get github.com/wonderivan/logger
go get gorm.io/gorm
go get gorm.io/driver/sqlite
go get gorm.io/driver/mysql

3. 项目目录

3.1 项目目录含义

目录名 作用
config 定义全局配置,如:监听地址,管理员账号等
controller controller层,定义路由规则及接口入参和相应
service 服务层,处理接口的业务逻辑
dao 数据库操作,包含数据的增删改查
model 定义数据库表的字段
db 用于初始化数据库连接及配置
middle 中间件层,添加全局的逻辑处理,如跨域,jwt验证等
utils 工具目录,定义常用工具,如token解析,文件操作等
go.mod 定义项目的依赖包以及版本
main.go 项目主入口,main函数

3.2 创建目录

D:\golang\k8s-plantform> mkdir controller config service dao db model middle utils
D:\golang\k8s-plantform>tree /f
卷 新加卷 的文件夹 PATH 列表
卷序列号为 7463-6B24
D:.
│  go.mod
│  go.sum
│  main.go
│
├─.idea
│      .gitignore
│      k8s-plantform.iml
│      modules.xml
│      watcherTasks.xml
│      workspace.xml
│
├─config
│      config
│
├─controller
├─dao
├─db
├─middle
├─model
├─service
└─utils

4. 定义路由

4.1 Gin初始化

4.1.1初始化路由

controller/router.go

// 初始化router类型的对象,首字母大写,用于跨包调用
var Router router

// 声明一个router的结构体
type router struct{
    
    }

func (r *router) InitApiRouter(router *gin.Engine) {
    
    
	router.GET("/", Index)
}

func Index(ctx *gin.Context) {
    
    
	ctx.JSON(200, gin.H{
    
    
		"code": 200,
		"msg":  "In index",
	})
}

4.1.2 定义监听的常量

config/config.go

package config

const (
	ListenAddr = "0.0.0.0:9090"
)

4.1.3 gin初始化

main.go

func main() {
    
    
	// 初始化gin
	r := gin.Default()
	controller.Router.InitApiRouter(r)
	// gin 程序启动
	//r.Run(config.ListenAdd)
	r.Run(config.ListenAddr)
}

启动服务后可以正常访问到url

root@harbor-1:~# curl 192.168.31.1:9090
{
    
    "code":200,"msg":"In index"}

4.2 初始化k8s Client

4.2.1 初始化K8s client

service/init.go

import (
	"k8s-plantform/config"
	"github.com/wonderivan/logger"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

// 用于初始化k8s client
var K8s k8s

type k8s struct {
    
    
	ClientSet *kubernetes.Clientset
}

// 初始化k8s
func (k *k8s) Init() {
    
    
	// 将kuberconfig文件转换成rest.config对象
	conf, err := clientcmd.BuildConfigFromFlags("", config.KubeConfig)
	if err != nil {
    
    
		panic("获取K8s配置失败:" + err.Error())
	} else {
    
    
		logger.Info("获取K8s配置 成功!")
	}
	// 根据rest.config对象,new一个clientset出来
	clientset, err := kubernetes.NewForConfig(conf)
	if err != nil {
    
    
		panic("创建K8s client失败:" + err.Error())
	} else {
    
    
		logger.Info("创建K8s client 成功!")
	}
	k.ClientSet = clientset
}

4.2.2 定义KubeConfig常量

config/config.go

const (
	ListenAddr = "0.0.0.0:9090"
	KubeConfig = "D:\\golang\\k8s-plantform\\config\\config"
)

4.2.3 main中初始化

main.go

func main() {
    
    
	// 初始化k8s client
	service.K8s.Init()	// <<-----这行  可以使用service.K8s.clientset 进行跨包调用
	// 初始化gin
	r := gin.Default()
	controller.Router.InitApiRouter(r)
	// gin 程序启动
	//r.Run(config.ListenAdd)
	fmt.Println("http://192.168.31.1:9090/")
	r.Run(config.ListenAddr)
}

重启服务没有报错就是成功

5. API

请添加图片描述

  1. Model层: 实体层>> 表数据与类的映射关系,这里的类就是strcut
  2. Dao层: 持久层/数据访问层>> 主要与数据库交互,增删改查
  3. Service层: 业务层 >> 控制业务逻辑,主要处理业务模块的功能逻辑
  4. Controller层: 控制层>> 接收请求参数,调用不同的Service层代码来控制业务流程

5.1 数组排序,过滤,分页实现

service/dataselector.go用来处理数组的排序,过滤,分页

5.1.1 定义数据结构

// dataselector 用于排序,过滤,分页的数据类型
type dataSelector struct {
    
    
	GenericDataList []DataCell
	DataSelect      *DataSelectQuery
}

// DataCell 接口,用于各种资源List的类型转换,转换后可以使用dataselector的排序,过滤,分页方法
type DataCell interface {
    
    
	GetCreation() time.Time
	GetName() string
}

// DataSelectQuery 定义过滤和分页的结构体,过滤:Name 分页:Limit和Page
type DataSelectQuery struct {
    
    
	Filter   *FilterQuery
	Paginate *PaginateQuery
}

// FilterQuery 用于查询 过滤:Name
type FilterQuery struct {
    
    
	Name string
}

// 分页:Limit和Page Limit是单页的数据条数,Page是第几页
type PaginateQuery struct {
    
    
	Page  int
	Limit int
}

5.2 排序

// 实现自定义的排序方法,需要重写Len,Swap,Less方法
// Len用于获取数组的长度
func (d *dataSelector) Len() int {
    
    
	return len(d.GenericDataList)
}

// Swap用于数据比较大小后的位置变更
func (d *dataSelector) Swap(i, j int) {
    
    
	d.GenericDataList[i], d.GenericDataList[j] = d.GenericDataList[j], d.GenericDataList[i]
}

// Less用于比较大小
func (d *dataSelector) Less(i, j int) bool {
    
    
	return d.GenericDataList[i].GetCreation().Before(d.GenericDataList[j].GetCreation())
}

// 重写以上三个方法,用sort.Sort 方法触发排序
func (d *dataSelector) Sort() *dataSelector {
    
    
	sort.Sort(d)
	return d
}

5.3 过滤

// Filter方法用于过滤,比较数据Name属性,若包含则返回
func (d *dataSelector) Filter() *dataSelector {
    
    
	if d.DataSelect.Filter.Name == "" {
    
    
		return d
	}
	filtered := []DataCell{
    
    }
	for _, value := range d.GenericDataList {
    
    
		// 定义是否匹配的标签变量,默认是匹配的
		matches := true
		objName := value.GetName()
		if !strings.Contains(objName, d.DataSelect.Filter.Name) {
    
    
			matches = false
			continue
		}
		if matches {
    
    
			filtered = append(filtered, value)
		}
	}
	d.GenericDataList = filtered
	return d
}

5.4 分页

// Paginate 分页,根据Limit和Page的传参,取一定范围内的数据返回
func (d *dataSelector) Paginate() *dataSelector {
    
    
	limit := d.DataSelect.Paginate.Limit
	page := d.DataSelect.Paginate.Page
	//验证参数合法,若参数不合法,则返回所有数据
	if limit <= 0 || page <= 0 {
    
    
		return d
	}
	//举例:25个元素的数组,limit是10,page是3,startIndex是20,endIndex是30(实际上endIndex是25)
	startIndex := limit * (page - 1)
	endIndex := limit * page

	//处理最后一页,这时候就把endIndex由30改为25了
	if len(d.GenericDataList) < endIndex {
    
    
		endIndex = len(d.GenericDataList)
	}
	d.GenericDataList = d.GenericDataList[startIndex:endIndex]
	return d
}

5.5 定义podCell类型

定义podCell类型,实现DataCell接口用于类型转换

// 定义podCell, 重写GetCreation和GetName 方法后,可以进行数据转换
// covev1.Pod --> podCell  --> DataCell
// appsv1.Deployment --> deployCell --> DataCell
type podCell corev1.Pod
// 重写DataCell接口的两个方法
func (p podCell) GetCreation() time.Time {
    
    
	return p.CreationTimestamp.Time
}
func (p podCell) GetName() string {
    
    
	return p.Name
}

5.2 获取Pod信息

5.2.1 Pod封装转换

service/pod.go

var Pod pod

// 定义列表的返回内容,Items是pod元素列表,Total是元素数量
type PodsResp struct {
    
    
	Total int          `json:"total"`
	Items []corev1.Pod `json:"items"`
}
type pod struct{
    
    }

// 获取pod列表,支持过滤,排序,分页
func (p *pod) GetPods(filterName, namespace string, limit, page int) (podsResp *PodsResp, err error) {
    
    
	//context.TODO()  用于声明一个空的context上下文,用于List方法内设置这个请求超时
	//metav1.ListOptions{} 用于过滤List数据,如label,field等
	podList, err := K8s.ClientSet.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{
    
    })
	if err != nil {
    
    
		logger.Info("获取Pod列表失败," + err.Error())
		// 返回给上一层,最终返回给前端,前端捕获到后打印出来
		return nil, errors.New("获取Pod列表失败," + err.Error())
	}
	// 实例化dataselector结构体,组装数据
	selectableData := &dataselector{
    
    
		GenericDataList: p.toCells(podList.Items),
		DataSelect: &DataSelectQuery{
    
    
			Filter: &FilterQuery{
    
    Name: filterName},
			Paginate: &PaginateQuery{
    
    
				Limit: limit,
				Page:  page,
			},
		},
	}
	// 先过滤
	filtered := selectableData.Filter()
	// 排序和分页
	data := filtered.Sort().Paginate()
    total := len(data.GenericDataList)
	// 将DataCell类型转成Pod
	pods := p.fromCells(data.GenericDataList)
	return &PodsResp{
    
    
		Total: total,
        Items: pods,
	},nil
}

// 类型转换方法corev1.Pod --> DataCell,DataCell-->corev1.Pod
func (p *pod) toCells(pods []corev1.Pod) []DataCell {
    
    
	cells := make([]DataCell, len(pods))
	for i := range pods {
    
    
		cells[i] = podCell(pods[i])
	}
	return cells
}

func (p *pod) fromCells(cells []DataCell) []corev1.Pod {
    
    
	pods := make([]corev1.Pod, len(cells))
	for i := range cells {
    
    
		// cells[i].(podCell)是将DataCell类型转换成podCell
		pods[i] = corev1.Pod(cells[i].(podCell))
	}
	return pods
}

5.2.2 获取pod列表

获取pod列表,支持分页,过滤,排序

controller/pod.go

package controller

import (
	"k8s-plantform/service"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/wonderivan/logger"
)

var Pod pod

type pod struct{
    
    }

// 获取pod列表,支持分页,过滤,排序
func (p *pod) GetPods(ctx *gin.Context) {
    
    
	// 处理入参
	// 匿名结构体用于定义入参,get请求为form格式,其他为json格式
	params := new(struct {
    
    
		FilterName string `form:"filter_name"`
		Namespace  string `form:"namespace"`
		Limit      int    `form:"limit"`
		Page       int    `form:"page"`
	})
	// form 格式使用Bind方法,json格式使用ShouldBindJson方法
	if err := ctx.Bind(params); err != nil {
    
    
		logger.Error("Bind绑定参数失败," + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  "Bind绑定参数失败," + err.Error(),
			"data": nil,
		})
		return
	}
	data, err := service.Pod.GetPods(params.FilterName, params.Namespace, params.Limit, params.Page)
	if err != nil {
    
    
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
    
    
		"msg":  "获取Pod列表成功",
		"data": data,
	})
}

5.2.3 配置router

import (
	"github.com/gin-gonic/gin"
)

// 初始化router类型的对象,首字母大写,用于跨包调用
var Router router

// 声明一个router的结构体
type router struct{
    
    }

func (r *router) InitApiRouter(router *gin.Engine) {
    
    
	router.
		GET("/api/k8s/pods", Pod.GetPods)
}

此时启动服务后可以通过postman获取到所有pod的信息

如果不加参数就是获取到所有pod信息

请添加图片描述

加了参数就可以对namespace,分页等进行过滤

请添加图片描述

可以只过滤某一个pod

请添加图片描述

5.2.4 获取Pod详情

service/pod.go

func (p *pod) GetDetail(podName string, namespace string) (pod *corev1.Pod, err error) {
    
    
	pod, err = K8s.ClientSet.CoreV1().Pods(namespace).Get(context.TODO(), podName, metav1.GetOptions{
    
    })
	if err != nil {
    
    
		logger.Error("获取Pod详情失败," + err.Error())
		return nil, errors.New("获取Pod详情失败," + err.Error())
	}
	return pod, nil
}

5.2.5 删除Pod

func (p *pod) DeletePod(podName string, namespace string) (err error) {
    
    
	err = K8s.ClientSet.CoreV1().Pods(namespace).Delete(context.TODO(), podName, metav1.DeleteOptions{
    
    })
	if err != nil {
    
    
		logger.Error("删除Pod详情失败," + err.Error())
		return errors.New("删除Pod详情失败," + err.Error())
	}
	return nil
}

5.2.6 更新Pod

func (p *pod) UpdatePod(podName string, namespace, content string) (err error) {
    
    
	var pod = &corev1.Pod{
    
    }
	// 反序列化为Pod对象
	err = json.Unmarshal([]byte(content), pod)
	if err != nil {
    
    
		logger.Error("反序列化失败," + err.Error())
		return errors.New("反序列化失败," + err.Error())
	}
	// 更新pod
	_, err = K8s.ClientSet.CoreV1().Pods(namespace).Update(context.TODO(), pod, metav1.UpdateOptions{
    
    })
	if err != nil {
    
    
		logger.Error("更新Pod失败," + err.Error())
		return errors.New("更新Pod失败," + err.Error())
	}
	return nil
}

5.2.7 获取Pod中的容器名

func (p *pod) GetPodContainer(podName string, namespace string) (containers []string, err error) {
    
    
	pod, err := p.GetPodDetail(podName, namespace)
	if err != nil {
    
    
		return nil, err
	}
	for _, container := range pod.Spec.Containers {
    
    
		containers = append(containers, container.Name)
	}
	return containers, nil
}

5.2.8 获取容器日志

// 获取Pod内容器日志
func (p *pod) GetPodLog(containerName string, podName string, namespace string) (log string, err error) {
    
    
	//设置日志配置,容器名,获取内容的配置
	lineLimit := int64(config.PodLogTailLine)
	option := &corev1.PodLogOptions{
    
    
		Container: containerName,
		TailLines: &lineLimit,
	}
	// 获取一个request实例
	req := K8s.ClientSet.CoreV1().Pods(namespace).GetLogs(podName, option)
	// 发起stream连接,获取到Response.body
	podLogs, err := req.Stream(context.TODO())
	if err != nil {
    
    
		logger.Error("更新Pod失败," + err.Error())
		return "", errors.New("更新Pod失败," + err.Error())
	}
	defer podLogs.Close()
	// 将Response.body 写入到缓存区,目的为了转换成string类型
	buf := new(bytes.Buffer)
	_, err = io.Copy(buf, podLogs)
	if err != nil {
    
    
		logger.Error("复制podLog失败," + err.Error())
		return "", errors.New("复制podLog失败," + err.Error())
	}
	return buf.String(), nil
}

5.2.9 获取每个namespace中pod数量

// 获取每个namespace中pod的数量
func(p *pod) GetPodNumPerNp() (podsNps []*PodsNp, err error) {
    
    
	//获取namespace列表
	namespaceList, err := K8s.ClientSet.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{
    
    })
	if err != nil {
    
    
		return nil, err
	}
	for _, namespace := range namespaceList.Items {
    
    
		//获取pod列表
		podList, err := K8s.ClientSet.CoreV1().Pods(namespace.Name).List(context.TODO(), metav1.ListOptions{
    
    })
		if err != nil {
    
    
			return nil, err
		}
		//组装数据
		podsNp := &PodsNp{
    
    
			Namespace: namespace.Name,
			PodNum:    len(podList.Items),
		}
		//添加到podsNps数组中
		podsNps = append(podsNps, podsNp)
	}
	return podsNps, nil
}

5.2.10 获取pod详情

5.2.10.1 获取pod详情

controller/pod.go

// 获取pod详情
func (p *pod) GetPodDetail(ctx *gin.Context) {
    
    
	// 处理入参
	// 匿名结构体用于定义入参,get请求为form格式,其他为json格式
	params := new(struct {
    
    
		PodName   string `form:"pod_name"`
		Namespace string `form:"namespace"`
	})
	// form 格式使用Bind方法,json格式使用ShouldBindJson方法
	if err := ctx.Bind(params); err != nil {
    
    
		logger.Error("Bind绑定参数失败," + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  "Bind绑定参数失败," + err.Error(),
			"data": nil,
		})
		return
	}
	data, err := service.Pod.GetPodDetail(params.PodName, params.Namespace)
	if err != nil {
    
    
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
    
    
		"msg":  "获取Pod列表成功",
		"data": data,
	})
}

5.2.10.2 路由配置

controller/router.go

type router struct{
    
    }

func (r *router) InitApiRouter(router *gin.Engine) {
    
    
	router.
		GET("/api/k8s/pods", Pod.GetPods).
		GET("/api/k8s/pods/detail", Pod.GetPodDetail).
		POST("/api/k8s/pods", Pod.DeletePod)
}

5.2.11 关于Pod其他功能

  1. 删除Pod
  2. 更新pod
  3. 获取pod容器
  4. 获取pod中容器日志
  5. 获取每个namespace的pod数量
// 删除Pod
func (p *pod) DeletePod(ctx *gin.Context) {
    
    
	// 处理入参
	// 匿名结构体用于定义入参,get请求为form格式,其他为json格式
	params := new(struct {
    
    
		PodName   string `json:"pod_name"`
		Namespace string `json:"namespace"`
	})
	// form 格式使用Bind方法,json格式使用ShouldBindJson方法
	if err := ctx.ShouldBindJSON(params); err != nil {
    
    
		logger.Error("Bind绑定参数失败," + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  "Bind绑定参数失败," + err.Error(),
			"data": nil,
		})
		return
	}
	err := service.Pod.DeletePod(params.PodName, params.Namespace)
	if err != nil {
    
    
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
    
    
		"msg": "删除Pod成功",
	})
}

// 更新pod
func (p *pod) UpdatePod(ctx *gin.Context) {
    
    
	params := new(struct {
    
    
		PodName   string `json:"pod_name"`
		Namespace string `json:"namespace"`
		Content   string `json:"content"`
	})
	//PUT请求,绑定参数方法改为ctx.ShouldBindJSON
	if err := ctx.ShouldBindJSON(params); err != nil {
    
    
		logger.Error("Bind请求参数失败, " + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	err := service.Pod.UpdatePod(params.PodName, params.Namespace, params.Content)
	if err != nil {
    
    
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
    
    
		"msg":  "更新Pod成功",
		"data": nil,
	})
}

// 获取pod容器
func (p *pod) GetPodContainer(ctx *gin.Context) {
    
    
	params := new(struct {
    
    
		PodName   string `form:"pod_name"`
		Namespace string `form:"namespace"`
	})
	//GET请求,绑定参数方法改为ctx.Bind
	if err := ctx.Bind(params); err != nil {
    
    
		logger.Error("Bind请求参数失败, " + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	data, err := service.Pod.GetPodContainer(params.PodName, params.Namespace)
	if err != nil {
    
    
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
    
    
		"msg":  "获取Pod容器成功",
		"data": data,
	})
}

// 获取pod中容器日志
func (p *pod) GetPodLog(ctx *gin.Context) {
    
    
	params := new(struct {
    
    
		ContainerName string `form:"container_name"`
		PodName       string `form:"pod_name"`
		Namespace     string `form:"namespace"`
	})
	//GET请求,绑定参数方法改为ctx.Bind
	if err := ctx.Bind(params); err != nil {
    
    
		logger.Error("Bind请求参数失败, " + err.Error())
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	data, err := service.Pod.GetPodLog(params.ContainerName, params.PodName, params.Namespace)
	if err != nil {
    
    
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
    
    
		"msg":  "获取Pod中容器日志成功",
		"data": data,
	})
}

// 获取每个namespace的pod数量
func (p *pod) GetPodNumPerNp(ctx *gin.Context) {
    
    
	data, err := service.Pod.GetPodNumPerNp()
	if err != nil {
    
    
		ctx.JSON(http.StatusInternalServerError, gin.H{
    
    
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
    
    
		"msg":  "获取每个namespace的pod数量成功",
		"data": data,
	})
}

5.2.12 定义路由

type router struct{
    
    }

func (r *router) InitApiRouter(router *gin.Engine) {
    
    
	router.
		GET("/api/k8s/pods", Pod.GetPods).
		GET("/api/k8s/pods/detail", Pod.GetPodDetail).
		POST("/api/k8s/pods", Pod.DeletePod).
		DELETE("/api/k8s/pod/del", Pod.DeletePod).
		PUT("/api/k8s/pod/update", Pod.UpdatePod).
		GET("/api/k8s/pod/container", Pod.GetPodContainer).
		GET("/api/k8s/pod/log", Pod.GetPodLog).
		GET("/api/k8s/pod/numnp", Pod.GetPodNumPerNp)
}

5.2.13 测试

依次测试以下端口

		GET("/api/k8s/pods/detail", Pod.GetPodDetail).
		POST("/api/k8s/pods", Pod.DeletePod).
		DELETE("/api/k8s/pod/del", Pod.DeletePod).
		PUT("/api/k8s/pod/update", Pod.UpdatePod).
		GET("/api/k8s/pod/container", Pod.GetPodContainer).
		GET("/api/k8s/pod/log", Pod.GetPodLog).
		GET("/api/k8s/pod/numnp", Pod.GetPodNumPerNp)

5.2.13.1 GetPodDetail

/api/k8s/pods/detail

请添加图片描述

5.2.13.2 DeletePod

/api/k8s/pods

# kubectl get pods
NAME                                        READY   STATUS    RESTARTS         AGE
centos7                                     2/2     Running   0                19d
el-gitlab-event-listener-75497dbb79-kpjmj   2/2     Running   19 (8d ago)      19d
el-s2i-listener-7c78cc48c-tvtpq             2/2     Running   18 (4m25s ago)   19d
sleep-557747455f-mvgbb                      2/2     Running   4 (19d ago)      19d

请添加图片描述

虽然还是3个pod但明显sleep-557747455f-l5hrg deployment是刚创建的.

# kubectl get pods
NAME                                        READY   STATUS    RESTARTS         AGE
centos7                                     2/2     Running   0                19d
el-gitlab-event-listener-75497dbb79-kpjmj   2/2     Running   19 (8d ago)      19d
el-s2i-listener-7c78cc48c-tvtpq             2/2     Running   18 (8m20s ago)   19d
sleep-557747455f-l5hrg                      2/2     Running   0                20s
# kubectl get deployments.apps 
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
el-gitlab-event-listener   1/1     1            1           19d
el-s2i-listener            1/1     1            1           19d
sleep                      1/1     1            1           19d

5.2.13.3 DeletePod

/api/k8s/pod/del

# kubectl get pods
NAME                                        READY   STATUS    RESTARTS         AGE
centos7                                     2/2     Running   0                19d
el-gitlab-event-listener-75497dbb79-kpjmj   2/2     Running   19 (8d ago)      19d
el-s2i-listener-7c78cc48c-tvtpq             2/2     Running   18 (8m20s ago)   19d
sleep-557747455f-l5hrg                      2/2     Running   0                20s

请添加图片描述

这里明显可以看到centos7这个pod被删除了

# kubectl get pods
NAME                                        READY   STATUS        RESTARTS       AGE
centos7                                     2/2     Terminating   0              19d
el-gitlab-event-listener-75497dbb79-kpjmj   2/2     Running       19 (8d ago)    19d
el-s2i-listener-7c78cc48c-tvtpq             2/2     Running       18 (12m ago)   19d
sleep-557747455f-6zcpj                      2/2     Running       0              82s
# kubectl get pods
NAME                                        READY   STATUS    RESTARTS       AGE
el-gitlab-event-listener-75497dbb79-kpjmj   2/2     Running   19 (8d ago)    19d
el-s2i-listener-7c78cc48c-tvtpq             2/2     Running   18 (13m ago)   19d
sleep-557747455f-6zcpj                      2/2     Running   0              108s

5.2.13.4 UpdatePod

/api/k8s/pod/update

先去获得一段json

请添加图片描述

将内容复制处理来略做改动

请添加图片描述

再次请求就可以看到这个新追加的test label

请添加图片描述

5.2.13.5 GetPodContainer

/api/k8s/pod/container

# kubectl describe pods  spring-boot-helloworld-5f77c6ff9f-k8z6v -n hello 
Name:         spring-boot-helloworld-5f77c6ff9f-k8z6v
Namespace:    hello
Priority:     0
Node:         192.168.31.111/192.168.31.111
Start Time:   Wed, 23 Nov 2022 11:00:31 +0800
Labels:       app=spring-boot-helloworld
              pod-template-hash=5f77c6ff9f
Annotations:  <none>
Status:       Running
IP:           172.100.109.74
IPs:
  IP:           172.100.109.74
Controlled By:  ReplicaSet/spring-boot-helloworld-5f77c6ff9f
Containers:
  spring-boot-helloworld:
    Container ID:   docker://1f692a565ff4c94cb811bfb5b3ac9c624841f3527bb703d269566f73f11a365f
    Image:          kurtqiu1979/spring:v0.9-20221118-081546
    Image ID:       docker-pullable://kurtqiu1979/spring@sha256:03b555ee834e27d03743ce221af839e6b81ff868bb23526c6d94501921354549
    Port:           80/TCP

得到的信息和命令行是相符的

请添加图片描述

5.2.13.6 GetPodLog

/api/k8s/pod/log

请添加图片描述

5.2.13.7 GetPodNumPerNp(命名空间pod数量)

/api/k8s/pod/numnp

这个不需要传参,直接返回所有命名空间pod的数量

请添加图片描述

猜你喜欢

转载自blog.csdn.net/qq_29974229/article/details/128328216