今日开发进度暂无,不过还是接着看service模块,使用go客户端,调用K8s集群接口,获取service相关信息。
先看一下示例代码,大家可以自行根据需求修改:
代码语言:javascript复制package main
import (
"context"
"fmt"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
func main() {
// 创建Kubernetes客户端,使用InClusterConfig获取集群内部config
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
// 获取Namespace列表,使用ListOptions设置超时时间避免长时间等待
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
namespaces, err := clientset.CoreV1().Namespaces().List(ctx,
metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
// 遍历每个Namespace
for _, namespace := range namespaces.Items {
// 为每个Service创建context,单独设置超时时间
ctx, cancel := context.WithTimeout(context.Background(),
3*time.Second)
defer cancel()
// 获取Namespace下的Service列表
services, err := clientset.CoreV1().Services(namespace.Name).List(ctx,
metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
// 遍历每个Service,获取详细信息
for _, service := range services.Items {
// 为获取Deployments创建context,设置超时时间
ctx, cancel := context.WithTimeout(context.Background(),
3*time.Second)
defer cancel()
// 获取Service对应的Deployments
deployments, err :=
clientset.AppsV1().Deployments(namespace.Name).List(ctx,
metav1.ListOptions{LabelSelector: service.Spec.Selector})
if err != nil {
panic(err.Error())
}
// 输出Service详细信息,增加相关注释
fmt.Printf("Name: %sn", service.Name) // Service名称
fmt.Printf("Namespace: %sn", namespace.Name) // 所在Namespace
fmt.Printf("Label: %sn", service.Labels) // Service标签
fmt.Printf("Selector: %sn", service.Spec.Selector) // Service选择器
fmt.Printf("IP: %sn", service.Spec.ClusterIP) // 集群IP
fmt.Printf("Port: %vn", service.Spec.Ports) // 端口信息
fmt.Printf("Deployments: %sn", deployments.Items) // 关联的Deployments
fmt.Println() // 空行
}
}
}
运行时LabelSelector: service.Spec.Selector这里会报错:
因为在Kubernetes中,Service的Spec.Selector字段表示的是Service选择的Pod标签选择器,其类型是map[string]string,例如:
代码语言:javascript复制selector:
app: myapp
release: stable
而在获取Deployments时,ListOptions的LabelSelector接收的应该是字符串形式的选择器,例如:
代码语言:javascript复制"app=myapp,release=stable"
所以,正确的代码应该是:
代码语言:javascript复制deployments, err := clientset.AppsV1().Deployments(namespace.Name).List(ctx,
metav1.ListOptions{LabelSelector: labels.Set(service.Spec.Selector).String()})
if err != nil {
panic(err.Error())
}
运行结果如下:
那么下一步就是将这些信息展示在前端,需要开放一个接口,那么其他的增删改查接口也是如此。
这时候就需要引入gin框架了:
代码语言:javascript复制package main
import (
"context"
"github.com/gin-gonic/gin"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"path/filepath"
)
初始化gin路由
代码语言:javascript复制router := gin.Default()
定义获取Services接口
代码语言:javascript复制router.GET("/services", func(c
*gin.Context)
然后封装Service信息
最后运行gin服务,我们看看结果:
访问就有结果了。
代码语言:javascript复制http://127.0.0.1:8080/services
那么这里相当于将所有需要的层都放在main函数中,这样就不利于后期的维护和扩展,所以可以参考上一篇文章说的通用目录结构分层,就可以慢慢开发了。
好了,今天的分享就到这了,祝学习顺利!