go语言-k8s宿主信息采集运维脚本

2024-03-08 22:52

本文主要是介绍go语言-k8s宿主信息采集运维脚本,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

由于工作需要,需要采集k8s集群中的宿主相关信息,包括cpu,memory,lvm,标签等信息。通常作为SRE会主选shell或python脚本来实现。但最近我们团队主流开发语言已经切换到golang.所以本次尝试用go语言来写写运维脚本。

实现流程图

代码实现

package mainimport ("errors""fmt""github.com/gocarina/gocsv""log""os""os/exec""strings""time"
)// K8SNode 描述宿主节点
type K8SNode struct {IP           string `csv:"ip"`CPUSize      string `csv:"cpu_size"`MemorySize   string `csv:"memory_size"`LVMSize      string `csv:"lvm_size"`VMINum       int    `csv:"vmi_num"` // 虚拟机个数ProjectLabel string `csv:"project_label"`
}// NodeDescribeOutput 执行kubectl describe node 指定ip后面的输出内容
func NodeDescribeOutput(ip string) (string, error) {cmd := "kubectl  describe node " + iplog.Printf("execut command: %s\n", cmd)output, err := ExecCmd(cmd)if err != nil {log.Println("err:", err)return "", err}return output, nil
}// CpuSize 获取节点cpu
func CPUSize(describeInfo string) (string, error) {describeInfoList := strings.Split(describeInfo, "\n")for _, line := range describeInfoList {if strings.Contains(line, "cpu:") {cpusizelist := strings.Split(line, ":")//log.Printf("cpusize: %s", cpusizelist[1])size := strings.Replace(cpusizelist[1], " ", "", -1)return size, nil}}return "", errors.New("not found cpu size.")
}// MemorySize 获取节点内存大小
func MemorySize(describeInfo string) (string, error) {describeInfoList := strings.Split(describeInfo, "\n")for _, line := range describeInfoList {if strings.Contains(line, "memory:") {memorysizelist := strings.Split(line, ":")size := strings.Replace(memorysizelist[1], " ", "", -1)return size, nil}}return "", errors.New("not found memory size.")
}// LVMSize 获取节点本地磁盘大小
func LVMSize(describeInfo string) (string, error) {describeInfoList := strings.Split(describeInfo, "\n")for _, line := range describeInfoList {if strings.Contains(line, "lvm:") {sizelist := strings.Split(line, ":")size := strings.Replace(sizelist[1], " ", "", -1)return size, nil}}return "", errors.New("not found memory size.")
}// VMINum 统计节点已经允许vmi的数量(vmi表示在k8s+kubevirt中KVM对应的对象)
func VMINum(describeInfo string) (int, error) {describeInfoList := strings.Split(describeInfo, "\n")var count intfor _, line := range describeInfoList {if strings.Contains(line, "irt-launcher-") {count++}}return count, nil
}// ProjectLabel 获取节点项目标签[我们业务定义project表示宿主用于哪一个项目]
func ProjectLabel(describeInfo string) (string, error) {describeInfoList := strings.Split(describeInfo, "\n")for _, line := range describeInfoList {if strings.Contains(line, "project=") {//log.Printf("cpusize: %s", cpusizelist[1])label := strings.Replace(line, " ", "", -1)label = strings.Replace(label, "project=", "", -1)label = strings.Replace(label, "\n", "", -1)return label, nil}}return "", errors.New("not found project label.")
}// ExecCmd 对exec.Command()的封装
func ExecCmd(cmdstr string) (string, error) {cmd := exec.Command("bash", "-c", cmdstr)res, err := cmd.Output()if err != nil {return "", err}return string(res), nil}// GetIPList 获取集群中节点对应的IP列表
func GetIPList() []string {cmd := "kubectl get  node |grep -E \"[0-9]\" |awk '{print $1}'"log.Printf("execut command: %s\n", cmd)output, err := ExecCmd(cmd)if err != nil {log.Println("err:", err)var nilIPList []stringreturn nilIPList}return strings.Split(string(output), "\n")
}// 将结构体切片转换为csv文件
func WriteToCsv(filename string, nodes []*K8SNode) {// 创建csv文件os.Chdir("/tmp")nodesFile, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)if err != nil {panic(err)}defer nodesFile.Close()// 将结构体切片转换为csv文件if err := gocsv.Marshal(&nodes, nodesFile); err != nil { // Load clients from filepanic(err)}
}// uploadToFilesever 将文件通过scp命令传到文件服务器
func uploadToFilesever(filename string) error {cmd := "scp " + filename + " 172.17.123.89:/home/segops/app/nginx/data/tmp/"log.Printf("execut command: %s\n", cmd)_, err := ExecCmd(cmd)if err != nil {log.Println("err:", err)return err}return nil
}func main() {// Nodes 保存节点的切片var Nodes = []*K8SNode{}// count 用于统计节点数量var count intipList := GetIPList()// 依次处理每一个宿主节点IPfor _, ip := range ipList {//fmt.Println(ip)if ip == "" {continue}count++var oneNode = &K8SNode{}oneNode.IP = ipdescribeNodeOutput, err := NodeDescribeOutput(ip)if err != nil {log.Printf("%s NodeDescribeOutput error.\n", ip)}cpusize, err := CPUSize(describeNodeOutput)if err == nil {oneNode.CPUSize = cpusize} else {oneNode.CPUSize = ""}memsize, err := MemorySize(describeNodeOutput)if err == nil {oneNode.MemorySize = memsize} else {oneNode.MemorySize = ""}lvmsize, err := LVMSize(describeNodeOutput)if err == nil {oneNode.LVMSize = lvmsize} else {oneNode.LVMSize = ""}vminum, err := VMINum(describeNodeOutput)if err == nil {oneNode.VMINum = vminum} else {oneNode.VMINum = -1}projectlabel, err := ProjectLabel(describeNodeOutput)if err == nil {oneNode.ProjectLabel = projectlabel} else {oneNode.ProjectLabel = ""}fmt.Printf("%v\n", oneNode)//log.Println(ProjectLabel(describeNodeOutput))// 将一个K8SNode对象加入切片Nodes = append(Nodes, oneNode)}//fmt.Println("nodemap=%v", nodeMap)fmt.Printf("===========================================================================================\n")fmt.Printf("=========================================统计结果===========================================\n")fmt.Printf("===========================================================================================\n")fmt.Printf("ip\t\tcpu\t\tmemory\t\tlvmsize\t\tvminum\t\tprojectlabel\n")for _, node := range Nodes {fmt.Printf("%s\t%s\t\t%s\t%s\t\t%d\t\t%s\n", node.IP, node.CPUSize, node.MemorySize, node.LVMSize, node.VMINum, node.ProjectLabel)}fmt.Println()fmt.Printf("node num is %d\n", count)fmt.Println()fmt.Println("write to csv file:")currentTime := time.Now().Format("20060102150405")hostname, _ := os.Hostname()csvfilename := hostname + "_" + "nodesinfo" + "_" + currentTime + ".csv"// 写入csv文件WriteToCsv(csvfilename, Nodes)// 上传到文件服务器err := uploadToFilesever(csvfilename)if err != nil {fmt.Println("upload csv file error.")return}// 定义下载文件的路径downloadPath := "http://172.17.123.89:8080/tmp/" + csvfilenamefmt.Println()fmt.Println("csv file can download from: ", downloadPath)fmt.Println()
}

实现结果

​
17:35:14  ===========================================================================================
17:35:14  =========================================统计结果===========================================
17:35:14  ===========================================================================================
17:35:14  ip		cpu		memory		lvmsize		vminum		projectlabel
17:35:14  172.24.52.11	96		394687572Ki	4862Gi		7		personal-dev
17:35:14  172.24.52.12	96		394687572Ki	4862Gi		8		personal-dev
17:35:14  172.24.52.13	96		394682812Ki	4862Gi		2		personal-dev
17:35:14  172.24.52.14	96		394687572Ki	4862Gi		5		personal-dev
17:35:14  172.24.52.141	96		394687572Ki	4862Gi		1		tools
17:35:14  172.24.52.142	96		394687572Ki	4862Gi		0		personal-dev-unuse
17:35:14  172.24.52.143	96		394687572Ki	4862Gi		0		personal-dev-unuse
17:35:14  172.24.53.79	80		394679084Ki	3225Gi		0		unuse
17:35:14  172.24.53.93	72		131267356Ki	11431Gi		0		unuse
17:35:14  172.24.53.94	72		131267356Ki	11431Gi		0		unuse
17:35:14  
17:35:14  node num is 122
17:35:14  
17:35:14  write to csv file:
17:35:14  2024/03/07 17:35:14 execut command: scp hyd01-seg-admin01_nodesinfo_20240307173514.csv 172.17.123.89:/home/segops/app/nginx/data/tmp/
17:35:15  
17:35:15  csv file can download from:  http://172.17.123.89:8080/tmp/hyd01-seg-admin01_nodesinfo_20240307173514.csv​

 

总结

用go脚本写了约300行,并不简洁。所以在工作实际中,如果写一些逻辑简单的脚本建议首选用shell或python。

这篇关于go语言-k8s宿主信息采集运维脚本的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/788668

相关文章

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别? 在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。 无缓冲的 channel 行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel