4. Checkpoint: Check custom resource and codes
4.1. Overview
- Create
CustomResourceDefinitionfoos.example.com. - Create
Fooobject. - Read the
Fooobject frommain.go.
4.2. Implement
Create main.go.
package main func main() { }Init k8s.io/klog/v2
import ( "k8s.io/klog/v2" )klog.InitFlags(nil)Set
kubeconfigfrom flag.If home is detected, use
~/.kube/configas default, otherwise,-kubeconfigargument is required.import ( "flag" "path/filepath" ... "k8s.io/client-go/util/homedir" )var kubeconfig *string if home := homedir.HomeDir(); home != "" { kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional)") } else { kubeconfig = flag.String("kubeconfig", "", "absolute path to kubeconfig file") } flag.Parse()Set config for Kubernetes client with client-go/tools/clientcmd
config is *restclient.Config
import ( ... "k8s.io/client-go/tools/clientcmd" )config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) if err != nil { klog.Fatalf("Error building kubeconfig: %s", err.Error()) klog.FlushAndExit(klog.ExitFlushTimeout, 1) }Initialize clientset for our custom resource.
import ( clientset "github.com/nakamasato/sample-controller/pkg/generated/clientset/versioned" )exampleClient, err := clientset.NewForConfig(config) if err != nil { klog.Fatalf("Error building example clientset: %s", err.Error()) klog.FlushAndExit(klog.ExitFlushTimeout, 1) }List the custom resource
Foo.import ( "context" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" )foos, err := exampleClient.ExampleV1alpha1().Foos("").List(context.Background(), metav1.ListOptions{}) if err != nil { klog.Fatalf("listing foos %s %s", err.Error()) klog.FlushAndExit(klog.ExitFlushTimeout, 1) } klog.Infof("length of foos is %d", len(foos.Items))
Final main.go:
package main
import (
"context"
"flag"
"path/filepath"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"k8s.io/klog/v2"
clientset "github.com/nakamasato/sample-controller/pkg/generated/clientset/versioned"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func main() {
klog.InitFlags(nil)
var kubeconfig *string
if home := homedir.HomeDir(); home != "" {
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional)")
} else {
kubeconfig = flag.String("kubeconfig", "", "absolute path to kubeconfig file")
}
flag.Parse()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
klog.Fatalf("Error building kubeconfig: %s", err.Error())
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
}
exampleClient, err := clientset.NewForConfig(config)
if err != nil {
klog.Fatalf("Error building example clientset: %s", err.Error())
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
}
foos, err := exampleClient.ExampleV1alpha1().Foos("").List(context.Background(), metav1.ListOptions{})
if err != nil {
klog.Fatalf("listing foos %s %s", err.Error())
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
}
klog.Infof("length of foos is %d", len(foos.Items))
}
4.3. Run and check
Build
sample-controllergo mod tidy go buildRegister the CRD.
kubectl apply -f config/crd/foos.yamlRun sample-controller.
./sample-controllerResult: no
Fooexistslength of foos is 0Create sample foo (custom resource) with
config/sample/foo.yaml.apiVersion: example.com/v1alpha1 kind: Foo metadata: name: foo-sample spec: deploymentName: foo-sample replicas: 1kubectl apply -f config/sample/foo.yamlRun the controller again.
./sample-controller length of foos is 1Clean up Foo (custom resource).
kubectl delete -f config/sample/foo.yaml