وصل شدن به کوبرنتیز با استفاده از گولنگ

شاید نیاز داشته باشید از داخل برنامه Go به کلاستر کیوب(کوبرنتیز) وصل بشید یا بخواید یه cli کوچیک برای خودتون بنویسید. اینجاست که باید به خاطر ریپو client-go متشکر تیم توسعه کیوب باشیم.😍

اما چجوری به کلاستر کیوب وصل بشیم؟

من می‌خوام توی این پست با دو روش متفاوت این رو توضیح بدم.

وصل شدن از خارج از کلاستر

اگر بخواین از بیرون، به کلاستر کیوب وصل بشین یه کد شبیه کد زیر داره این کار رو میکنه.

import (
        "context"
        "fmt"
        "os"
        "path/filepath"

        v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/client-go/kubernetes"
        "k8s.io/client-go/tools/clientcmd"
)

func main() {
        fmt.Println("Get Kubernetes pods")

        userHomeDir, err := os.UserHomeDir()
        if err != nil {
                fmt.Printf("error getting user home dir: %v\n", err)
                os.Exit(1)
        }
        kubeConfigPath := filepath.Join(userHomeDir, ".kube", "config")
        fmt.Printf("Using kubeconfig: %s\n", kubeConfigPath)

        kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
        if err != nil {
                fmt.Printf("error getting Kubernetes config: %v\n", err)
                os.Exit(1)
        }

        clientset, err := kubernetes.NewForConfig(kubeConfig)
        if err != nil {
                fmt.Printf("error getting Kubernetes clientset: %v\n", err)
                os.Exit(1)
        }

        pods, err := clientset.CoreV1().Pods("kube-system").List(context.Background(), v1.ListOptions{})
        if err != nil {
                fmt.Printf("error getting pods: %v\n", err)
                os.Exit(1)
        }
        for _, pod := range pods.Items {
                fmt.Printf("Pod name: %s\n", pod.Name)
        }
}

بیاین یکم با جزییات بیشتر کد رو بررسی کنیم. اول از همه داخل تیکه کد زیر ما داریم فایل کانفیگ کیوب رو از دایرکتوری پیش فرض می‌خونیم.

userHomeDir, err := os.UserHomeDir()
if err != nil {
        fmt.Printf("error getting user home dir: %v\n", err)
        os.Exit(1)
}
kubeConfigPath := filepath.Join(userHomeDir, ".kube", "config")

مرحله بعدی لازم داریم یک کانفیگ آبجکت از فایل کانفیگ بسازیم.

kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)

و توی مرحله بعد ما یک کلاینت‌ست میسازیم.

clientset, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
        fmt.Printf("error getting Kubernetes clientset: %v\n", err)
        os.Exit(1)
}

خب بلاخره ما یک ابجکت داریم که می‌تونه به apiهای مختلف کیوب دسترسی داشته باشه. به عنوان یک مثال ساده من‌ می‌خوام لیست pod های نیم‌اسپیس kube-system رو بخونم.

pods, err := clientset.CoreV1().Pods("kube-system").List(context.Background(), v1.ListOptions{})
if err != nil {
        fmt.Printf("error getting pods: %v\n", err)
        os.Exit(1)
}
for _, pod := range pods.Items {
        fmt.Printf("Pod name: %s\n", pod.Name)
}

که این میشه خروجی نهایی کد ما.

Get Kubernetes pods
Using kubeconfig: /home/trstringer/.kube/config
Pod name: coredns-558bd4d5db-77b5b
Pod name: coredns-558bd4d5db-sskcx
Pod name: etcd-kind-control-plane
Pod name: kindnet-xg859
Pod name: kube-apiserver-kind-control-plane
Pod name: kube-controller-manager-kind-control-plane
Pod name: kube-proxy-vpp5d
Pod name: kube-scheduler-kind-control-plane

وصل شدن از داخل کلاستر

وصل شدن از داخل کلاستر فقط یک تفاوت کوچیک با کد بالا داره. اینکه ما اول k8s.io/client-go/rest   رو ایمپورت می‌کنیم و بعد از این فانکشن استفاده می‌کنیم rest.InClusterConfig() . بعد از چک کردن ارور، خروجی رو به این فانکشن kubernetes.NewForConfig() می‌دیم و بقیه کد کاملا یکسان هست.