Предварительное исследование клиентского опыта второго открытия K8s

Kubernetes
Предварительное исследование клиентского опыта второго открытия K8s

Введение в client-go

В последнее время возникла необходимость настроить и интегрировать некоторые данные k8s.Для быстрой и простой реализации требований можно использовать Client-go.При эксплуатации и обслуживании K8s мы можем использовать kubectl, клиентскую библиотеку или REST-запрос для доступа к K8S API. . По сути, и kubectl, и клиентские библиотеки — это инструменты, инкапсулирующие REST-запросы. В качестве клиентской библиотеки client-go может вызывать API K8S для реализации таких операций, как добавление, удаление, изменение и проверка объектов ресурсов (включая развертывание, службу, вход, набор реплик, модуль, пространство имен, узел и т. д.) в K8S. кластер.

2 Введение

2.1 Структурная схема

На рисунке вы можете увидеть четырех клиентов в Client-Go.ClientSet,DynamicClient,DiscoveryClientобаRestClientконкретная реализация.

2.2 Структура каталогов

# tree client-go/ -L 1
client-go/
  ├── discovery
  ├── dynamic
  ├── informers
  ├── kubernetes
  ├── listers
  ├── plugin
  ├── rest
  ├── scale
  ├── tools
  ├── transport
  └── util
  • discovery:поставкаDiscoveryClientобнаружить клиента
  • dynamic:поставкаDynamicClientдинамический клиент
  • informers: Реализация информера для каждого ресурса kubernetes
  • kubernetes:поставкаClientSetклиент
  • listers: Предоставляет функцию Lister для каждого ресурса Kubernetes, которая предоставляет кэшированные данные только для чтения для запросов Get и List.
  • plugin: Предоставляет авторизованные подключаемые модули для поставщиков облачных услуг, таких как OpenStack, GCP и Azure.
  • rest:поставкаRESTClientКлиент, выполняйте операции RESTful на сервере API Kubernetes.
  • scale:поставкаScaleClientКлиент, используемый для расширения или сжатия объектов ресурсов, таких как Deployment, ReplicaSet, Relication Controller и т. д.
  • tools: Предоставляет общие инструменты, такие как SharedInformer, Reflector, DealtFIFO и индексаторы. Обеспечить клиентский запрос и механизм кэширования, чтобы уменьшить количество запросов к kube-apiserver и т. д.
  • transport: обеспечивает безопасное TCP-соединение, поддерживает Http Stream, а для некоторых операций требуется передача двоичных потоков между клиентом и контейнером, таких как выполнение, присоединение и другие операции. Эта функциональность поддерживается внутренним пакетом spdy.
  • util: Предоставляет общие методы, такие как очередь функций WorkQueue, управление сертификатами и т. д.

Три сертификации

Стоит упомянуть, что пора идти мод идти клиент через маленькую дырку в прикладе k8s Итак, что нам нужно указать версию k8s в файле go mod, иначе он будет по умолчанию k8s получил меня последней версией пакета, мы также знаем, что разные версии k8s отличаются API

3.1 Сертификация

3.1.1 token

# APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
# TOKEN=$(kubectl get secret $(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') -o # jsonpath='{.data.token}' | base64 --decode )
# curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure

Четыре клиента — четыре типа

4.1 RestClient

RestClient — самый простой клиент. RestClient инкапсулирован на основе HTTP-запроса и реализует Restful API. Он может взаимодействовать напрямую с помощью RESTful-методов, предоставляемых RESTClient, таких как Get(), Put(), Post(), Delete(). Оба Поддерживаются Json и protobuf, поддерживаются все нативные ресурсы и CRD, но в целом для более элегантной обработки требуется дополнительная инкапсуляция RESTClient инкапсулируется через Clientset, а затем интерфейсы и сервисы предоставляются извне.

package main

import (
	"fmt"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
)

var configFile = "../config"
var ApiPath = "api"
var nameSpace = "kube-system"
var resouce = "pods"

func main() {
	// 生成config
	config, err := clientcmd.BuildConfigFromFlags("", configFile)
	if err != nil {
		panic(err)
	}
	config.APIPath = ApiPath
	config.GroupVersion = &corev1.SchemeGroupVersion
	config.NegotiatedSerializer = scheme.Codecs

	// 生成restClient
	restClient, err := rest.RESTClientFor(config)
	if err != nil {
		panic(err)
	}
	// 声明空结构体
	rest := &corev1.PodList{}
	if err = restClient.Get().Namespace(nameSpace).Resource("pods").VersionedParams(&metav1.ListOptions{Limit: 500},
		scheme.ParameterCodec).Do().Into(rest); err != nil {
		panic(err)
	}
	for _, v := range rest.Items {
		fmt.Printf("NameSpace: %v  Name: %v  Status: %v \n", v.Namespace, v.Name, v.Status.Phase)
	}
}

4.2 ClientSet

ClientSet инкапсулирует методы управления Resouorce и Version на основе RestClient.Resource может пониматься как клиент, а ClientSet — это совокупность нескольких клиентов

При работе с ресурсным объектом вам нужно указать Группу, указать Версию, а затем получить ее в соответствии с Ресурсом, но клиентский набор не поддерживает пользовательский crd.

package main

import (
	"flag"
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	"path/filepath"
)

// ~/.kube/config
func ParseConfig(configPath string) (*kubernetes.Clientset, error) {
	var kubeconfigPath *string
	if home := homedir.HomeDir(); home != "" {
		kubeconfigPath = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
	} else {
		kubeconfigPath = flag.String("kubeconfig", configPath, "absolute path to the kubeconfig file")
	}
	flag.Parse()
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfigPath)
	if err != nil {
		return nil, err
	}
	// 生成clientSet
	clientSet, err := kubernetes.NewForConfig(config)
	if err != nil {
		return clientSet, err
	}
	return clientSet, nil
}

func ListCm(c *kubernetes.Clientset, ns string) error {
	configMaps, err := c.CoreV1().ConfigMaps(ns).List(metav1.ListOptions{})
	if err != nil {
		return err
	}
	for _, cm := range configMaps.Items {
		fmt.Printf("configName: %v, configData: %v \n", cm.Name, cm.Data)
	}
	return nil
}

func ListNodes(c *kubernetes.Clientset) error {
	nodeList, err := c.CoreV1().Nodes().List(metav1.ListOptions{})
	if err != nil {
		return err
	}
	for _, node := range nodeList.Items {
		fmt.Printf("nodeName: %v, status: %v", node.GetName(), node.GetCreationTimestamp())
	}
	return nil
}

func ListPods(c *kubernetes.Clientset, ns string) {
	pods, err := c.CoreV1().Pods(ns).List(metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	for _, v := range pods.Items {
		fmt.Printf("namespace: %v podname: %v podstatus: %v \n", v.Namespace, v.Name, v.Status.Phase)
	}
}

func ListDeployment(c *kubernetes.Clientset, ns string) error {
	deployments, err := c.AppsV1().Deployments(ns).List(metav1.ListOptions{})
	if err != nil {
		return err
	}
	for _, v := range deployments.Items {
		fmt.Printf("deploymentname: %v, available: %v, ready: %v", v.GetName(), v.Status.AvailableReplicas, v.Status.ReadyReplicas)
	}
	return nil
}

func main() {
	var namespace = "kube-system"
	configPath := "../config"
	config, err := ParseConfig(configPath)
	if err != nil {
		fmt.Printf("load config error: %v\n", err)
	}
	fmt.Println("list pods")
	ListPods(config, namespace)
	fmt.Println("list cm")
	if err = ListCm(config, namespace); err != nil {
		fmt.Printf("list cm error: %v", err)
	}
	fmt.Println("list nodes")
	if err = ListNodes(config); err != nil {
		fmt.Printf("list nodes error: %v", err)
	}
	fmt.Println("list deployment")
	if err = ListDeployment(config, namespace); err != nil {
		fmt.Printf("list deployment error: %v", err)
	}
}

4.3 DynamicClient

DynamicClient – это динамический клиент, который может выполнять операции покоя с любым ресурсом, включая пользовательские ресурсы crd. В отличие от набора клиентов, объект, возвращаемый динамическим клиентом, представляет собой интерфейс map[string]{}. Если контроллеру необходимо управлять всеми API, динамический клиент может be used, который в настоящее время используется в сборщике мусора и контроллере пространства имен. Процесс обработки DynamicClient преобразует ресурс, такой как подлист, в неструктурированный тип. Все ресурсы k8s могут быть преобразованы в этот тип структуры. После обработки он преобразуется в подлист. Весь процесс преобразования аналогичен преобразованию интерфейса, которое осуществляется через утверждение интерфейса{}.

Динамический клиент — это динамический клиент, который может обрабатывать все ресурсы kubernetes и поддерживает только JSON.

package main

import (
	"fmt"
	apiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/tools/clientcmd"
)

var namespace = "kube-system"

func main() {

	config, err := clientcmd.BuildConfigFromFlags("", "../config")
	if err != nil {
		panic(err)
	}

	dynamicClient, err := dynamic.NewForConfig(config)
	if err != nil {
		panic(err)
	}
	// 定义组版本资源
	gvr := schema.GroupVersionResource{Version: "v1", Resource: "pods"}
	unStructObj, err := dynamicClient.Resource(gvr).Namespace(namespace).List(metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	podList := &apiv1.PodList{}

	if err = runtime.DefaultUnstructuredConverter.FromUnstructured(unStructObj.UnstructuredContent(), podList); err != nil {
		panic(err)
	}

	for _, v := range podList.Items {
		fmt.Printf("namespaces:%v  name:%v status:%v \n", v.Namespace, v.Name, v.Status.Phase)
	}
}

4.4 DiscoveryClient

DiscoveryClient — это клиент обнаружения. Он в основном используется для обнаружения групп ресурсов, версий ресурсов и информации о ресурсах, поддерживаемых сервером API. Сервер API k8s поддерживает множество групп ресурсов, версий ресурсов и информации о ресурсах. В настоящее время вы можете просмотреть его через DiscoveryClient. .

API-версия и API-ресурс kubectl также реализуются через DiscoveryClient, а информация также может кэшироваться в локальном кеше, чтобы уменьшить давление доступа API.По умолчанию в ./kube/cache и ./kube /http-кэш.

package main

import (
	"fmt"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/discovery"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	config, err := clientcmd.BuildConfigFromFlags("", "../config")
	if err != nil {
		panic(err)
	}
	discoverClient, err := discovery.NewDiscoveryClientForConfig(config)
	if err != nil {
		panic(err)
	}
	_, apiResourceList, err := discoverClient.ServerGroupsAndResources()
	for _, v := range apiResourceList {
		gv, err := schema.ParseGroupVersion(v.GroupVersion)
		if err != nil {
			panic(err)
		}
		for _, resource := range v.APIResources {
			fmt.Println("name:", resource.Name, "    ", "group:", gv.Group, "    ", "version:", gv.Version)
		}
	}

}

5 других

Изучив client-go, вы можете легко использовать его для управления ресурсами кластера k8s, kubeconfig→rest.config→clientset→конкретный клиент (CoreV1Client)→конкретный ресурсный объект (pod)→RESTClient→http.Client→HTTP-запрос Отправить и ответить

Такие операции, как добавление, удаление, изменение и проверка объектов ресурсов в kubernetes, реализуются с помощью методов разных клиентов в наборе клиентов и разных объектов ресурсов в клиенте.Часто используемые клиенты включают CoreV1Client, AppsV1beta1Client, ExtensionsV1beta1Client и т. д.

Эта статья посвящена простому использованию client-go для реализации простых операций с ресурсами k8s Позже, использование kubebuilder и operator-SDK для написания операторов также потребует глубокого понимания и изучения client-go. Продолжите углубленное изучение позже.

Ссылка на ссылку