【云原生开发】K8S集群调度资源deployment,daemonset,statefulset,cronjob,节点管理等开发设计与实现
✨✨ 欢迎大家来到景天科技苑✨✨
🎈🎈 养成好习惯,先赞后看哦~🎈🎈
🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。所属的专栏:云原生开发
景天的主页:景天科技苑
文章目录
- k8s调度资源管理开发设计与实现
- 1. Deployment的功能开发
- 2. Statefulset的功能开发
- 3. Daemonset的功能开发
- 4. cronjob功能开发
- 5. Replicaset功能实现
- 6. 实现节点管理
k8s调度资源管理开发设计与实现
在上一章,我们在做pod管理的开发后,对我们得接口进行了优化,后续我们对其他资源的操作,都采用接口的方式进行开发。本文我们就使用接口,开发k8s集群各个调度资源的管理。
1. Deployment的功能开发
我们直接将pod目录进行复制改成deployment,然后对代码稍加修改即可。
路由:
routers/deployment/deployment.go
package deployment
import (
"github.com/gin-gonic/gin"
"jingtian/krm-backend/controllers/deployment"
)
// 实现创建deployment的接口
func create(deploymentGroup *gin.RouterGroup) {
//具体逻辑写到控制器controller里面
deploymentGroup.POST("/create", deployment.Create)
}
// 实现更新deployment的接口
func update(deploymentGroup *gin.RouterGroup) {
//具体逻辑写到控制器controller里面
deploymentGroup.POST("/update", deployment.Update)
}
// 删除deployment
func deletedeployment(deploymentGroup *gin.RouterGroup) {
deploymentGroup.GET("/delete", deployment.Delete)
}
// 批量删除deployment
func deleteList(deploymentGroup *gin.RouterGroup) {
deploymentGroup.POST("/deleteList", deployment.DeleteList)
}
// 获取deployment信息
func get(deploymentGroup *gin.RouterGroup) {
deploymentGroup.GET("/get", deployment.Get)
}
// 列出所有deployment
func list(deploymentGroup *gin.RouterGroup) {
deploymentGroup.GET("/list", deployment.List)
}
// RegisterSubRouter 认证子路由
func RegisterSubRouter(g *gin.RouterGroup) {
//配置登录功能路由策略
deploymentGroup := g.Group("/deployment")
create(deploymentGroup)
update(deploymentGroup)
deletedeployment(deploymentGroup)
get(deploymentGroup)
list(deploymentGroup)
deleteList(deploymentGroup)
}
控制器
封装接口之后,我们再写代码就变得非常简单了,比如deployment/update.go
package deployment
import (
"github.com/gin-gonic/gin"
"github.com/littlefun91/kubeutils/kubeutils"
"jingtian/krm-backend/controllers"
"jingtian/krm-backend/utils/logs"
appsv1 "k8s.io/api/apps/v1"
)
func Update(c *gin.Context) {
logs.Debug(nil, "更新deployment")
//更新,只需要把create代码复制过来,将info中的create方法改成update方法即可
var deployment appsv1.Deployment
var info controllers.Info
info.Item = &deployment
kubeconfig := controllers.NewInfo(c, &info, "deployment更新成功")
// 改为接口形式的创建
var kubeUtilser kubeutils.KubeUtilser
instance := kubeutils.NewDeployment(kubeconfig, &deployment)
// 把实例复制给kubeUtilser
kubeUtilser = instance
// 使用kubeUtilser创建资源
info.Update(c, kubeUtilser)
}
测试deployment功能
我们在postman中将pod文件夹,复制一份,改名为deployment
将请求路径改为deployment
创建deployment:
我们使用kubectl create deployment --dry-run=client的方式生成创建deployment的json文件
kubectl create deployment myweb --image="web:v4" --dry-run=client -ojson
我们将json文件复制到postman,执行创建deployment操作
{
"kind": "Deployment",
"apiVersion": "apps/v1",
"metadata": {
"name": "myweb",
"creationTimestamp": null,
"labels": {
"app": "myweb"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app": "myweb"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"app": "myweb"
}
},
"spec": {
"containers": [
{
"name": "web",
"image": "web:v4",
"resources": {}
}
]
}
},
"strategy": {}
},
"status": {}
}
创建成功
在k8s集群查看,创建成功
更新deployment:
我们更新下deployment的annotations
{
"clusterId":"cluster01",
"namespace":"jingtian",
"item": {
"kind": "Deployment",
"apiVersion": "apps/v1",
"metadata": {
"name": "myweb",
"creationTimestamp": null,
"annotations":{
"kubeasy.com":"true"
},
"labels": {
"app": "myweb"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app": "myweb"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"app": "myweb"
}
},
"spec": {
"containers": [
{
"name": "web",
"image": "web:v4",
"resources": {}
}
]
}
},
"strategy": {}
},
"status": {}
}
}
集群中查看,更新成功
查看deployment列表:
再创建个deployment
postman发送查询请求
查询deployment详情:
删除deployment功能:
2. Statefulset的功能开发
与deployment管理的开发大致类似,都是先创建路由,然后开发控制器。
routers/statefulset.go
package statefulset
import (
"github.com/gin-gonic/gin"
"jingtian/krm-backend/controllers/statefulset"
)
// 实现创建statefulset的接口
func create(statefulsetGroup *gin.RouterGroup) {
//具体逻辑写到控制器controller里面
statefulsetGroup.POST("/create", statefulset.Create)
}
// 实现更新statefulset的接口
func update(statefulsetGroup *gin.RouterGroup) {
//具体逻辑写到控制器controller里面
statefulsetGroup.POST("/update", statefulset.Update)
}
// 删除statefulset
func deletestatefulset(statefulsetGroup *gin.RouterGroup) {
statefulsetGroup.GET("/delete", statefulset.Delete)
}
// 批量删除statefulset
func deleteList(statefulsetGroup *gin.RouterGroup) {
statefulsetGroup.POST("/deleteList", statefulset.DeleteList)
}
// 获取statefulset信息
func get(statefulsetGroup *gin.RouterGroup) {
statefulsetGroup.GET("/get", statefulset.Get)
}
// 列出所有statefulset
func list(statefulsetGroup *gin.RouterGroup) {
statefulsetGroup.GET("/list", statefulset.List)
}
// RegisterSubRouter 认证子路由
func RegisterSubRouter(g *gin.RouterGroup) {
//配置登录功能路由策略
statefulsetGroup := g.Group("/statefulset")
create(statefulsetGroup)
update(statefulsetGroup)
deletestatefulset(statefulsetGroup)
get(statefulsetGroup)
list(statefulsetGroup)
deleteList(statefulsetGroup)
}
注册总路由
控制器
创建statefulset和deployment有些不一样。
创建statefulset的时候,需要指定servicename。
需要看一下是否要自动创建headless service。这个功能我们在前后端交互时,我们再做
测试管理statefulset的可用性
创建sts
创建statefulset的时候,不能再用–dry-run=client生成json文件。因为kubectl create命令行没有生成statefulset的命令
我们需要通过yaml方式生成statefulset,然后导出json文件
{
"apiVersion": "apps/v1",
"kind": "StatefulSet",
"metadata": {
"name": "myweb",
"namespace": "jingtian",
},
"spec": {
"podManagementPolicy": "OrderedReady",
"replicas": 1,
"revisionHistoryLimit": 10,
"selector": {
"matchLabels": {
"app": "myweb"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"app": "myweb"
}
},
"spec": {
"containers": [
{
"image": "web:v4",
"imagePullPolicy": "IfNotPresent",
"name": "myweb"
}
],
"nodeSelector": {
"stateless": "yes"
},
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"terminationGracePeriodSeconds": 30
}
},
"updateStrategy": {
"rollingUpdate": {
"partition": 0
},
"type": "RollingUpdate"
}
}
}
k8s集群查看,statefunset创建成功
更新statefulset:
我们将updateStrategy下的partition改为2
集群中查看,修改成功
查看statefulset列表:
获取statefulset详情:
删除statefulset:
3. Daemonset的功能开发
类似的,复制,修改
先添加路由
routers/daemonset.go
package daemonset
import (
"github.com/gin-gonic/gin"
"jingtian/krm-backend/controllers/daemonset"
)
// 实现创建daemonset的接口
func create(daemonsetGroup *gin.RouterGroup) {
//具体逻辑写到控制器controller里面
daemonsetGroup.POST("/create", daemonset.Create)
}
// 实现更新daemonset的接口
func update(daemonsetGroup *gin.RouterGroup) {
//具体逻辑写到控制器controller里面
daemonsetGroup.POST("/update", daemonset.Update)
}
// 删除daemonset
func deletedaemonset(daemonsetGroup *gin.RouterGroup) {
daemonsetGroup.GET("/delete", daemonset.Delete)
}
// 批量删除daemonset
func deleteList(daemonsetGroup *gin.RouterGroup) {
daemonsetGroup.POST("/deleteList", daemonset.DeleteList)
}
// 获取daemonset信息
func get(daemonsetGroup *gin.RouterGroup) {
daemonsetGroup.GET("/get", daemonset.Get)
}
// 列出所有daemonset
func list(daemonsetGroup *gin.RouterGroup) {
daemonsetGroup.GET("/list", daemonset.List)
}
// RegisterSubRouter 认证子路由
func RegisterSubRouter(g *gin.RouterGroup) {
//配置登录功能路由策略
daemonsetGroup := g.Group("/daemonset")
create(daemonsetGroup)
update(daemonsetGroup)
deletedaemonset(daemonsetGroup)
get(daemonsetGroup)
list(daemonsetGroup)
deleteList(daemonsetGroup)
}
注册到总路由
控制器
controllers/daemonset
创建daemonset
{
"clusterId":"cluster01",
"namespace":"jingtian",
"item": {
"apiVersion": "apps/v1",
"kind": "DaemonSet",
"metadata": {
"labels": {
"name": "node-exporter"
},
"name": "node-exporter",
"namespace": "jingtian"
},
"spec": {
"revisionHistoryLimit": 10,
"selector": {
"matchLabels": {
"name": "node-exporter"
}
},
"template": {
"metadata": {
"labels": {
"name": "node-exporter"
}
},
"spec": {
"containers": [
{
"image": "web:v4",
"imagePullPolicy": "IfNotPresent",
"name":"webdaemonset"
}
],
"restartPolicy": "Always",
"terminationGracePeriodSeconds": 30,
"tolerations": [
{
"effect": "NoSchedule",
"key": "k8s-master",
"operator": "Equal",
"value": "null"
},
{
"effect": "NoExecute",
"key": "node-role.kubernetes.io/etcd",
"operator": "Equal",
"value": "true"
},
{
"effect": "NoSchedule",
"key": "nexus",
"operator": "Equal",
"value": "null"
},
{
"effect": "NoSchedule",
"key": "node-role.kubernetes.io/control-plane",
"operator": "Exists"
}
]
}
},
"updateStrategy": {
"rollingUpdate": {
"maxUnavailable": 1
},
"type": "RollingUpdate"
}
}
}
}
创建成功
更新daemonset:
我们将最大不可用改为2
集群查看,更新成功
查看daemonset列表
查看daemonset详情
删除daemonset
4. cronjob功能开发
路由routers/cronjob.go
package cronjob
import (
"github.com/gin-gonic/gin"
"jingtian/krm-backend/controllers/cronjob"
)
// 实现创建cronjob的接口
func create(cronjobGroup *gin.RouterGroup) {
//具体逻辑写到控制器controller里面
cronjobGroup.POST("/create", cronjob.Create)
}
// 实现更新cronjob的接口
func update(cronjobGroup *gin.RouterGroup) {
//具体逻辑写到控制器controller里面
cronjobGroup.POST("/update", cronjob.Update)
}
// 删除cronjob
func deletecronjob(cronjobGroup *gin.RouterGroup) {
cronjobGroup.GET("/delete", cronjob.Delete)
}
// 批量删除cronjob
func deleteList(cronjobGroup *gin.RouterGroup) {
cronjobGroup.POST("/deleteList", cronjob.DeleteList)
}
// 获取cronjob信息
func get(cronjobGroup *gin.RouterGroup) {
cronjobGroup.GET("/get", cronjob.Get)
}
// 列出所有cronjob
func list(cronjobGroup *gin.RouterGroup) {
cronjobGroup.GET("/list", cronjob.List)
}
// RegisterSubRouter 认证子路由
func RegisterSubRouter(g *gin.RouterGroup) {
//配置登录功能路由策略
cronjobGroup := g.Group("/cronjob")
create(cronjobGroup)
update(cronjobGroup)
deletecronjob(cronjobGroup)
get(cronjobGroup)
list(cronjobGroup)
deleteList(cronjobGroup)
}
注册总路由
控制器
创建cronjob:
我们通过kubectl create -h 查看哪些资源可以通过kubectl create命令行来创建
我们发现,cronjob是可以的,因此我们可以通过kubectl create --dry-run=client 来导出生成cronjob的json文件
我们可以通过 kubectl create cronjob -h 来查看通过命令行来创建cronjob的示例
kubectl create cronjob my-job --image=alphinewithlocaltime:v1 --schedule="*/1 * * * *" --dry-run=client -ojson
{
"clusterId":"cluster01",
"namespace":"jingtian",
"item": {
"kind": "CronJob",
"apiVersion": "batch/v1",
"metadata": {
"name": "my-job"
},
"spec": {
"schedule": "*/1 * * * *",
"jobTemplate": {
"metadata": {
"name": "my-job"
},
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "my-job",
"image": "alphinewithlocaltime:v1",
"resources": {}
}
],
"restartPolicy": "OnFailure"
}
}
}
}
},
"status": {}
}
}
集群查看,创建成功
修改cronjob:
我们将调度周期改为每五分钟调度一次
修改成功
查看cronjob列表
查询cronjob详情
删除cronjob
删除成功
5. Replicaset功能实现
我们在执行deployment回滚的时候,需要查询有哪些replicaset。因此,我们也需要对rs的操作管理进行开发实现。
我们一般不需要去更新或删除rs。只需要查询即可,因此需要有个查询列表和查询详情的功能
一样的,我们需要路由和控制器
routers/replicaset.go
package replicaset
import (
"github.com/gin-gonic/gin"
"jingtian/krm-backend/controllers/replicaset"
)
// 获取replicaset信息
func get(replicasetGroup *gin.RouterGroup) {
replicasetGroup.GET("/get", replicaset.Get)
}
// 列出所有replicaset
func list(replicasetGroup *gin.RouterGroup) {
replicasetGroup.GET("/list", replicaset.List)
}
// RegisterSubRouter 认证子路由
func RegisterSubRouter(g *gin.RouterGroup) {
//配置登录功能路由策略
replicasetGroup := g.Group("/replicaset")
get(replicasetGroup)
list(replicasetGroup)
}
注册到总路由
控制器
我们先看下jingtian命名空间下的rs
查询rs列表
查询rs详情
6. 实现节点管理
节点的功能和rs也是比较类似的,它也是去实现查询节点状态,节点详情。更新一些节点的标签,污点等操作。
路由
routers/node.go
package node
import (
"github.com/gin-gonic/gin"
"jingtian/krm-backend/controllers/node"
)
// 实现更新node的接口
func update(nodeGroup *gin.RouterGroup) {
//具体逻辑写到控制器controller里面
nodeGroup.POST("/update", node.Update)
}
// 获取node信息
func get(nodeGroup *gin.RouterGroup) {
nodeGroup.GET("/get", node.Get)
}
// 列出所有node
func list(nodeGroup *gin.RouterGroup) {
nodeGroup.GET("/list", node.List)
}
// RegisterSubRouter 认证子路由
func RegisterSubRouter(g *gin.RouterGroup) {
//配置登录功能路由策略
nodeGroup := g.Group("/node")
update(nodeGroup)
get(nodeGroup)
list(nodeGroup)
}
注册到总路由
node控制器
查看node列表
查询node详情
更新node标签或者注解
我们将查询节点详情里面item里面的json拿出来,其他的status等全部删除,对标签或注解稍作修改。
添加一个注解
{
"clusterId":"cluster01",
"name":"node01",
"item": {
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "node01",
"uid": "96bf47a9-15ac-4e09-929c-754ed361c890",
"resourceVersion": "2139695",
"creationTimestamp": "2024-06-20T08:33:12Z",
"labels": {
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "node01",
"kubernetes.io/os": "linux",
"node-role.kubernetes.io/worker": "true"
},
"annotations": {
"kubeadm.alpha.kubernetes.io/cri-socket": "unix:///var/run/containerd/containerd.sock",
"node.alpha.kubernetes.io/ttl": "0",
"projectcalico.org/IPv4Address": "10.10.0.11/24",
"projectcalico.org/IPv4IPIPTunnelAddr": "172.29.55.0",
"volumes.kubernetes.io/controller-managed-attach-detach": "true",
"jingtian":"true"
}
},
"spec": {
"podCIDR": "172.16.1.0/24",
"podCIDRs": [
"172.16.1.0/24"
]
}
}
}
集群查看,添加成功
添加标签
集群查看,添加成功
当然也可以删除注解,删除标签,添加删除污点等操作,感兴趣的朋友试试吧!