简介
该篇文章主要是《k8s集群管理平台开发实践》的开发环境的准备工作,安装golang、ide环境,下载必须的文件及软件包,并通过client-go实现连接部分clientset的功能连接到k8s。
一.环境安装
1.1.安装golang
golang下载地址:https://studygolang.com/dl https://studygolang.com/dl/golang/go1.22.0.windows-amd64.zip
编辑器下载地址:https://studygolang.com/articles/4930, https://github.com/visualfc/liteide/releases/download/x38.3/liteidex38.3-win64-qt5.15.2.zip
创建目录D:\tools\go1.22.0 和 D:\tools\liteide目录并将golang和liteide安装到对应目录下,然后设置环境变量:在高级系统设置---》环境变量---》系统变量---》新建变量名:GOROOT,变量值:D:\tools\go----》在系统变量里path,编辑新增一条:D:\tools\go\bin---最后确定。然后新打开powershell 执行go version 如果现实版本表示安装成功。 将D:\tools\liteide\bin\liteide.exe 右击--发送到桌面快捷方式,双击改文件,打开编辑器。
1.2.安装beego环境下的工具bee
下载地址:github.com/beego/bee https://github.com/beego/bee/archive/refs/tags/v2.1.0.zip 安装方法一:1. go install github.com/beego/bee/v2@latest,然后将bee.exe加到path的环境变量,或者放到c:\windows\system32下。 安装方法二:下载zip包,解压,然后进入目录执行go build main.go将生成的main.exe 重命名为bee.exe并放到c:\windows\system32 下。 重新打开powershell,然后执行bee version 如果有如下信息表示成功。
2024/04/22 11:55:18.719 [D] init global config instance failed. If you do not use this, just ignore it. open conf/app.conf: The system cannot find the path specified.
______
| ___ \
| |_/ / ___ ___
| ___ \ / _ \ / _ \
| |_/ /| __/| __/
\____/ \___| \___| v2.1.0
├── GoVersion : go1.22.0
├── GOOS : windows
├── GOARCH : amd64
├── NumCPU : 12
├── GOPATH :
├── GOROOT : D:\tools\go1.22.0
├── Compiler : gc
└── Date : Monday, 22 Apr 2024
1.3.下载layuimini模板
layuimini是采用layui的框架实现的后台模板,layui采用的版本是2.6.3 layuimini git地址:https://github.com/zhongshaofa/layuimini 官网地址:http://layuimini.99php.cn/ 演示地址:http://layuimini.99php.cn/iframe/v2/index.html 下载代码仓库(iframe 多tab版) v2版本:https://github.com/zhongshaofa/layuimini/tree/v2
layui镜像站:https://www.layui.site/, 由于2.7以前的版本的使用文档下线了,所以使用镜像站地址。
二.创建项目
2.1.用bee命令创建项目
创建目录:D:\myproject\,然后进入该目录执行:bee new myk8s创建一个项目,然后用liteide 打开目录:D:\myproject\myk8s。
2.2.配置静态访问地址
在D:\myproject\myk8s\views\下创建目录front,并将layuimini-v2.zip 内的文件解压到front目录下,注意:front目录结构如下:
目录: D:\myproject\myk8s\views\front
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2024/4/22 12:22 api
d----- 2024/4/22 12:22 css
d----- 2024/4/22 12:22 images
d----- 2024/4/22 12:22 js
d----- 2024/4/22 12:22 lib
d----- 2024/4/22 12:22 page
-a---- 2021/9/17 8:17 107 .gitattributes
-a---- 2021/9/17 8:17 6 .gitignore
-a---- 2021/9/17 8:17 7812 index.html
-a---- 2021/9/17 8:17 1066 LICENSE
-a---- 2021/9/17 8:17 6823 README.md
配置静态访问地址:在main.go中设置静态访问地址,代码如下:
package main
import (
_ "myk8s/routers"
beego "github.com/beego/beego/v2/server/web"
)
func main() {
beego.SetStaticPath("/", "views/front")
beego.Run()
}
三.实现客户端连接clientset
在myk8s 下创建common 目录,并在该目录下创建一个文件:k8sclient.go,完整代码如下:
// k8sclient.go
package common
import (
"log"
"os"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func ClientSet(clusterid string) *kubernetes.Clientset {
var kubeconfigPath string
switch clusterid {
case "ali-cluster1":
kubeconfigPath = "./ali-cluster1.txt"
case "ali-cluster2":
kubeconfigPath = "./ali-cluster2.txt"
default:
kubeconfigPath = "./kubeconfig.txt"
}
config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
if err != nil {
panic(err.Error())
}
config.QPS = 10
config.Burst = 100
if clusterid == "aws-cluster1" { //针对aws的k8s集群需要读取token来进行验证
bearerToken, err := GetBearerTokenByClusterId(kubeconfigPath)
if err != nil {
//panic(err.Error())
log.Printf("[ERROR] GetBearerTokenByClusterId err:%s\n", err)
}
//log.Println(bearerToken)
if bearerToken != "" && bearerToken != "null" {
config.BearerToken = bearerToken
}
}
// create the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
bearerToken, err2 := GetBearerTokenByClusterId(clusterid)
if err2 != nil {
//panic(err.Error())
log.Printf("[ERROR] GetBearerTokenByClusterId err:%s\n", err2)
}
//log.Println(bearerToken)
if bearerToken != "" && bearerToken != "null" {
config.BearerToken = bearerToken
}
return clientset
}
//读取文件中的bearerToken
func GetBearerTokenByClusterId(tokenFilePath string) (string, error) {
content, err := os.ReadFile(tokenFilePath)
if err != nil {
return "", err
}
return string(content), nil
}
四.修改前端代码,实现初步的显示框架
4.1.修改菜单配置
修改views\front\api\init.json中去掉不必要的菜单选项,保留最简单的框架,完整的页面形式可以参考layuimini的演示地址,代码如下:
{
"homeInfo": {
"title": "首页",
"href": "page/xkube/main.html?t=1"
},
"logoInfo": {
"title": "LAYUI MINI",
"image": "images/logo.png",
"href": ""
},
"menuInfo": [
{
"title": "k8s管理",
"icon": "fa fa-address-book",
"href": "",
"target": "_self",
"child": [
{
"title": "集群信息",
"href": "",
"icon": "fa fa-home",
"target": "_self",
"child": [
{
"title": "节点管理",
"href": "page/xkube/nodeList.html",
"icon": "fa fa-tachometer",
"target": "_self"
}
]
},
{
"title": "工作负载",
"href": "",
"icon": "fa fa-calendar",
"target": "_self",
"child": [
{
"title": "无状态[deploy]",
"href": "page/xkube/deployList.html",
"icon": "fa fa-list-alt",
"target": "_self"
},
{
"title": "容器组[pod]",
"href": "page/xkube/podList.html",
"icon": "fa fa-navicon",
"target": "_self"
},
{
"title": "定时任务[cronjob]",
"href": "page/xkube/cronjobList.html",
"icon": "fa fa-navicon",
"target": "_self"
}
,
{
"title": "自动伸缩[hpa]",
"href": "page/xkube/hpaList.html",
"icon": "fa fa-navicon",
"target": "_self"
}
]
},
{
"title": "网络",
"href": "",
"icon": "fa fa-flag-o",
"target": "_self",
"child": [
{
"title": "服务[svc]",
"href": "page/xkube/svcList.html",
"icon": "fa fa-stumbleupon-circle",
"target": "_blank"
},
{
"title": "路由[ingress]",
"href": "page/xkube/ingressList.html",
"icon": "fa fa-viacoin",
"target": "_blank"
}
]
},
{
"title": "配置管理",
"href": "",
"icon": "fa fa-home",
"target": "_self",
"child": [
{
"title": "configmap[cm]",
"href": "page/xkube/configmapList.html",
"icon": "fa fa-hourglass-end",
"target": "_self"
}
]
},
{
"title": "存储",
"href": "",
"icon": "fa fa-snowflake-o",
"target": "",
"child": [
{
"title": "存储声明[pvc]",
"href": "page/xkube/pvcList.html",
"icon": "fa fa-snowflake-o",
"target": "_self"
}
]
}
]
}
]
}
4.2.控制端主页代码
views\front\page\xkube\main.html代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>主页一</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/lib/layui-v2.6.3/css/layui.css" media="all">
<link rel="stylesheet" href="/lib/font-awesome-4.7.0/css/font-awesome.min.css" media="all">
<link rel="stylesheet" href="/css/public.css" media="all">
<script src="/js/xkube.js?v=1.0.0" charset="utf-8"></script>
</head>
<style>
.layui-top-box {padding:40px 20px 20px 20px;color:#fff}
.panel {margin-bottom:17px;background-color:#fff;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}
.panel-body {padding:15px}
.panel-title {margin-top:0;margin-bottom:0;font-size:14px;color:inherit}
.label {display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em;margin-top: .3em;}
.layui-red {color:red}
.main_btn > p {height:40px;}
</style>
<body>
<div class="layuimini-container">
<div class="layuimini-main layui-top-box">
<div class="layui-row layui-col-space10">
<div class="layui-col-md3">
<div class="col-xs-6 col-md-3">
<div class="panel layui-bg-cyan">
<div class="panel-body">
<div class="panel-title">
<span class="label pull-right layui-bg-blue">实时</span>
<h5>节点统计</h5>
</div>
<div class="panel-content">
1234
<div class="stat-percent font-bold text-gray"><i class="fa fa-commenting"></i> 1234</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-md3">
<div class="col-xs-6 col-md-3">
<div class="panel layui-bg-blue">
<div class="panel-body">
<div class="panel-title">
<span class="label pull-right layui-bg-cyan">实时</span>
<h5>POD统计</h5>
</div>
<div class="panel-content">
1234
<div class="stat-percent font-bold text-gray"><i class="fa fa-commenting"></i> 1234</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-md3">
<div class="col-xs-6 col-md-3">
<div class="panel layui-bg-green">
<div class="panel-body">
<div class="panel-title">
<span class="label pull-right layui-bg-orange">实时</span>
<h5>deploymen统计</h5>
</div>
<div class="panel-content">
1234
<div class="stat-percent font-bold text-gray"><i class="fa fa-commenting"></i> 1234</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-md3">
<div class="col-xs-6 col-md-3">
<div class="panel layui-bg-orange">
<div class="panel-body">
<div class="panel-title">
<span class="label pull-right layui-bg-green">实时</span>
<h5>存储统计</h5>
</div>
<div class="panel-content">
1234
<div class="stat-percent font-bold text-gray"><i class="fa fa-commenting"></i> 1234</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-box">
<div class="layui-row layui-col-space10">
<div class="layui-col-md6">
<table class="layui-table">
<colgroup>
<col width="150">
<col width="200">
<col>
</colgroup>
<thead>
<tr>
<th>集群名称</th>
<th>默认集群</th>
<th>设置为默认集群</th>
</tr>
</thead>
<tbody>
<tr>
<td>ali-cluster1</td>
<td>true</td>
<td><input class="layui-btn layui-btn-sm" type="button" onclick="SetDefaultCluster('ali-cluster1');" value="设置默认集群"/></td>
</tr>
<tr>
<td>ali-cluster2</td>
<td>false</td>
<td><input class="layui-btn layui-btn-sm" type="button" onclick="SetDefaultCluster('ali-cluster2');" value="设置默认集群"/></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<script src="/lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
</body>
</html>
五.调试代码
5.1.用liteide编辑器调试代码
在liteide --->编译----> get ---> test。调试成功以后,编译--Build 就会在myk8s目录下生成一个myk8s.exe,成功后的结果如下:
D:/prog/go1.22.0/bin/go.exe build [D:/myproject/myk8s]
成功: 进程退出代码 0.
5.2.修改beego的配置文件
修改conf/app.conf
appname = myk8s
httpport = 8080
runmode = dev
#传递obdy的配置
copyrequestbody = true
#由于layui和beego对于模板的引用字符有冲突,这里修改一下beego的模板字符。
TemplateLeft = "<<<"
TemplateRight = ">>>"
5.3.编译调试启动
执行myk8s.exe启动进程:
PS D:\myproject\myk8s> .\myk8s.exe
2024/04/23 14:43:01.136 [I] [server.go:281] http server Running on http://:8080
5.4.浏览器打开
浏览器打开:http://127.0.0.1:8080/index.html ,效果如下图