client-go连接数

单节点k8s集群 v1.19.0

服务创建的https连接数量

client-go用于访问kube-apiserver,可以list/watch k8s资源。

组件名称

访问kube-apiserver方式

单个实例的https连接数

kube-scheduler

本机ip

2

kube-controller-manager

本机ip

2

coredns

service cluster ip

1

kube-proxy

本机ip

1

kubelet

本机ip

1

kube-flannel-ds

service cluster ip

1

client-go走http和https不同点

走http

client-go通过http访问kube-apiserver时,list/watch每种类型的k8s资源,都会创建1条长连接。
clientset发送http请求访问kube-apiserver时,会新起http短连接。因为要走http2复用连接,需要https。

走https

client-go默认通过https访问kube-apiserver时,只建立一条长连接,原因是http2复用连接,maxConcurrentStreams会影响创建的连接数。
http2客户端默认maxConcurrentStreams是100,kube-apiserver默认maxConcurrentStreams是250。
当协商完成之前,maxConcurrentStreams是100,如果瞬间请求量超过100,那么新建连接。
当协商完成之后,maxConcurrentStreams是250,不新建连接。
kube-apiserver从v1.25版本开始,默认maxConcurrentStreams从250改成100,减小服务端压力。

验证只有1条https长连接

创建多个kubeconfig和clientset依然只有1条https长连接。

package main

import (
	"os"
	"os/signal"
	"syscall"

	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/clientcmd"
	klog "k8s.io/klog/v2"
)

func SetupSignalHandler() (stopCh <-chan struct{}) {
	stop := make(chan struct{})
	c := make(chan os.Signal, 2)
	signal.Notify(c, []os.Signal{os.Interrupt, syscall.SIGTERM}...)
	go func() {
		<-c
		close(c)
		close(stop)
	}()

	return stop
}

func addListWatchCfgAndClient(stopCh <-chan struct{}) {
	cfg, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
	if err != nil {
		klog.Fatalf("Error building kubeconfig: %s", err.Error())
	}

	kubeClient, err := kubernetes.NewForConfig(cfg)
	if err != nil {
		klog.Fatalf("Error building kubernetes clientset: %s", err.Error())
	}

	informerFactory := informers.NewSharedInformerFactory(kubeClient, 0)
	hasSynced := informerFactory.Core().V1().Nodes().Informer().HasSynced
	informerFactory.Core().V1().Nodes().Lister()

	informerFactory.Start(stopCh)
	// defer informerFactory.Shutdown()

	if ok := cache.WaitForCacheSync(stopCh, hasSynced); !ok {
		klog.Fatalf("failed to wait for caches to sync")
	}

	cfg1, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
	if err != nil {
		klog.Fatalf("Error building kubeconfig: %s", err.Error())
	}

	kubeClient1, err := kubernetes.NewForConfig(cfg1)
	if err != nil {
		klog.Fatalf("Error building kubernetes clientset: %s", err.Error())
	}

	informerFactory1 := informers.NewSharedInformerFactory(kubeClient1, 0)
	hasSynced1 := informerFactory1.Core().V1().Endpoints().Informer().HasSynced
	informerFactory1.Core().V1().Endpoints().Lister()

	informerFactory1.Start(stopCh)
	// defer informerFactory.Shutdown()

	if ok := cache.WaitForCacheSync(stopCh, hasSynced1); !ok {
		klog.Fatalf("failed to wait for caches to sync")
	}
}

func main() {
	stopCh := SetupSignalHandler()
	addListWatchCfgAndClient(stopCh)
	<-stopCh
}

posted on 2024-01-14 16:01  王景迁  阅读(45)  评论(0编辑  收藏  举报

导航