golangkubenetes容器多集群平台开发实践

author author     2022-12-04     218

关键词:

前言

   Go语言在基础服务开发领域优势

        Go语言在高并发、通信交互复杂、重业务逻辑的分布式系统中非常适用,具有开发体验好、一定量级下服务稳定、性能满足需要等优势。随着kubernetes在企业中快速扩展,席卷云计算浪潮,而这些云原生技术都是用Go编写,Go语法简洁具有非常简单的并发编程支持。Go语言迅速成为云原生时代的编程语言,更成为kubernetes二次开发首选语言。


今天给大家分享一个Go语言开发运维平台的案例

   LuBan运维平台是一个基于Go语言+Vue开发的Kubernetes多集群管理平台,可以兼容不同云厂商Kubernetes集群,同时集成CMDB资产管理、支持容器分批发布、发布暂停、JAVA应用诊断等功能。

项目地址:​https://github.com/dnsjia/luban​

Golang



技术框架​


后端框架:Golang 1.16 + Gin前端框架:Vue3 + AntDesign 2.x数据库:MySQL 5.7、Redis 5.0


资产管理

支持同步阿里云ecs到平台,代码实现思路比较简单,通过云平台API接口发起http请求调用查询资产数据

Golang


代码示例:

type CmdbInterface interface 
GetHostMenu(pid, echo int) ([]*host.TreeList, error)
UpdateHostGroup(tgr *host.TreeGroupRequest) error
DeleteHostGroup(groupId int) (err error)
SShNodeTree(pid int, search string) ([]*host.SShNodeTreeList, error)
ListVirtualMachine(treeId string, page *models.PageResult, keyword string) (result models.PageResult, err error)
GetServerAssetsUsers(instanceId string, username interface) (data *[]host.SSHLoginUser, err error)
GetGlobalServerSSHUsers(page *models.PageResult) (result models.PageResult, err error)
DisableServerSSHUsers(sshUser *host.SystemSSHUser) (err error)
UpdateServerSSHUsers(sshData *host.SSHGlobalReq, hostUserId string) (err error)
CreateServerSSHUser(sshData *host.SSHGlobalReq) (err error)
GetServerAssets(page *models.PageResult) (result models.PageResult, err error)
DeleteServerSSHUsers(uid int) (err error)
DeleteHost(groupId int) (err error)
CollectionDeleteServer(s *host.ServerReq) (err error)
ConnectionSSH(instanceId string, credentialId string) (sshClient *ssh.Client, err error)
DeleteAssets(id uint) (err error)
GetVirtualByInstanceId(instanceId string) (h *host.VirtualMachine, err error)
GetByCredentialId(credentialId string) (h host.SSHGlobalConfig, err error)
GetVirtualByUUID(uuid string) (h *host.VirtualMachine, err error)
ListPlatform(page *models.PageResult) (result models.PageResult, err error)
CreateCloudAccount(platform *host.CloudPlatform) (err error)
GetCloudAccount(cloudType string) (platform *host.CloudPlatform, err error)
InsertSSHRecord(sshRecord *host.SSHRecord) error
...
Create([]*host.VirtualMachine) error // cmdb资产同步方法
Updates(uuid string, value map[string]interface) error
NewAsynqScheduler() (scheduler *asynq.Scheduler, crontab string)
NewAsynqServer() *asynq.Server


// 程序启动后通过调用tasks.TaskBeat启动定时任务,将通过配置文件crontab参数
// 定期同步资产到运维平台
// tasks.TaskBeta() 定时任务
// 配置文件如下# 每隔两小时同步一次
crontab:
aliyun: "* */2 * * *"

Golang


const (
SyncAliYunCloud = "cmdb:aliyun"
SyncTencentCloud = "cmdb:tencent"
TypeDeployDeployment = "deploy:deployment"
CheckDeployDeploymentStatus = "deploy:checkDeployment"
)

// NewAliCloudTask 同步阿里云资产同步任务
func NewAliCloudTask(conf *cmdb.CloudPlatform) *asynq.Task
payload, err := json.Marshal(conf)
if err != nil
log.Logger.Errorf("创建阿里云资产同步任务失败,err=%v", err)

return asynq.NewTask(SyncAliYunCloud, payload)


func HandleAliCloudTask(ctx context.Context, t *asynq.Task) error
var a cmdb.CloudPlatform
if err := json.Unmarshal(t.Payload(), &a); err != nil
return err


_, err := cloudvendor.GetVendorClient(&a)
if err != nil
log.Logger.Warnf("AccountVerify GetVendorClient failed,%v", err)
return err


cloudsync.SyncAliYunHost(&a)

log.Logger.Info("Aliyun Cloud assets are successfully synchronized...")
return nil


通过调用cloudsync.SyncAliYunHost(&account)方法传入阿里云Ak,创建aliClient同步资产


// SyncAliYunHost 同步阿里云主机
func SyncAliYunHost(task *cmdb.CloudPlatform)
defer func()
if err := recover(); err != nil
log.Logger.Error(fmt.Sprintf("sync panic err: %v", err))

()

// 获取cloud账户
conf := cmdb.CloudPlatform
Type: cmdb.AliYun,
AccessKey: task.AccessKey,
SecretKey: task.SecretKey,


aliClient, _ = cloudvendor.GetVendorClient(&conf)

// 获取所有可用区
regionSet, _ := aliClient.GetRegions()
for _, region := range regionSet
// 获取所有区域下的ecs主机
instancesInfo, err := aliClient.GetInstances(region.RegionId)
if err != nil
log.Logger.Error(fmt.Sprintf("同步资产发生错误, err: %v", err))

// 判断区域下是否有ecs
if len(instancesInfo) != 0
for _, i := range instancesInfo
// 根据主机实例id获取db中的主机信息,并获取有差异的主机
diffHosts, _ := getDiffHosts(&i)
if len(diffHosts) != 0
// 有差异的更新任务状态为同步中
//updateTaskState(diffHosts)

// 同步有差异的主机数据
syncDiffHosts(diffHosts)




return


同步逻辑

/Users/micheng/code/luban/pkg/cloud/cloudsync/hostsyncor.go
// addHost 添加云主机
func addHost(hostResource []*cmdb.VirtualMachine) error
if err := luban.CoreV1.Cmdb().Create(hostResource); err != nil
return err


return nil


// syncDiffHosts 更新变化的主机
func syncDiffHosts(diff map[string][]*cmdb.VirtualMachine)
for k, v := range diff
switch k
case "update":
for _, host := range v
// HostName、PublicAddr、PrivateAddr、VmExpiredTime、Status、Mem、CPU、BandWidth
if err := luban.CoreV1.Cmdb().Updates(host.UUID, map[string]interface
"hostname": &host.HostName,
"public_addr": &host.PublicAddr,
"private_addr": &host.PrivateAddr,
"vm_expired_time": &host.VmExpiredTime,
"status": &host.Status,
"mem": &host.Mem,
"cpu": &host.CPU,
"bandwidth": &host.BandWidth,
); err != nil
log.Logger.Error("更新主机资源失败", zap.Any("err", err.Error()))


case "add":
if err := addHost(v); err != nil
log.Logger.Error("同步新增主机失败", zap.Any("err", err.Error()))




资产管理支持为用户授权

Golang


WebSSH支持屏幕录像、文件管理

Golang


鲁班运维平台Web终端集成了文件管理, 使用户更加方便上传下载文件。

Golang


接入集群

获取集群凭证, 可在k8s控制节点执行 cat $HOME/.kube/config。将集群文件内容粘贴到集群管理内。

Golang



工作负载

Golang


计算Pod内多个容器代码逻辑

// GetPodListFromChannels returns a list of all Pods in the cluster
// reading required resource list once from the channels.
func GetPodListFromChannels(channels *k8scommon.ResourceChannels, dsQuery *dataselect.DataSelectQuery) (*PodList, error)

pods := <-channels.PodList.List
err := <-channels.PodList.Error
if err != nil
return nil, err


eventList := <-channels.EventList.List
err = <-channels.EventList.Error
if err != nil
return nil, err


podList := ToPodList(pods.Items, eventList.Items, dsQuery)
podList.Status = getStatus(pods, eventList.Items)
return &podList, nil


func ToPod(pod *coreV1.Pod, warnings []k8scommon.Event) *Pod
if pod == nil
return nil

var restarts = int32(0)
var containers []*ExtContainer
for _, container := range pod.Spec.Containers
bc := ExContainerStatus(pod.Status.ContainerStatuses, &container)
containers = append(containers, bc)
if bc.Restarts > restarts
restarts = bc.Restarts


var intContainers []*ExtContainer
cn := len(containers)
for _, container := range pod.Spec.InitContainers
bc := ExContainerStatus(pod.Status.InitContainerStatuses, &container)
intContainers = append(intContainers, bc)
if bc.Restarts > restarts
restarts = bc.Restarts


cn += len(intContainers)
podDetail := Pod
ObjectMeta: k8s.NewObjectMeta(pod.ObjectMeta),
TypeMeta: k8s.NewTypeMeta(k8s.ResourceKindPod),
Warnings: warnings,
Status: getPodStatus(*pod),
InitContainers: intContainers,
RestartCount: getRestartCount(*pod),
NodeName: pod.Spec.NodeName,
ContainerImages: k8scommon.GetContainerImages(&pod.Spec),
PodIP: pod.Status.PodIP,
ContainerNum: cn,
Containers: containers,

return &podDetail


容器组

支持动态打印、日志下载

  1. 容器终端连接支持屏幕录像、操作审计。
  2. 容器终端连接文件管理支持上传、下载

Golang


容器监控

容器监控依赖于Prometheus,需要在导入集群时填写prometheus地址即可完成监控展示

Golang


应用发布

Golang


应用详情支持展示应用CPU、内存使用率。同时支持配置弹性伸缩策略

Golang


HPA弹性伸缩​

为应用配置弹性伸缩(HPA),同时支持两种指标cpu、memory

Golang



应用发布支持分批发布,基于Openkruise实现

Golang


Golang



在发布的过程中支持随时暂停发布, 这里使用的是原生操作。控制器还是会做 ​replicas​ 数量管理

Golang


发布暂停代码逻辑如下

  // 根据环境id, 获取kubeConfig
cs, err := luban.CoreV1.App().GetClusterConfig(context.TODO(), pause.EnvId, pause.Namespace)
if err != nil
response.FailWithMessage(response.AppEnvIdNotFound, response.AppEnvIdNotFoundMsg, c)
return

...
// 调用kubernetes api
client, err := Init.GetK8sClient(cs.KubeConfig)
if err != nil
response.FailWithMessage(http.StatusInternalServerError, response.NotOkMsg, c)
return


dClient := client.AppsV1().Deployments(pause.Namespace)
// RetryOnConflict 对资源进行更新 防止其他代码同时对资源进行不相关更新引起的冲突
// RetryOnConflict 将等待一段时间,如退避,然后重试。出现非“冲突”错误,或者重试次数过多并放弃,RetryOnConflict 将向调用者返回错误。
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error
result, getErr := dClient.Get(context.TODO(), pause.AppName, metav1.GetOptions)
if getErr != nil
log.Logger.Error(fmt.Sprintf("获取deployment 发生错误, err=%s", getErr))
return getErr


if pause.IsPause
result.Spec.Paused = true
msg = "发布已暂停"
else
result.Spec.Paused = false
msg = "已恢复发布"


_, updateErr := dClient.Update(context.TODO(), result, metav1.UpdateOptions)
return updateErr
)

....


应用诊断

基于阿里arthas对JAVA应用进行性能诊断,快速定位Java线上问题、可以在不重启JVM进程的情况下,查看程序的运行情况。线程耗时分析、方法执行分析和性能分析。

对需要诊断的应用Pod Annotation增加​​diagnosis: true​​字段


面对线上服务器cpu使用率一直处于100% ,cpu使用率居高不下,某些线程一直占用着cpu资源,那又如何查看占用cpu较高的线程?按照传统方法我们需通过top命令定位到cpu占用率较高的线程之后,使用jstack pid命令查看当前java进程的堆栈状态。隔段时间再执行一次stack命令获取thread dump,通过thread dump分析线程状态

在dump中,线程一般存在如下几种状态:
1、RUNNABLE,线程处于执行中
2、BLOCKED,线程被阻塞
3、WAITING,线程正在等待

Golang


针对以上问题,可以使用应用诊断快速定位线程是否存在死锁,线程CPU使用率过高问题。很大程度上节约了线上问题排查故障时间

源码查看

通过jad反编译class文件

Golang



线程堆栈

Golang



JVM信息

Golang


项目地址:​https://github.com/dnsjia/luban​

文档地址:​​https://docs.dnsjia.com/application/diagnosis/​


公众号: 自记小屋

Golang



另开设了容器开发实战培训班,想学习提升技能的同学欢迎入群交流学习。

Golang



容器集群管理平台的比较

容器化和微服务是当前最热话题,不久之前,笔者(据说因为现在都不用笔了,“笔者”的称谓已经不合适了,因为输入用键盘,叫“键人”更为合适)参加QCon上海一个微服务监控的Session,场面爆棚,我不得不在拥挤的过道听... 查看详情

容器云paas平台建设中应关注的重点和难点

对于企业级容器云PaaS平台,在多集群管理的模式下,每一个功能都会变得非常复杂。对于建设中的重点和难点,从以下多个方面进行了详细的方案分析和设计实现。主要包含安全集中控制、资源统一管理、镜像统一管理、应用... 查看详情

k8s和docker区别

k8s和docker区别:1、技术原理不同Dockers是容器化技术,K8S是一套自动化部署工具,可全生命周期管理Dockers容器。K8S是谷歌开发的容器集群管理系统。在Dockers技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动... 查看详情

wisecloud的诞生促进了容器管理的完善/睿云智合wise2c

  什么是WiseCloud  全面支持Kubernetes等主流容器集群管理框架,也支持Rancher等企业级容器管理平台,提供开发、测试、发布、持续运营等容器化应用的全生命周期管理。面对多容器集群管理平台,WiseCloud能提供完善... 查看详情

airflow+k8s多用户-分布式-跨集群-容器化调度

...作者:栾鹏)​架构系列文章最开始采用airflow+k8s分布式容器化调度的方案主要是为了解决下面的问题:1、特有环境/特有脚本调度的调度问题2、大数据量任务或大算力任务节点故障和调度管理问题目前已经基于airflow+k8s改造成... 查看详情

docker最佳实践-----美团点评的分享

美团点评容器平台简介本文介绍美团点评的Docker容器集群管理平台(以下简称“容器平台”)。该平台始于2015年,是基于美团云的基础架构和组件而开发的Docker容器集群管理平台。目前该平台为美团点评的外卖、酒店、到店、... 查看详情

如何使用容器实现生产级别的mongodbsharding集群的一键交付(代码片段)

...稳定,被大量公司用到自己的生产环境下。如何使用容器技术来实现Mongo集群的一键式交付部署,屏蔽底层实现的细节,是很多人关心的话题。本文将给大家介绍基于进程的容器技术实现Mongosharding集群的一键部署࿰... 查看详情

cnstack虚拟化服务:实现虚拟机和容器资源的共池管理

...力,又能不失灵活性地独立演进与发布。作者:林苍背景容器无疑已经成为新的云计算基础设施,企业私有云平台的建设重心,正在从虚拟化的计算、存储、网络的建设,转向构建以容器、微服务等为核心的云原生平台。不过值... 查看详情

kubesphere容器平台(代码片段)

###Kubesphere容器平台kubenertes的可视化界面,多租户,多集群,一站式上云。Linux单节点部署KubeSphere1.服务器最低4核8G,Centos7.92.安装:​1.准备KubeKey```exportKKZONE=cncurl-sfLhttps://get-kk.ku 查看详情

kubesphere容器平台(代码片段)

###Kubesphere容器平台kubenertes的可视化界面,多租户,多集群,一站式上云。Linux单节点部署KubeSphere1.服务器最低4核8G,Centos7.92.安装:​1.准备KubeKey```exportKKZONE=cncurl-sfLhttps://get-kk.ku 查看详情

容器平台自动化ci/cd流水线实操

          CI/CD————(实操说明) CI/CD持续集成(ContinuousIntegration,CI): 代码合并,构建,部署,测试都在一起,不断地执行这个过程,并对结果反馈。持续部署(ContinuousDeployment,CD): 部... 查看详情

快速搭建kubernetes容器集群平台(kubeadm)

kubeadm简介kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。这个工具能通过两条指令完成一个kubernetes集群的部署: #创建一个Master节点kubeadminit#将一个Node节点加入到当前集群中kubeadmjoin<Master节点的IP和端口> 1.... 查看详情

docker集群环境实现方式

...群环境实现的新方式近几年来,Docker作为一个开源的应用容器引擎,深受广大开发者的欢迎。随着Docker生态圈的不断建设,应用领域越来越广。云计算,大数据,移动技术的快速发展,加之企业业务需求的不断变化,紧随技术更... 查看详情

proxmox支持虚拟机和容器的虚拟化平台

ProxmoxVE是可以运行在虚拟机和容器的虚拟化平台。ProxmoxVE基于DebianLinux开发,并且完全开源。出于灵活性的考虑,ProxmoxVE同时支持两种虚拟化技术:KVM虚拟机和LXC容器。ProxmoxVE的一个重要设计目标就是尽可能简化管理... 查看详情

proxmox支持虚拟机和容器的虚拟化平台

ProxmoxVE是可以运行在虚拟机和容器的虚拟化平台。ProxmoxVE基于DebianLinux开发,并且完全开源。出于灵活性的考虑,ProxmoxVE同时支持两种虚拟化技术:KVM虚拟机和LXC容器。ProxmoxVE的一个重要设计目标就是尽可能简化管理... 查看详情

kubesphere-使用kubekey搭建k8s集群及kubesphere(代码片段)

...eSphere是一款面向云原生设计的开源项目,在目前主流容器调度平台Kubernetes之上构建的分布式多租户容器管理平台,提供简单易用的操作界面以及向导式操作方式,在降低用户使用容器调度平台学习成本的同时,... 查看详情

业务容灾管理设计利器:工商银行如何使用karmada千级容器集群

文章目录前言一、工行业务背景1.1、工行云计算架构组成1.2、工行云平台技术栈1.3、工行金融云成效1.3.1、入云规模同业最大1.3.2、业务如云场景广1.4、容灾及高可用保障1.5、PaaS层多集群现状1.5.1、集群种类多1.5.2、k8s集群node数... 查看详情

k8s和docker区别

1、技术原理不同docker是容器化技术,K8S是一套自动化部署工具,可全生命周期管理docker容器。K8S是谷歌开发的容器集群管理系统。在docker技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列... 查看详情