APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

GitHub CopilotでKubernetes Operatorを書いてみる

こんにちはACS事業部の谷合です。

数日前に小ネタでGitHub Copilotでバッチファイルを書いてみる記事が投稿されていました。

techblog.ap-com.co.jp

負けてられんということで、今回は表題の通り、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君の相棒としてよりよいコードを一緒に書いていけるよう、エンジニアとしてレベルアップしていかねば!

github.com

ACS事業部のご紹介

私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。
www.ap-com.co.jp また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。 www.ap-com.co.jp

本記事の投稿者: 谷合純也
AKS/ACAをメインにインフラ系のご支援を担当しています。
junya0530さんの記事一覧 | Zenn