こんにちはACS事業部の谷合です。
数日前に小ネタでGitHub Copilotでバッチファイルを書いてみる記事が投稿されていました。
負けてられんということで、今回は表題の通り、GitHub CopilotでKubernetes Operatorを書いてみます。
本記事のゴール
今回はGitHub Copilotで以下フローでHello World
を出力するKubernetes Operatorを書くことをゴールとします。
1. CustomResourceの.spec.msgフィールドにWorld
を指定してデプロイする
2. CustomControllerで、Hello
と .spec.msgの World
を結合する
3. CustomControllerログとkubectl getの結果にHello World
を出力する
実装
早速GitHub Copilot君と頑張って実装していきます。
Projectを作成
今回のProject名はk8soperator-loves-githubcopilot
なんて名前にしました。
mkdir k8soperator-loves-githubcopilot cd k8soperator-loves-githubcopilot/ kubebuilder init --domain jnytnai0613.github.io --repo github.com/<user_name>/k8soperator-loves-githubcopilot kubebuilder create api --group k8soperatorlovesgithubcopilot --version v1 --kind HelloWorld
API実装
ここではCustomResourceのフィールドとkubectl getで出力する列を定義します。
まず、Specフィールドを定義します。
今回はユーザに World
を指定させたいので、Msgフィールドを定義します。
次に、Statusフィールドを定義します。
こちらも同様に数文字書いただけでほしいコードが出てきます。
続けて、kubectl getで出力する列を定義します。
今回は.Status.FullMsgに代入した値を出力させます。
しかし、意図したコードが提案されませんでした。
そこで、少し続きを書いていくことで、意図したコードがやっと出てきました。
これにてAPI実装は終了です。
Controller実装
いよいよOperatorの大元、CustomControllerの実装に入ります。
まず、CustomControllerのReconcile Loopのレシーバを構造体として定義します。
なお、Reconcile Loopとはなんぞやと思った方は以下の記事をご確認ください。
techblog.ap-com.co.jp
続けて、Reconcile Loopの中身を実装します。
通常、CuctomResourceを変数として定義するのですが、varと記載しただけでコードが出てきました!
CuctomResourceを取得します。
これもすぐに出てきますね。恐るべし、GitHub Copilot...
次に、CuctomResourceの.spec.msgフィールドの値と、Hello
文字列を結合して変数に格納します。
このコードですが、意図しないコードが提案されました。
こちらもAPI実装のkubectl getの列定義の際と同様に続きを書いていくことで、意図したコードが提案されました。
さて、CustomResourceのstatusフィールドを更新する処理を書きましょう...はい、これも教えてくれるんだね。
最後に、Eventを更新しましょう。これもGitHub Copilot君が教えてくれます。 ここまでで、Controllerの実装は完了です。
main実装
Reconcilerのレシーバ構造体に値を渡すコードを書きますが、これもいい感じに書いてくれます。
これにて全実装完了です。
なお、ここまで実装したコードはWindowsであれば、Ctrl + Enterで複数候補を提案してもらうことができます。
動作確認
早速実装したOperatorの動作を確認していきましょう。
CRDデプロイ
make manifests make install
Operator実行
make run test -s /home/junya/k8soperator-loves-githubcopilot/bin/controller-gen && /home/junya/k8soperator-loves-githubcopilot/bin/controller-gen --version | grep -q v0.11.3 || \ GOBIN=/home/junya/k8soperator-loves-githubcopilot/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.11.3 /home/junya/k8soperator-loves-githubcopilot/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases /home/junya/k8soperator-loves-githubcopilot/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..." go fmt ./... go vet ./... go run ./cmd/main.go 2023-05-31T23:14:50+09:00 INFO controller-runtime.metrics Metrics server is starting to listen {"addr": ":8080"} 2023-05-31T23:14:50+09:00 INFO setup starting manager 2023-05-31T23:14:50+09:00 INFO Starting server {"path": "/metrics", "kind": "metrics", "addr": "[::]:8080"} 2023-05-31T23:14:50+09:00 INFO Starting server {"kind": "health probe", "addr": "[::]:8081"} 2023-05-31T23:14:50+09:00 INFO Starting EventSource {"controller": "helloworld", "controllerGroup": "k8soperatorlovesgithubcopilot.jnytnai0613.github.io", "controllerKind": "HelloWorld", "source": "kind source: *v1.HelloWorld"} 2023-05-31T23:14:50+09:00 INFO Starting Controller {"controller": "helloworld", "controllerGroup": "k8soperatorlovesgithubcopilot.jnytnai0613.github.io", "controllerKind": "HelloWorld"} 2023-05-31T23:14:50+09:00 INFO Starting workers {"controller": "helloworld", "controllerGroup": "k8soperatorlovesgithubcopilot.jnytnai0613.github.io", "controllerKind": "HelloWorld", "worker count": 1}
CustomResourceデプロイ
kubectl create namespace k8soperator-loves-githubcopilot-system cat << EOT | kubectl apply -f - apiVersion: k8soperatorlovesgithubcopilot.jnytnai0613.github.io/v1 kind: HelloWorld metadata: name: helloworld-sample namespace: k8soperator-loves-githubcopilot-system spec: msg: "World" EOT
Operator確認
以下の出力を確認できるはずです。
2023-05-31T23:14:58+09:00 INFO Msg: Hello World {"controller": "helloworld", "controllerGroup": "k8soperatorlovesgithubcopilot.jnytnai0613.github.io", "controllerKind": "HelloWorld", "HelloWorld": {"name":"helloworld-sample","namespace":"k8soperator-loves-githubcopilot-system"}, "namespace": "k8soperator-loves-githubcopilot-system", "name": "helloworld-sample", "reconcileID": "bb068f74-2c51-4b28-a5bd-9e507a8b1f94"}
kubectl getコマンドでも以下のように実装結果が確認できます。
kubectl -n k8soperator-loves-githubcopilot-system get helloworlds.k8soperatorlovesgithubcopilot.jnytnai0613.github.io NAME MSG AGE helloworld-sample Hello World 4m57s
また、Eventでも確認可能です。
kubectl -n k8soperator-loves-githubcopilot-system describe helloworlds.k8soperatorlovesgithubcopilot.jnytnai0613.github.io Name: helloworld-sample Namespace: k8soperator-loves-githubcopilot-system : Spec: Msg: World Status: Full Msg: Hello World Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Updated 3s helloworld-controller Updated HelloWorld
さいごに
いやぁ、GitHub Copilot最高ですよね。
使い始めて数時間で、瞬く間に虜になりました。
あまりに簡単に実装できて、これがない生活には戻れそうにはありません。
とは言っても、以下のFrequently asked questions
記載の通り、完璧なコードを書いてくれるわけではありません。
GitHub Copilot君の相棒としてよりよいコードを一緒に書いていけるよう、エンジニアとしてレベルアップしていかねば!
ACS事業部のご紹介
私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。
www.ap-com.co.jp
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。
www.ap-com.co.jp