Введение в 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. Продолжите углубленное изучение позже.