本連載の第23回で、Kubernetesの拡張性を活かし、システム固有の運用作業を自動化するものとして「Kubernetes Operator」を紹介しました。

今回取り上げる「Kubebuilder」は、Kubernetes Operatorを作るためのScaffolding(土台)ツールです。Kubebuilderを使えば、CRD(Custom Resource Definition)やカスタムコントローラのひな型を自動生成することができます。Kubernetes Operatorを構成するさまざまなファイル群を一から作成する必要がないため、学習コストを下げられることに加え、素早くKubernetes Operatorを構築することが可能です。

では早速、Kubebuilderを使ってKubernetes Operatorを作ってみましょう。以降は、Kubebuilder公式サイトのQuick Startの手順に沿って実施します。

  1. 事前条件
  2. Kubebuilderコマンドのインストール
  3. Kubernetes Operatorのベース作成
    • プロジェクトの作成(kubebuilder init)
    • APIの作成(kubebuilder create api)
  4. Kubernetes Operatorを実行する
    • CRDの組み込み(make install)
    • カスタムコントローラーの実行(make run)
  5. 実行結果の確認

1. 事前条件

構築を始める前に、まず環境を整えましょう。それぞれ、以下のバージョン以上のものがインストールされている必要があります。

  • go:v1.16
  • docker:v17.03
  • kubectl:v1.11.3
  • Kubernetes cluster:v1.11.3

2. Kubebuilderコマンドのインストール

まずは、kubebuilderコマンドをインストールしましょう。

最新のバイナリをcurlで取得し、実行可能な状態にします。

$curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)
$chmod +x kubebuilder && mv kubebuilder /usr/local/bin/

インストールされたkubebuilderコマンドのバージョンは以下の通りです。

$kubebuilder version
Version: main.version{KubeBuilderVersion:"3.1.0", KubernetesVendor:"unknown", GitCommit:"92e0349ca7334a0a8e5e499da4fb077eb524e94a",
BuildDate:"2021-05-29T06:00:59+01:00", GoOs:"darwin", GoArch:"amd64"}

3. Kubernetes Operatorのベース作成

次に、Kubebuilderを使って、Kubernetes Operatorのベースを作成します。

プロジェクトの作成(kubebuilder init)

プロジェクトを作成してみましょう。

$kubebuilder init --domain localhost --repo localhost/guestbook
Writing kustomize manifests for you to edit...
Writing scaffold for you to edit...
Get controller runtime:
$ go get sigs.k8s.io/controller-runtime@v0.8.3
Update dependencies:
$ go mod tidy
Next: define a resource with:
$ kubebuilder create api

以下のファイルが生成されます。ここでは、まだKubernetes Operatorに必要なCRDやControllerは生成されていません。

イメージ

APIの作成(kubebuilder create api)

GuestbookカスタムリソースのAPIを作成します。

$kubebuilder create api --group webapp --version v1 --kind Guestbook
Create Resource [y/n]
y
Create Controller [y/n]
y
Writing kustomize manifests for you to edit...
Writing scaffold for you to edit...
api/v1/guestbook_types.go
controllers/guestbook_controller.go
Update dependencies:
$ go mod tidy
Running make:
$ make generate
go: creating new go.mod: module tmp
Downloading sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1
go get: added sigs.k8s.io/controller-tools v0.4.1
/Users/xxxxxxx/kubebuilder/example/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."

上記コマンドにより、以下①②が作成されました。

①api/v1/guestbook_types.go:CRDに関する定義を書くファイル。 ②controllers/guestbook_controller.go:Reconcile関数にコントローラの挙動を書きます。

①②のファイルの配置は以下の通りです。

イメージ

4. Kubernetes Operatorを実行する

Kubernetes Operatorを実行するための準備を整えていきます。

CRDの組み込み(make install)

GuestbookカスタムリソースのCRDをクラスタに組み込みます。

$make install
/Users/xxxxxx/kubebuilder/example/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/Users/xxxxxx/kubebuilder/example/bin/kustomize build config/crd | kubectl apply -f -
customresourcedefinition.apiextensions.k8s.io/guestbooks.webapp.localhost created

CRDが作成されているか確認してみましょう。

$kubectl get crd|grep guestbooks
guestbooks.webapp.localhost                   2021-09-04T08:56:37Z

CRDに対応するカスタムリソース(kindがGuestbook)を作ってみましょう。

$kubectl apply -f config/samples/
guestbook.webapp.localhost/guestbook-sample created
$kubectl get Guestbook
NAME               AGE
guestbook-sample   69s

カスタムコントローラの実行(make run)

GuestBookカスタムリソースを取り扱う、カスタムコントローラを実行します。

$make run
/Users/xxxxxx/kubebuilder/example/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/Users/xxxxxx/kubebuilder/example/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."
go fmt ./...
go vet ./...
go run ./main.go
I0904 17:57:39.425761   62041 request.go:655] Throttling request took 1.021041764s, request: GET:https://127.0.0.1:59652/apis/extensions/v1beta1?timeout=32s
2021-09-04T17:57:42.188+0900    INFO    controller-runtime.metrics  metrics server is starting to listen    {"addr": ":8080"}
2021-09-04T17:57:42.188+0900    INFO    setup   starting manager
2021-09-04T17:57:42.189+0900    INFO    controller-runtime.manager  starting metrics server {"path": "/metrics"}
2021-09-04T17:57:42.189+0900    INFO    controller-runtime.manager.controller.guestbook Starting EventSource    {"reconciler group": "webapp.my.domain", "reconciler kind": "Guestbook", "source": "kind source: /, Kind="}
2021-09-04T17:57:42.290+0900    INFO    controller-runtime.manager.controller.guestbook Starting Controller {"reconciler group": "webapp.my.domain", "reconciler kind": "Guestbook"}
2021-09-04T17:57:42.290+0900    INFO    controller-runtime.manager.controller.guestbook Starting workers    {"reconciler group": "webapp.my.domain", "reconciler kind": "Guestbook", "worker count": 1}

* * *

今回は、Kubebuilderを使って簡単な手順を踏むことで、Kubernetes Operatorを作ってみました。実際手を動かしてみたことで、CRDやカスタムコントローラに対する理解が深まったのではないでしょうか? 今回は公式サイトのサンプルで作ってみましたが、ぜひ、皆さんのシステム要件に合わせた独自のKubernetes Operatorを作ってみてください。

著者紹介


正野 勇嗣 (SHONO Yuji ) - NTTデータ 部長

2011年まで開発自動化技術のR&Dに従事。その後、開発プロジェクト支援やトラブルシューティング等に主戦場を移す。「ソースコード自動生成」に加えて、JenkinsやMaven等の「ビルド自動化」、JsTestDriverやSelenium等の「テスト自動化」を扱うようになり、多様化する開発自動化技術動向に興味。

最近は第四の自動化であるInfrastructure as Code等の「基盤自動化」の魅力に惹かれている。開発自動化技術に関する雑誌・記事執筆も行う。3児のパパ。