Kubernetes - client-go
https://github.com/kubernetes/client-go
Built-in clients like kubectl and kubelet are all based on client-go.
config + http.Client = RESTClient
vendor/k8s.io/client-go/rest/client.go
vendor/k8s.io/client-go/rest/request.go
ListerWatcher
The ListerWatcher interface in the client-go SDK, used in all Go-based Kubernetes controllers, plays a critical role on how these events are generated, propagated and reliably consumed throughout the various Kubernetes components and actors.
type ListerWatcher interface {
  Lister
  Watcher
}
list and watch
client.Get()
client.Watch()
Cache
client-go cache:
Reflectorwatches a specified resource and causes all changes to be reflected in the given store.Storeis the interface of the cache;ExpirationCacheis one of the implementation.
Package cache is a client-side caching mechanism. It is useful for reducing the number of server calls you'd otherwise need to make. Reflector watches a server and updates a Store. Two stores are provided; one that simply caches objects (for example, to allow a scheduler to list currently available nodes), and one that additionally acts as a FIFO queue (for example, to allow a scheduler to process incoming pods).
Clients
http.Client: Go's built-in HTTP Client.rest.RESTClient:client-goprovides arest.RESTClientthat wraps ahttp.Client.kubernetes.Clientset: a set of typed clients that provides pre-generated local API objects for every core resource type (Pods,Deployments,Services, etc.).dynamic.DynamicClient:client-go/dynamicpackage provides a dynamic client which can perform RESTful operations on arbitrary API resources. Thestruct dynamic.Interfaceusesunstructured.Unstructuredto represent all object values from the API server. The dynamic package defers all data bindings until runtime.
import
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/dynamic"
dynamicClient, err := dynamic.NewForConfig(config)
Configuration
- In-Cluster configuration: used when running inside a pod and uses the service account token mounted to the pod 
/var/run/secrets/kubernetes.io/serviceaccount/token.audshould match API server’s--api-audiencesflag.
 - Out-of-Cluster configuration: used when running outside of the cluster and uses either a provided 
kubeconfigfile or the current user’s defaultkubeconfigfile. 
The controller-runtime library provides a GetConfig() that first attempts Out-of-Cluster configuration, and if it fails, attempts In-Cluster configuration.
Code Examples
RESTClientGetter
  => To RESTConfig: rest.Config ("k8s.io/client-go/rest")
  => To DiscoveryClient: discovery.CachedDiscoveryInterface ("k8s.io/client-go/discovery")
  => To RESTMapper: meta.RESTMapper ("k8s.io/apimachinery/pkg/api/meta")
Retry
import "k8s.io/client-go/util/retry"
retry.RetryOnConflict(retryBackoff, func() error {
    //logic
})
Backoff
ctx := context.Background()
secret := &corev1.Secret{}
if err := retry.OnError(wait.Backoff{
  Duration: 10 * time.Second,
  Steps:    6,
}, func(err error) bool { return true }, func() error {
  if err := c.Get(ctx, client.ObjectKey{
    Namespace: "kube-system",
    Name:      "foo-secret",
  }, secret); err != nil {
    return err
  }
  return nil
}); err != nil {
  return fmt.Errorf("failed to get secret foo-secret: %w", err)
}
Get in cluster rest config
// vendor/k8s.io/client-go/rest/config.go
// creates the in-cluster config
config, err := rest.InClusterConfig()
// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
kubeconfig => clientSet
import (
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  "k8s.io/client-go/kubernetes"
)
bytesArray := []byte(*kubeconfig)
clientConfig ,err:= clientcmd.NewClientConfigFromBytes(bytesArray)
if err!=nil {
	logs.Error(err.Error())
	return nil
}
config, _ := clientConfig.ClientConfig()
clientset, err := kubernetes.NewForConfig(config)
nodes, err := clientset.CoreV1().Nodes().List(context.Background(), metav1.ListOptions{})
kubeconfig => dynamic client
Dynamic client has no knowledge about the resource you want to consume.
config, err := rest.InClusterConfig()
if err != nil {
    return nil, err
}
dynClient, err := dynamic.NewForConfig(config)
if err != nil {
    return nil, err
}
secrets => kubeconfig
capiconfig "sigs.k8s.io/cluster-api/util/kubeconfig"
nn := types.NamespacedName{
  Name: consts.FooName,
  Namespace: consts.FooNamespace,
}
kubeconfig, err := capiconfig.FromSecret(ctx, client, nn)
// kubeconfig []byte
ClientGetter => Client
clientConfig, err := clientGetter.ToRESTConfig()
if err != nil {
    return err
}
client, err := client.New(clientConfig, client.Options{})
if err != nil {
    return err
}
kubeconfig => restconfig
import (
  "k8s.io/client-go/tools/clientcmd"
)
restConfig, err := clientcmd.RESTConfigFromKubeConfig(kubeconfig)
RateLimiter
rateLimiter is passed from config to client to request.