티스토리 뷰
Do you have a plan to develop something related to Kubernetes?
Then you should read this blog!
Last few weeks, I spend some time developing CLI to communicate with OpenShift Cluster. During the time, I researched Kubernetes development basics and I realize that there are several important terms and repos which are very useful.
Memorize is limited so I will write the key points here.
- *rest.Config
- Typed Client
- Clientset
- Unstructured Client
- Discovery Client
- RESTMapping
- Dynamic Client
- k8s.io/apimachinery
*rest.Config
This is an object based on kubeconfig file that contains cluster information.
How to get *rest.Config?
package main
import (
"context"
"fmt"
"time"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
}
func main(){
// creates the in-cluster config
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
}
package main
import (
"context"
"flag"
"fmt"
"path/filepath"
"time"
"k8s.io/apimachinery/pkg/api/errors"
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"
)
func main() {
var kubeconfig *string
if home := homedir.HomeDir(); home != "" {
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
} else {
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
}
flag.Parse()
// use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
// create the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
}
- Outside of cluster 2
import "k8s.io/client-go/tools/clientcmd"
...
kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config")
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
Typed Client
This is using Go types defined in k8s.io/api.to represent a kind(Kubernetes object such as pod, route, and so on)
Typical example
clientset, err := kubernetes.NewForConfig(config)
deployment := &appsv1.Deployment{}
deployment.Name = "example"
// edit deployment spec
client := clientset.AppsV1().Deployments(ns)
_, err = client.Create(ctx, deployment, metav1.CreateOptions{})
Clientset contains the clients for groups. Each group has exactly one version included in a Clientset.
In short, it has all clients to do create/read/update/delete for each Go struct object.
type Clientset struct {
*discovery.DiscoveryClient
admissionregistrationV1 *admissionregistrationv1.AdmissionregistrationV1Client
admissionregistrationV1beta1 *admissionregistrationv1beta1.AdmissionregistrationV1beta1Client
internalV1alpha1 *internalv1alpha1.InternalV1alpha1Client
...
}
So if you get a Clientset, you can communicate with Kubernetes
Unstructured Client
This is using unstructured.Unstructured type(json/yaml) and it will be converted to Go structs. In other words, it will create objects from json/yaml file.
Typical example
const dsManifest = `
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: example
namespace: default
spec:
selector:
matchLabels:
name: nginx-ds
template:
metadata:
labels:
name: nginx-ds
spec:
containers:
- name: nginx
image: nginx:latest
`
func main() {
obj := &unstructured.Unstructured{}
// decode YAML into unstructured.Unstructured
dec := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme)
_, gvk, err := dec.Decode([]byte(dsManifest), nil, obj)
// Get the common metadata, and show GVK
fmt.Println(obj.GetName(), gvk.String())
// encode back to JSON
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
enc.Encode(obj)
}
Discovery Client
DiscoveryClient queries API server about the resources
dc, err := discovery.NewDiscoveryClientForConfig(cfg)
RESTMapping
This is for finding GVR (available in *meta.RESTMapping)for GVK from api server
dc, err := discovery.NewDiscoveryClientForConfig(cfg)
if err != nil {
return nil, err
}
mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(dc))
return mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
Dynamic Client
This client is for an unstructured data update.
_, err = dr.Patch(ctx, obj.GetName(), types.ApplyPatchType, data, metav1.PatchOptions{
FieldManager: "sample-controller",
})
k8s.io/apimachinery
This is the baseline for all objects.
The hierarchy of components
Client-go (Tool/frameworks)
Inxexer/Cache/Informer/clientcmd ....
-> Kuberentes Clientset
-> RESTClient
-> k8s.io/api-machinery
Reference
- How to use Dynamic Client
- Client-Go rest Doc
- Client-Go definition
- How to use Client-Go to use CRD
- Discovery client
- Client-go example
'IT > GOLANG' 카테고리의 다른 글
[Issue] Go Module can not find a package (0) | 2021.02.04 |
---|---|
Go를 시작하는 사람들을 위한 Module 이야기 (0) | 2021.02.04 |
- Total
- Today
- Yesterday
- certification
- 온타리오
- 우드워킹
- 인터넷
- cert
- 토론토정착서비스
- 밀튼
- ansible
- TORONTO
- 캐나다부동산
- 미시사가
- 캐나다
- git proGit
- RHEL
- RHCE
- BTBS
- 토론토
- basement
- BC주
- redhat
- 정착서비스
- 부모님초청이민
- 부동산분석
- docker
- Certificate
- Red Hat
- 옥빌
- Canada
- 벌링턴
- Jay
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |