Service模块开发

2023-10-30 18:38:41 浏览数 (2)

今日开发进度暂无,不过还是接着看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函数中,这样就不利于后期的维护和扩展,所以可以参考上一篇文章说的通用目录结构分层,就可以慢慢开发了。

好了,今天的分享就到这了,祝学习顺利!

0 人点赞