hisamounaのブログ

アウトプットを習慣化するためのブログ

client-goを使って、node上のpod一覧を表示する

環境

kindを使ってローカル上(Mac)にバージョン: v1.21.0のk8sクラスタを用意

クライアント作成

import (
    "context"
    "fmt"

    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"

    corev1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/fields"
)

type KubeClient struct {
    ClientSet *kubernetes.Clientset
}

func NewClient(fileName string) (*KubeClient, error) {
    kubeconfig := fmt.Sprintf("%s/.kube/%s", homedir.HomeDir(), fileName)

    config, err := clientcmd.BuildConfigFromFlags("", *&kubeconfig)
    if err != nil {
        return nil, err
    }
    client, err := kubernetes.NewForConfig(config)
    if err != nil {
        return nil, err
    }

    return &KubeClient{client}, err
}

node一覧を取得

KubernetesのlistNodesを参考

func (kc *KubeClient) GetNodes() ([]string, error) {
    nodes, err := kc.ClientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
    if err != nil {
        return nil, err
    }
    var nodeNames []string
    for _, item := range nodes.Items {
        nodeNames = append(nodeNames, item.Name)
    }
    return nodeNames, nil
}

node上のpod一覧を取得

kubectlのDescribeを参考

func (kc *KubeClient) DescribeNode(name string) (interface{}, error) {
    fieldSelector, err := fields.ParseSelector("spec.nodeName=" + name + ",status.phase!=" + string(corev1.PodSucceeded) + ",status.phase!=" + string(corev1.PodFailed))
    if err != nil {
        return nil, err
    }
    nodeNonTerminatedPodsList, err := kc.ClientSet.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{FieldSelector: fieldSelector.String()})
    if err != nil {
        return nil, err
    }
    for _, pod := range nodeNonTerminatedPodsList.Items {
        fmt.Printf("%s\t%s\t\n", pod.Namespace, pod.Name)
    }
    return nil, nil
}

無事、一覧を取得できました。

テストコード

func TestGetNodes(t *testing.T) {
    kc, err := NewClient("kind_config")
    if err != nil {
        t.Fatalf("NewClient: %v", err)
    }

    nodes, err := kc.GetNodes()
    if err != nil {
        t.Fatalf("GetNodes: %v", err)
    }

    _, err = kc.DescribeNode(nodes[1])
    if err != nil {
        t.Fatalf("DescribeNode: %v", err)
    }
}
└─> go test -v pkg/kube/*.go
=== RUN   TestGetNodes
gatekeeper-system   gatekeeper-audit-d57fc8bf-flddz
gatekeeper-system   gatekeeper-controller-manager-6d68cfcdd8-hztlb
gatekeeper-system   gatekeeper-controller-manager-6d68cfcdd8-s5wp4
kube-system coredns-558bd4d5db-nb2rw
kube-system kindnet-bqnlc
kube-system kube-proxy-n69kv
--- PASS: TestGetNodes (0.03s)
PASS
ok      command-line-arguments  0.287s

kc.ClientSet.CoreV1().Pods("") だとすべてのnamespaceのpodを取得するので、特定のnamespaceのみの場合は kc.ClientSet.CoreV1().Pods("kube-system") と記載