Supported commands: ls, cd ${PATH}

The Kubebuilder Quick Start

Dec. 14, 2021

칼끝에 선 개발자를 위한 Note

오퍼레이터 기본 개념: http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791161754789&orderClick=LAG&Kc=

오퍼레이터 개발 도구: https://book.kubebuilder.io/

오퍼레이터 best practices 개요: https://github.com/cncf/tag-app-delivery/blob/main/operator-wg/whitepaper/Operator-WhitePaper_v1-0.md#emerging-patterns-of-the-future

Installation

brew install kubebuilder

Create a Project

mkdir guestbook
cd guestbook
kubebuilder init --domain my.domain --repo my.domain/guestbook

Create an API

kubebuilder create api --group webapp --version v1 --kind Guestbook

그렇다면 Resource와 Controller를 생성하지 않으면 어떻게 되는가?

Create Resource [y/n]
n
Create Controller [y/n]
n
diff --git a/guestbook/PROJECT b/guestbook/PROJECT
index f7ecce0..9310789 100644
--- a/guestbook/PROJECT
+++ b/guestbook/PROJECT
@@ -3,4 +3,9 @@ layout:
 - go.kubebuilder.io/v3
 projectName: guestbook
 repo: my.domain/guestbook
+resources:
+- domain: my.domain
+  group: webapp
+  kind: Guestbook
+  version: v1
 version: "3"
Create Resource [y/n]
y
# api definition, CRD, rbac등을 생성
Create Controller [y/n]
y
# ${PROJECT}_controller.go 코드 생성
diff --git a/guestbook/PROJECT b/guestbook/PROJECT
index f7ecce0..8a42803 100644
--- a/guestbook/PROJECT
+++ b/guestbook/PROJECT
@@ -3,4 +3,14 @@ layout:
 - go.kubebuilder.io/v3
 projectName: guestbook
 repo: my.domain/guestbook
+resources:
+- api:
+    crdVersion: v1
+    namespaced: true
+  controller: true
+  domain: my.domain
+  group: webapp
+  kind: Guestbook
+  path: my.domain/guestbook/api/v1
+  version: v1
 version: "3"

Write logic

diff --git a/guestbook/config/samples/webapp_v1_guestbook.yaml b/guestbook/config/samples/webapp_v1_guestbook.yaml
index b7226ed..0b6802a 100644
--- a/guestbook/config/samples/webapp_v1_guestbook.yaml
+++ b/guestbook/config/samples/webapp_v1_guestbook.yaml
@@ -4,3 +4,4 @@ metadata:
   name: guestbook-sample
 spec:
   # TODO(user): Add fields here
+  foo: guestbook-sample
diff --git a/guestbook/controllers/guestbook_controller.go b/guestbook/controllers/guestbook_controller.go
index cb92e51..79fbbbc 100644
--- a/guestbook/controllers/guestbook_controller.go
+++ b/guestbook/controllers/guestbook_controller.go
@@ -50,6 +50,15 @@ func (r *GuestbookReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
 	_ = log.FromContext(ctx)

 	// TODO(user): your logic here
+	guestBook := &webappv1.Guestbook{}
+	_ = r.Get(ctx, req.NamespacedName, guestBook)
+
+	if guestBook.Spec.Foo != "bar" {
+		println("Reconciling..")
+		guestBook.Spec.Foo = "bar"
+
+		_ = r.Update(ctx, guestBook, &client.UpdateOptions{})
+	}

 	return ctrl.Result{}, nil
 }

Install the CRDs into the cluster

make install

Run controller

# At shell 1
make run
# At shell 2
kubectl apply -f config/samples/

Result

(kubernetes-admin-dev@dev) ☁  guestbook [main] ⚡  make run
~/Projects/d-controller/guestbook/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
~/Projects/d-controller/guestbook/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."
go fmt ./...
api/v1/zz_generated.deepcopy.go
go vet ./...
go run ./main.go
2021-12-13T15:55:09.156+0900	INFO	controller-runtime.metrics	metrics server is starting to listen	{"addr": ":8080"}
2021-12-13T15:55:09.156+0900	INFO	setup	starting manager
2021-12-13T15:55:09.156+0900	INFO	starting metrics server	{"path": "/metrics"}
2021-12-13T15:55:09.156+0900	INFO	controller.guestbook	Starting EventSource	{"reconciler group": "webapp.my.domain", "reconciler kind": "Guestbook", "source": "kind source: /, Kind="}
2021-12-13T15:55:09.157+0900	INFO	controller.guestbook	Starting Controller	{"reconciler group": "webapp.my.domain", "reconciler kind": "Guestbook"}
2021-12-13T15:55:09.258+0900	INFO	controller.guestbook	Starting workers	{"reconciler group": "webapp.my.domain", "reconciler kind": "Guestbook", "worker count": 1}
Reconciling..