当前位置:

GO K8s 管理系统项目2[API部分--Deployment]

访客 2024-04-25 1412 0

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

1.实现接口

service/dataselector.go

packageserviceimport("sort""strings""time"appsv1"k8s.io/api/apps/v1"corev1"k8s.io/api/core/v1")//dataselector用于排序,过滤,分页的数据类型typedataSelectorstruct{GenericDataList[]DataCellDataSelect*DataSelectQuery}//DataCell接口,用于各种资源List的类型转换,转换后可以使用dataselector的排序,过滤,分页方法typeDataCellinterface{GetCreation()time.TimeGetName()string}//DataSelectQuery定义过滤和分页的结构体,过滤:Name分页:Limit和PagetypeDataSelectQuerystruct{Filter*FilterQueryPaginate*PaginateQuery}//FilterQuery用于查询过滤:NametypeFilterQuerystruct{Namestring}//分页:Limit和PageLimit是单页的数据条数,Page是第几页typePaginateQuerystruct{PageintLimitint}//实现自定义的排序方法,需要重写Len,Swap,Less方法//Len用于获取数组的长度func(d*dataSelector)Len()int{returnlen(d.GenericDataList)}//Swap用于数据比较大小后的位置变更func(d*dataSelector)Swap(i,jint){d.GenericDataList[i],d.GenericDataList[j]=d.GenericDataList[j],d.GenericDataList[i]}//Less用于比较大小func(d*dataSelector)Less(i,jint)bool{returnd.GenericDataList[i].GetCreation().Before(d.GenericDataList[j].GetCreation())}//重写以上三个方法,用sort.Sort方法触发排序func(d*dataSelector)Sort()*dataSelector{sort.Sort(d)returnd}//Filter方法用于过滤,比较数据Name属性,若包含则返回func(d*dataSelector)Filter()*dataSelector{ifd.DataSelect.Filter.Name==""{returnd}filtered:=[]DataCell{}for_,value:=ranged.GenericDataList{//定义是否匹配的标签变量,默认是匹配的matches:=trueobjName:=value.GetName()if!strings.Contains(objName,d.DataSelect.Filter.Name){matches=falsecontinue}ifmatches{filtered=append(filtered,value)}}d.GenericDataList=filteredreturnd}//Paginate分页,根据Limit和Page的传参,取一定范围内的数据返回func(d*dataSelector)Paginate()*dataSelector{limit:=d.DataSelect.Paginate.Limitpage:=d.DataSelect.Paginate.Page//验证参数合法,若参数不合法,则返回所有数据iflimit<=0||page<=0{returnd}//举例:25个元素的数组,limit是10,page是3,startIndex是20,endIndex是30(实际上endIndex是25)startIndex:=limit*(page-1)endIndex:=limit*page//处理最后一页,这时候就把endIndex由30改为25了iflen(d.GenericDataList)<endIndex{endIndex=len(d.GenericDataList)}d.GenericDataList=d.GenericDataList[startIndex:endIndex]returnd}//定义podCell,重写GetCreation和GetName方法后,可以进行数据转换//covev1.Pod-->podCell-->DataCell//appsv1.Deployment-->deployCell-->DataCelltypepodCellcorev1.Pod//重写DataCell接口的两个方法func(ppodCell)GetCreation()time.Time{returnp.CreationTimestamp.Time}func(ppodCell)GetName()string{returnp.Name}//deployCelltypedeploymentCellappsv1.Deploymentfunc(ddeploymentCell)GetCreation()time.Time{returnd.CreationTimestamp.Time}func(ddeploymentCell)GetName()string{returnd.Name}

2.Deployment功能

service/deployment.go

  1. 列表
  2. 获取Deployment详情
  3. 修改Deployment副本数
  4. 创建Deployment
  5. 删除Deployment
  6. 重启Deployment
  7. 更新Deployment
  8. 获取每个namespace的Deployment数量

2.1from和to方法

func(d*deployment)toCells(std[]appsv1.Deployment)[]DataCell{cells:=make([]DataCell,len(std))fori:=rangestd{cells[i]=deploymentCell(std[i])}returncells}func(d*deployment)fromCells(cells[]DataCell)[]appsv1.Deployment{deployments:=make([]appsv1.Deployment,len(cells))fori:=rangecells{deployments[i]=appsv1.Deployment(cells[i].(deploymentCell))}returndeployments}

2.2获取deployment副本数

//设置deployment副本数func(d*deployment)ScaleDeployment(deploymentName,namespacestring,scaleNumint)(replicaint32,errerror){//获取autoscalingv1.Scale类型的对象,能点出当前的副本数scale,err:=K8s.ClientSet.AppsV1().Deployments(namespace).GetScale(context.TODO(),deploymentName,metav1.GetOptions{})iferr!=nil{logger.Error(errors.New("获取Deployment副本数信息失败,"err.Error()))return0,errors.New("获取Deployment副本数信息失败,"err.Error())}//修改副本数scale.Spec.Replicas=int32(scaleNum)//更新副本数,传入scale对象newScale,err:=K8s.ClientSet.AppsV1().Deployments(namespace).UpdateScale(context.TODO(),deploymentName,scale,metav1.UpdateOptions{})iferr!=nil{logger.Error(errors.New("更新Deployment副本数信息失败,"err.Error()))return0,errors.New("更新Deployment副本数信息失败,"err.Error())}returnnewScale.Spec.Replicas,nil}

2.3创建deployment

//创建deployment,接收DeployCreate对象func(d*deployment)CreateDeployment(data*DeployCreate)(errerror){//将data中的属性组装成appsv1.Deployment对象,并将入参数据放入deployment:=&appsv1.Deployment{//ObjectMeta中定义资源名、命名空间以及标签ObjectMeta:metav1.ObjectMeta{Name:data.Name,Namespace:data.Namespace,Labels:data.Label,},//Spec中定义副本数、选择器、以及pod属性Spec:appsv1.DeploymentSpec{Replicas:&data.Replicas,Selector:&metav1.LabelSelector{MatchLabels:data.Label,},Template:corev1.PodTemplateSpec{//定义pod名和标签ObjectMeta:metav1.ObjectMeta{Name:data.Name,Labels:data.Label,},//定义容器名、镜像和端口Spec:corev1.PodSpec{Containers:[]corev1.Container{{Name:data.Name,Image:data.Image,Ports:[]corev1.ContainerPort{{Name:"http",Protocol:corev1.ProtocolTCP,ContainerPort:data.ContainerPort,},},},},},},},//Status定义资源的运行状态,这里由于是新建,传入空的appsv1.DeploymentStatus{}对象即可Status:appsv1.DeploymentStatus{},}//判断是否打开健康检查功能,若打开,则定义ReadinessProbe和LivenessProbeifdata.HealthCheck{//设置第一个容器的ReadinessProbe,因为我们pod中只有一个容器,所以直接使用index0即可//若pod中有多个容器,则这里需要使用for循环去定义了deployment.Spec.Template.Spec.Containers[0].ReadinessProbe=&corev1.Probe{ProbeHandler:corev1.ProbeHandler{HTTPGet:&corev1.HTTPGetAction{Path:data.HealthPath,//intstr.IntOrString的作用是端口可以定义为整型,也可以定义为字符串//Type=0则表示表示该结构体实例内的数据为整型,转json时只使用IntVal的数据//Type=1则表示表示该结构体实例内的数据为字符串,转json时只使用StrVal的数据Port:intstr.IntOrString{Type:0,IntVal:data.ContainerPort,},},},//初始化等待时间InitialDelaySeconds:5,//超时时间TimeoutSeconds:5,//执行间隔PeriodSeconds:5,}deployment.Spec.Template.Spec.Containers[0].LivenessProbe=&corev1.Probe{ProbeHandler:corev1.ProbeHandler{HTTPGet:&corev1.HTTPGetAction{Path:data.HealthPath,Port:intstr.IntOrString{Type:0,IntVal:data.ContainerPort,},},},InitialDelaySeconds:15,TimeoutSeconds:5,PeriodSeconds:5,}//定义容器的limit和request资源deployment.Spec.Template.Spec.Containers[0].Resources.Limits=map[corev1.ResourceName]resource.Quantity{corev1.ResourceCPU:resource.MustParse(data.Cpu),corev1.ResourceMemory:resource.MustParse(data.Memory),}deployment.Spec.Template.Spec.Containers[0].Resources.Requests=map[corev1.ResourceName]resource.Quantity{corev1.ResourceCPU:resource.MustParse(data.Cpu),corev1.ResourceMemory:resource.MustParse(data.Memory),}}//调用sdk创建deployment_,err=K8s.ClientSet.AppsV1().Deployments(data.Namespace).Create(context.TODO(),deployment,metav1.CreateOptions{})iferr!=nil{logger.Error(errors.New("创建Deployment失败,"err.Error()))returnerrors.New("创建Deployment失败,"err.Error())}returnnil}

2.4删除Deployment

//删除deploymentfunc(d*deployment)DeleteDeployment(deploymentName,namespacestring)(errerror){err=K8s.ClientSet.AppsV1().Deployments(namespace).Delete(context.TODO(),deploymentName,metav1.DeleteOptions{})iferr!=nil{logger.Error(errors.New("删除Deployment失败,"err.Error()))returnerrors.New("删除Deployment失败,"err.Error())}returnnil}

2.5重启deployment

//重启deploymentfunc(d*deployment)RestartDeployment(deploymentName,namespacestring)(errerror){//此功能等同于一下kubectl命令//kubectldeployment${service}-p\//'{"spec":{"template":{"spec":{"containers":[{"name":"'"${service}"'","env":[{"name":"RESTART_","value":"'$(date%s)'"}]}]}}}}'//使用patchDataMap组装数据patchData:=map[string]interface{}{"spec":map[string]interface{}{"template":map[string]interface{}{"spec":map[string]interface{}{"containers":[]map[string]interface{}{{"name":deploymentName,"env":[]map[string]string{{"name":"RESTART_","value":strconv.FormatInt(time.Now().Unix(),10),}},},},},},},}//序列化为字节,因为patch方法只接收字节类型参数patchByte,err:=json.Marshal(patchData)iferr!=nil{logger.Error(errors.New("json序列化失败,"err.Error()))returnerrors.New("json序列化失败,"err.Error())}//调用patch方法更新deployment_,err=K8s.ClientSet.AppsV1().Deployments(namespace).Patch(context.TODO(),deploymentName,"application/strategic-merge-patchjson",patchByte,metav1.PatchOptions{})iferr!=nil{logger.Error(errors.New("重启Deployment失败,"err.Error()))returnerrors.New("重启Deployment失败,"err.Error())}returnnil}

2.6更新deployment

//更新deploymentfunc(d*deployment)UpdateDeployment(namespace,contentstring)(errerror){vardeploy=&appsv1.Deployment{}err=json.Unmarshal([]byte(content),deploy)iferr!=nil{logger.Error(errors.New("反序列化失败,"err.Error()))returnerrors.New("反序列化失败,"err.Error())}_,err=K8s.ClientSet.AppsV1().Deployments(namespace).Update(context.TODO(),deploy,metav1.UpdateOptions{})iferr!=nil{logger.Error(errors.New("更新Deployment失败,"err.Error()))returnerrors.New("更新Deployment失败,"err.Error())}returnnil}

2.7获取所有Namespace中Deployment数量

//获取每个namespace的deployment数量func(d*deployment)GetDeployNumPerNp()(deploysNps[]*DeploysNp,errerror){namespaceList,err:=K8s.ClientSet.CoreV1().Namespaces().List(context.TODO(),metav1.ListOptions{})iferr!=nil{returnnil,err}for_,namespace:=rangenamespaceList.Items{deploymentList,err:=K8s.ClientSet.AppsV1().Deployments(namespace.Name).List(context.TODO(),metav1.ListOptions{})iferr!=nil{returnnil,err}deploysNp:=&DeploysNp{Namespace:namespace.Name,DeployNum:len(deploymentList.Items),}deploysNps=append(deploysNps,deploysNp)}returndeploysNps,nil}

2.8整个deployment

service/deployment.go

packageserviceimport("context""encoding/json""errors""strconv""time""github.com/wonderivan/logger"appsv1"k8s.io/api/apps/v1"corev1"k8s.io/api/core/v1""k8s.io/apimachinery/pkg/api/resource"metav1"k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/apimachinery/pkg/util/intstr")varDeploymentdeploymenttypedeploymentstruct{}//定义列表的返回内容,Items是deployment元素列表,Total为deployment元素数量typeDeploymentsRespstruct{Items[]appsv1.Deployment`json:"items"`Totalint`json:"total"`}//定义DeployCreate结构体,用于创建deployment需要的参数属性的定义typeDeployCreatestruct{Namestring`json:"name"`Namespacestring`json:"namespace"`Replicasint32`json:"replicas"`Imagestring`json:"image"`Labelmap[string]string`json:"label"`Cpustring`json:"cpu"`Memorystring`json:"memory"`ContainerPortint32`json:"container_port"`HealthCheckbool`json:"health_check"`HealthPathstring`json:"health_path"`}//定义DeploysNp类型,用于返回namespace中deployment的数量typeDeploysNpstruct{Namespacestring`json:"namespace"`DeployNumint`json:"deployment_num"`}//获取deployment列表,支持过滤、排序、分页func(d*deployment)GetDeployments(filterName,namespacestring,limit,pageint)(deploymentsResp*DeploymentsResp,errerror){//获取deploymentList类型的deployment列表deploymentList,err:=K8s.ClientSet.AppsV1().Deployments(namespace).List(context.TODO(),metav1.ListOptions{})iferr!=nil{logger.Error(errors.New("获取Deployment列表失败,"err.Error()))returnnil,errors.New("获取Deployment列表失败,"err.Error())}//将deploymentList中的deployment列表(Items),放进dataselector对象中,进行排序selectableData:=&dataSelector{GenericDataList:d.toCells(deploymentList.Items),DataSelect:&DataSelectQuery{Filter:&FilterQuery{Name:filterName},Paginate:&PaginateQuery{Limit:limit,Page:page,},},}filtered:=selectableData.Filter()total:=len(filtered.GenericDataList)data:=filtered.Sort().Paginate()//将[]DataCell类型的deployment列表转为appsv1.deployment列表deployments:=d.fromCells(data.GenericDataList)return&DeploymentsResp{Items:deployments,Total:total,},nil}//获取deployment详情func(d*deployment)GetDeploymentDetail(deploymentName,namespacestring)(deployment*appsv1.Deployment,errerror){deployment,err=K8s.ClientSet.AppsV1().Deployments(namespace).Get(context.TODO(),deploymentName,metav1.GetOptions{})iferr!=nil{logger.Error(errors.New("获取Deployment详情失败,"err.Error()))returnnil,errors.New("获取Deployment详情失败,"err.Error())}returndeployment,nil}//设置deployment副本数func(d*deployment)ScaleDeployment(deploymentName,namespacestring,scaleNumint)(replicaint32,errerror){//获取autoscalingv1.Scale类型的对象,能点出当前的副本数scale,err:=K8s.ClientSet.AppsV1().Deployments(namespace).GetScale(context.TODO(),deploymentName,metav1.GetOptions{})iferr!=nil{logger.Error(errors.New("获取Deployment副本数信息失败,"err.Error()))return0,errors.New("获取Deployment副本数信息失败,"err.Error())}//修改副本数scale.Spec.Replicas=int32(scaleNum)//更新副本数,传入scale对象newScale,err:=K8s.ClientSet.AppsV1().Deployments(namespace).UpdateScale(context.TODO(),deploymentName,scale,metav1.UpdateOptions{})iferr!=nil{logger.Error(errors.New("更新Deployment副本数信息失败,"err.Error()))return0,errors.New("更新Deployment副本数信息失败,"err.Error())}returnnewScale.Spec.Replicas,nil}//创建deployment,接收DeployCreate对象func(d*deployment)CreateDeployment(data*DeployCreate)(errerror){//将data中的属性组装成appsv1.Deployment对象,并将入参数据放入deployment:=&appsv1.Deployment{//ObjectMeta中定义资源名、命名空间以及标签ObjectMeta:metav1.ObjectMeta{Name:data.Name,Namespace:data.Namespace,Labels:data.Label,},//Spec中定义副本数、选择器、以及pod属性Spec:appsv1.DeploymentSpec{Replicas:&data.Replicas,Selector:&metav1.LabelSelector{MatchLabels:data.Label,},Template:corev1.PodTemplateSpec{//定义pod名和标签ObjectMeta:metav1.ObjectMeta{Name:data.Name,Labels:data.Label,},//定义容器名、镜像和端口Spec:corev1.PodSpec{Containers:[]corev1.Container{{Name:data.Name,Image:data.Image,Ports:[]corev1.ContainerPort{{Name:"http",Protocol:corev1.ProtocolTCP,ContainerPort:data.ContainerPort,},},},},},},},//Status定义资源的运行状态,这里由于是新建,传入空的appsv1.DeploymentStatus{}对象即可Status:appsv1.DeploymentStatus{},}//判断是否打开健康检查功能,若打开,则定义ReadinessProbe和LivenessProbeifdata.HealthCheck{//设置第一个容器的ReadinessProbe,因为我们pod中只有一个容器,所以直接使用index0即可//若pod中有多个容器,则这里需要使用for循环去定义了deployment.Spec.Template.Spec.Containers[0].ReadinessProbe=&corev1.Probe{ProbeHandler:corev1.ProbeHandler{HTTPGet:&corev1.HTTPGetAction{Path:data.HealthPath,//intstr.IntOrString的作用是端口可以定义为整型,也可以定义为字符串//Type=0则表示表示该结构体实例内的数据为整型,转json时只使用IntVal的数据//Type=1则表示表示该结构体实例内的数据为字符串,转json时只使用StrVal的数据Port:intstr.IntOrString{Type:0,IntVal:data.ContainerPort,},},},//初始化等待时间InitialDelaySeconds:5,//超时时间TimeoutSeconds:5,//执行间隔PeriodSeconds:5,}deployment.Spec.Template.Spec.Containers[0].LivenessProbe=&corev1.Probe{ProbeHandler:corev1.ProbeHandler{HTTPGet:&corev1.HTTPGetAction{Path:data.HealthPath,Port:intstr.IntOrString{Type:0,IntVal:data.ContainerPort,},},},InitialDelaySeconds:15,TimeoutSeconds:5,PeriodSeconds:5,}//定义容器的limit和request资源deployment.Spec.Template.Spec.Containers[0].Resources.Limits=map[corev1.ResourceName]resource.Quantity{corev1.ResourceCPU:resource.MustParse(data.Cpu),corev1.ResourceMemory:resource.MustParse(data.Memory),}deployment.Spec.Template.Spec.Containers[0].Resources.Requests=map[corev1.ResourceName]resource.Quantity{corev1.ResourceCPU:resource.MustParse(data.Cpu),corev1.ResourceMemory:resource.MustParse(data.Memory),}}//调用sdk创建deployment_,err=K8s.ClientSet.AppsV1().Deployments(data.Namespace).Create(context.TODO(),deployment,metav1.CreateOptions{})iferr!=nil{logger.Error(errors.New("创建Deployment失败,"err.Error()))returnerrors.New("创建Deployment失败,"err.Error())}returnnil}//删除deploymentfunc(d*deployment)DeleteDeployment(deploymentName,namespacestring)(errerror){err=K8s.ClientSet.AppsV1().Deployments(namespace).Delete(context.TODO(),deploymentName,metav1.DeleteOptions{})iferr!=nil{logger.Error(errors.New("删除Deployment失败,"err.Error()))returnerrors.New("删除Deployment失败,"err.Error())}returnnil}//重启deploymentfunc(d*deployment)RestartDeployment(deploymentName,namespacestring)(errerror){//此功能等同于一下kubectl命令//kubectldeployment${service}-p\//'{"spec":{"template":{"spec":{"containers":[{"name":"'"${service}"'","env":[{"name":"RESTART_","value":"'$(date%s)'"}]}]}}}}'//使用patchDataMap组装数据patchData:=map[string]interface{}{"spec":map[string]interface{}{"template":map[string]interface{}{"spec":map[string]interface{}{"containers":[]map[string]interface{}{{"name":deploymentName,"env":[]map[string]string{{"name":"RESTART_","value":strconv.FormatInt(time.Now().Unix(),10),}},},},},},},}//序列化为字节,因为patch方法只接收字节类型参数patchByte,err:=json.Marshal(patchData)iferr!=nil{logger.Error(errors.New("json序列化失败,"err.Error()))returnerrors.New("json序列化失败,"err.Error())}//调用patch方法更新deployment_,err=K8s.ClientSet.AppsV1().Deployments(namespace).Patch(context.TODO(),deploymentName,"application/strategic-merge-patchjson",patchByte,metav1.PatchOptions{})iferr!=nil{logger.Error(errors.New("重启Deployment失败,"err.Error()))returnerrors.New("重启Deployment失败,"err.Error())}returnnil}//更新deploymentfunc(d*deployment)UpdateDeployment(namespace,contentstring)(errerror){vardeploy=&appsv1.Deployment{}err=json.Unmarshal([]byte(content),deploy)iferr!=nil{logger.Error(errors.New("反序列化失败,"err.Error()))returnerrors.New("反序列化失败,"err.Error())}_,err=K8s.ClientSet.AppsV1().Deployments(namespace).Update(context.TODO(),deploy,metav1.UpdateOptions{})iferr!=nil{logger.Error(errors.New("更新Deployment失败,"err.Error()))returnerrors.New("更新Deployment失败,"err.Error())}returnnil}//获取每个namespace的deployment数量func(d*deployment)GetDeployNumPerNp()(deploysNps[]*DeploysNp,errerror){namespaceList,err:=K8s.ClientSet.CoreV1().Namespaces().List(context.TODO(),metav1.ListOptions{})iferr!=nil{returnnil,err}for_,namespace:=rangenamespaceList.Items{deploymentList,err:=K8s.ClientSet.AppsV1().Deployments(namespace.Name).List(context.TODO(),metav1.ListOptions{})iferr!=nil{returnnil,err}deploysNp:=&DeploysNp{Namespace:namespace.Name,DeployNum:len(deploymentList.Items),}deploysNps=append(deploysNps,deploysNp)}returndeploysNps,nil}func(d*deployment)toCells(std[]appsv1.Deployment)[]DataCell{cells:=make([]DataCell,len(std))fori:=rangestd{cells[i]=deploymentCell(std[i])}returncells}func(d*deployment)fromCells(cells[]DataCell)[]appsv1.Deployment{deployments:=make([]appsv1.Deployment,len(cells))fori:=rangecells{deployments[i]=appsv1.Deployment(cells[i].(deploymentCell))}returndeployments}

3.获取Deployment列表

controller/deployment.go

packagecontrollerimport("fmt""k8s-plantform/service""net/http""github.com/gin-gonic/gin""github.com/wonderivan/logger")varDeploymentdeploymenttypedeploymentstruct{}//获取deployment列表,支持过滤、排序、分页func(d*deployment)GetDeployments(ctx*gin.Context){params:=new(struct{FilterNamestring`form:"filter_name"`Namespacestring`form:"namespace"`Pageint`form:"page"`Limitint`form:"limit"`})iferr:=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.Deployment.GetDeployments(params.FilterName,params.Namespace,params.Limit,params.Page)iferr!=nil{ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}ctx.JSON(http.StatusOK,gin.H{"msg":"获取Deployment列表成功","data":data,})}//获取deployment详情func(d*deployment)GetDeploymentDetail(ctx*gin.Context){params:=new(struct{DeploymentNamestring`form:"deployment_name"`Namespacestring`form:"namespace"`})iferr:=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.Deployment.GetDeploymentDetail(params.DeploymentName,params.Namespace)iferr!=nil{ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}ctx.JSON(http.StatusOK,gin.H{"msg":"获取Deployment详情成功","data":data,})}//创建deploymentfunc(d*deployment)CreateDeployment(ctx*gin.Context){var(deployCreate=new(service.DeployCreate)errerror)iferr=ctx.ShouldBindJSON(deployCreate);err!=nil{logger.Error("Bind请求参数失败,"err.Error())ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}iferr=service.Deployment.CreateDeployment(deployCreate);err!=nil{ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})}ctx.JSON(http.StatusOK,gin.H{"msg":"创建Deployment成功","data":nil,})}//设置deployment副本数func(d*deployment)ScaleDeployment(ctx*gin.Context){params:=new(struct{DeploymentNamestring`json:"deployment_name"`Namespacestring`json:"namespace"`ScaleNumint`json:"scale_num"`})//PUT请求,绑定参数方法改为ctx.ShouldBindJSONiferr:=ctx.ShouldBindJSON(params);err!=nil{logger.Error("Bind请求参数失败,"err.Error())ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}data,err:=service.Deployment.ScaleDeployment(params.DeploymentName,params.Namespace,params.ScaleNum)iferr!=nil{ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}ctx.JSON(http.StatusOK,gin.H{"msg":"设置Deployment副本数成功","data":fmt.Sprintf("最新副本数:%d",data),})}//删除deploymentfunc(d*deployment)DeleteDeployment(ctx*gin.Context){params:=new(struct{DeploymentNamestring`json:"deployment_name"`Namespacestring`json:"namespace"`})//DELETE请求,绑定参数方法改为ctx.ShouldBindJSONiferr:=ctx.ShouldBindJSON(params);err!=nil{logger.Error("Bind请求参数失败,"err.Error())ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}err:=service.Deployment.DeleteDeployment(params.DeploymentName,params.Namespace)iferr!=nil{ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}ctx.JSON(http.StatusOK,gin.H{"msg":"删除Deployment成功","data":nil,})}//重启deploymentfunc(d*deployment)RestartDeployment(ctx*gin.Context){params:=new(struct{DeploymentNamestring`json:"deployment_name"`Namespacestring`json:"namespace"`})//PUT请求,绑定参数方法改为ctx.ShouldBindJSONiferr:=ctx.ShouldBindJSON(params);err!=nil{logger.Error("Bind请求参数失败,"err.Error())ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}err:=service.Deployment.RestartDeployment(params.DeploymentName,params.Namespace)iferr!=nil{ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}ctx.JSON(http.StatusOK,gin.H{"msg":"重启Deployment成功","data":nil,})}//更新deploymentfunc(d*deployment)UpdateDeployment(ctx*gin.Context){params:=new(struct{Namespacestring`json:"namespace"`Contentstring`json:"content"`})//PUT请求,绑定参数方法改为ctx.ShouldBindJSONiferr:=ctx.ShouldBindJSON(params);err!=nil{logger.Error("Bind请求参数失败,"err.Error())ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}err:=service.Deployment.UpdateDeployment(params.Namespace,params.Content)iferr!=nil{ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}ctx.JSON(http.StatusOK,gin.H{"msg":"更新Deployment成功","data":nil,})}//获取每个namespace的pod数量func(d*deployment)GetDeployNumPerNp(ctx*gin.Context){data,err:=service.Deployment.GetDeployNumPerNp()iferr!=nil{ctx.JSON(http.StatusInternalServerError,gin.H{"msg":err.Error(),"data":nil,})return}ctx.JSON(http.StatusOK,gin.H{"msg":"获取每个namespace的deployment数量成功","data":data,})}

4.定义路由

controller/router.go

packagecontrollerimport("github.com/gin-gonic/gin")//初始化router类型的对象,首字母大写,用于跨包调用varRouterrouter//声明一个router的结构体typerouterstruct{}func(r*router)InitApiRouter(router*gin.Engine){router.//PodsGET("/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).//deployment操作GET("/api/k8s/deployments",Deployment.GetDeployments).GET("/api/k8s/deployment/detail",Deployment.GetDeploymentDetail).PUT("/api/k8s/deployment/scale",Deployment.ScaleDeployment).DELETE("/api/k8s/deployment/del",Deployment.DeleteDeployment).PUT("/api/k8s/deployment/restart",Deployment.RestartDeployment).PUT("/api/k8s/deployment/update",Deployment.UpdateDeployment).GET("/api/k8s/deployment/numnp",Deployment.GetDeployNumPerNp).POST("/api/k8s/deployment/create",Deployment.CreateDeployment)}

5.测试Deployment方法

5.1获取Deployment清单

/api/k8s/deployments

5.2获取Deployment清单详情

/api/k8s/deployment/detail

5.3修改Deployment副本数

/api/k8s/deployment/scaleroot@master-01:~/exam-CKA#kubectlgetdeployments.apps-ANAMESPACENAMEREADYUP-TO-DATEAVAILABLEAGEdefaultnginx-deployment3/3332d20hkube-systemcoredns0/2202d23hweworkwework-tomcat-app1-deployment1/1112d21hweworkwework-tomcat-app2-deployment1/1112d21h

root@master-01:~/exam-CKA#kubectlgetdeployments.appsNAMEREADYUP-TO-DATEAVAILABLEAGEnginx-deployment4/4442d20hroot@master-01:~/exam-CKA#kubectlgetpodsNAMEREADYSTATUSRESTARTSAGEnginx-deployment-66b6c48dd5-24grz1/1Running02d20hnginx-deployment-66b6c48dd5-cz6ql1/1Running031snginx-deployment-66b6c48dd5-gttz61/1Running02d20hnginx-deployment-66b6c48dd5-gxksp1/1Running02d20htest-pod11/1Running12d23htest-pod21/1Running12d23htest-pod31/1Running12d23htest-pod41/1Running12d23h

5.4创建Deployment

/api/k8s/deployment/createroot@master-01:~/exam-CKA#kubectlgetdeployments.appsNAMEREADYUP-TO-DATEAVAILABLEAGEnginx-deployment4/4442d20h

这个放到前端一起测

5.5删除Deployment

/api/k8s/deployment/delroot@master-01:~/exam-CKA/yaml#kubectlgetdeployments.apps-nk8sNAMEREADYUP-TO-DATEAVAILABLEAGEfront-end1/11111s

front-end这个deployment就被删除了

#kubectlgetdeployments.apps-nk8sNoresourcesfoundink8snamespace.

5.6重启Deployment

/api/k8s/deployment/restartroot@master-01:~/exam-CKA/yaml#kubectlgetdeployments.apps,podsNAMEREADYUP-TO-DATEAVAILABLEAGEdeployment.apps/nginx3/333115sNAMEREADYSTATUSRESTARTSAGEpod/nginx-64dd8946f7-7c6nj1/1Running063spod/nginx-64dd8946f7-8wp7f1/1Running067spod/nginx-64dd8946f7-9f9bn1/1Running065spod/test-pod11/1Running13dpod/test-pod21/1Running13dpod/test-pod31/1Running13dpod/test-pod41/1Running13d

这里可以看到pod已经被重启过了

root@master-01:~/exam-CKA/yaml#kubectlgetdeployments.apps,podsNAMEREADYUP-TO-DATEAVAILABLEAGEdeployment.apps/nginx3/3333m15sNAMEREADYSTATUSRESTARTSAGEpod/nginx-64f8cb6df4-5mtjg1/1Running017spod/nginx-64f8cb6df4-jkgtq1/1Running022spod/nginx-64f8cb6df4-qj9dj1/1Running019spod/test-pod11/1Running13dpod/test-pod21/1Running13dpod/test-pod31/1Running13dpod/test-pod41/1Running13d

5.7更新Deployment

/api/k8s/deployment/update

这个放到前端一起测.其实之前的restart已经实现了部分功能

5.8获取每个namespace的Deployment数量

/api/k8s/deployment/numnp

发表评论

  • 评论列表
还没有人评论,快来抢沙发吧~