4. Checkpoint: Check custom resource and codes
4.1. Overview
- Create
CustomResourceDefinition
foos.example.com
. - Create
Foo
object. - Read the
Foo
object 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
kubeconfig
from flag.If home is detected, use
~/.kube/config
as default, otherwise,-kubeconfig
argument 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-controller
go mod tidy go build
Register the CRD.
kubectl apply -f config/crd/foos.yaml
Run sample-controller.
./sample-controller
Result: no
Foo
existslength of foos is 0
Create sample foo (custom resource) with
config/sample/foo.yaml
.apiVersion: example.com/v1alpha1 kind: Foo metadata: name: foo-sample spec: deploymentName: foo-sample replicas: 1
kubectl apply -f config/sample/foo.yaml
Run the controller again.
./sample-controller length of foos is 1
Clean up Foo (custom resource).
kubectl delete -f config/sample/foo.yaml