Operatorを作ってみた。Controller)の一種。Controllerが汎用的なのに対して、特定のアプリケーションに特化しているのが特徴。アプリケーションごとの細かな設定をKubernetesオブジェクトで表現するために、KubernetesのAPIを拡張する。(CRD)を使う方法がある。Aggregationは、Kubernetesオブジェクトをetcd以外で管理したり、WebSocketを使ったり、Kubernetesクラスタ外のAPIサーバを使う場合など、特殊な場合にも対応できる高度なやりかたで、大抵のユースケースではCRDで事足りる。Operatorも普通はCRDを使う。(というかCRDを使うのがOperatorという人もいる。)CRDとはKubernetesのAPIを簡単に拡張できる仕組みで、Kubernetesオブジェクト(リソース)を定義するKubernetesオブジェクト。APIとかkubectlで作成したり取得したりできるようになる。Operatorの仕組みOperatorは、CRDで定義されたリソース(など)の作成、更新、削除を監視(watch)して、リソースの内容に応じた何らかの処理をするReconciliationループを回すPod。普通、リソースはOperatorの管理対象のアプリケーションの状態を表す。Operatorはリソースの内容とアプリケーションの状態が同じになるように、Reconciliationループ内でDeploymentを作ったりアプリケーションのAPIを叩いたりする。ユーザとしては、アプリケーションの構成や設定をKubernetesのAPIで宣言的に統一的に管理できるようになって幸せになれる。Operator作成ツールOperatorを作るツールとして以下がある。プロジェクトテンプレート生成、ビルド、デプロイをするCLIツール。AnsibleでもOperatorを書けるのが面白い。Managerなどが提供されていたり、OperatorHub.ioというコミュニティサイトがあったり、エコシステムが充実している。プロジェクトテンプレート生成、ビルド、デプロイをするCLIツール。3つの中で一番シンプル。Goでしか開発できない。他の2つと毛色が違って、Metacontroller自体が汎用的にOperatorを管理するKubernetesアプリ。Operatorの定義をJSONを投げて登録すると、Reconciliationループを回してその中でWebフックを実行してくるので、それを受けて任意の処理をするサーバを任意の言語で書ける。SDKが数歩リードしている感じ。Hatが後ろ盾ているし、OperatorHub.ioはGCPとAWSとAzureが協力している。この記事のネタを書き始めたときにはまだOperatorHub.ioが発表されていなくて、単純にKubebuilderがシンプルでいいと思って採用してしまった。Frameworkへの移行も難しくなかろう。CRDで定義したリソースは以下。作るとズンドコきよしを開始する。「ズン」と「ドコ」を表す。Hikawaに管理される。「キ・ヨ・シ!」を表す。Hikawaに管理される。Operatorは、HikawaとZundokoをwatchする。Hikawaが作成されると、一定間隔で、ランダムに「ズン」か「ドコ」をセットしたZundokoを作成する。「ズン」を4つ作ったあとに「ドコ」を作ったら、Kiyoshiを作成して、Zundokoの作成を止める。Kuberbuilderを使うにはGo、depとkustomizeとDockerが必要で、Linuxしかサポートしていない。18.04)で環境を作ったんだけど、結局Dockerビルドとかテストとかが上手く動かなかったので、VMとかのLinuxで動かしたほうがよさそう。KubebuilderセットアップGoインストールGoは公式サイトからLinux用アーカイブをダウンロードして展開して、そのbinディレクトリにPATH通すだけでインストールできる。linux/amd64あと、作業ディレクトリを作ってGOPATHを設定しておく。~/go/を作業ディレクトリとする。$GOPATH/srcで、$GOPATH/binにもPATH通しておく。depインストールGo公式の依存ライブラリ管理ツール。コマンド一発でインストールできる。shkustomizeインストールバイナリをPATHの通ったところにダウンロードするだけ。/usr/local/bin/kustomizekubebuilderインストールGitHubのReleasesからアーカイブをダウンロードして展開してPATH通すだけ。Operatorのプロジェクトを生成する。ensureを実行するかを聞かれるのでyesで回答すると、依存ライブラリがダウンロードされ、プロジェクトのビルドが走る。デフォルトではCRDなどの名前空間がk8s.ioになっているので、kaitoy.github.comに変えるべく、zundoko-operator/PROJECTを編集する。github.com/kaitoy/zundoko-operatorCRDとController生成HikawaとZundokoとKiyoshiのCRDを生成する。リソースはそれぞれ作成して、ControllerはHikawaにだけ作成した。生成されたのは以下のファイル。API定義をもとに生成されるので、API定義を書いた後生成しなおすことになる。API定義記述リソースがどのような属性をもつかをGoで定義する。テンプレートは生成されているので、ちょっと書き足すだけでできる。以下はHikawaのAPI定義。&HikawaList{})}自分で書いたのはHikawaSpecとHikawaStatusの中だけ。Specの方には期待する状態、Statusの方には現在の実際の状態を表すフィールドを定義するのがパターン。HikawaSpec.NumZundokosが期待するZundokoの数で、HikawaStatus.NumZundokosSaidが実際に作成されたZundokono数。ControllerはReconciliationループの中で、SpecとStateが同じになるように処理をすることになる。ZundokoとKiyoshiのAPI定義は、Specに「Zun」、「Doko」、または「Kiyoshi!」を入れるためのSayフィールドだけを書いた。Controllerもテンプレートが生成されているので、それを参考に書ける。どのリソースをwatchするかを書く。nil}Hikawaは普通にwatchして、Zundokoはownしているリソースとしてwatchしている。Reconciliationループは以下のように書いた。ControllerはHikawaとZundokoとKiyoshiを作ったり取得したりする必要があるので、それっぽく書いた。watchしているリソースの作成・更新・削除のたびにReconcile()が呼ばれるので、そのなかでは対象となるHikawaを取得して期待されている状態を調べたり、Zundokoのリストを取得して現状を確認したり、リソースを更新したりして、reconcile.Result{}をreturnする。reconcile.Result{}が何なのかドキュメントにも記載が無くてよくわからないが、いつも空でreturnしておくのが無難っぽい。errorオブジェクトをreturnすると、若干のインターバルののち再度Reconcile()が呼ばれる。リソースの削除時になにか処理をしたいときは、Finalizerという仕組みが使える。Zundokoを作成するcreateZundoko()は以下。nil}controllerutil.SetControllerReference()で、作成するZundokoにHikawaをownerとして紐づけている。Collectionされる。CRDなどの再生成API定義などの記述を反映させるため、CRDとかrbac_role.yamlとかzz_generated.deepcopy.goを再生成する。OperatorはPodとして動かすので、そのDockerイメージをビルドしておく必要がある。DockerfileもKubebuilderが生成してくれているので、それをそのまま使えばいい。OperatorをデプロイするKubernetesマニフェストはkustomizeで生成する。生成する前に、kustomizeのパッチファイルであるzundoko-operator/config/default/manager_image_patch.yamlを編集して、spec.template.spec.containers[].imageにさっきビルドしたDockerイメージの名前を書いておく。managerで、以下のコマンドで生成できる。applyしてやればいい。zundoko-operator/zundoko-operator.yamlHikawa作成Hikawaを登録するとズンドコしはじめる。1.8のアクセス制御について。あとDashboard。dockerKubernetes1.8のクラスタを構築する。