Go言語以外でもk8sオペレータが作りたい
要約
- k8sオペレータとかカスタムコントローラ作ると行ったらGo言語という風潮
- 内部はHTTPなんだし所詮コントローラはただのプログラムなんだから実装は何でも良いでしょ
- OCamlっていう言語で実装してやんよ
- はい、できた
そもそもk8sって
- 宣言的な構成管理ができて
- 自動デプロイや
- スケーリングや
- コンテナ運用のための
オープンソースなプラットフォームですよって。
んじゃk8sのカスタムコントローラとかオペレータって何よ?
- k8s標準リソースとかカスタムリソースを管理するプログラムがカスタムコントローラ
- カスタムコントローラとCRD(カスタムリソース定義)を合わせたものの名称であり、運用自動化を図ったのがオペレータ
待って、待って。そもそも前提知識が過ぎるよ・・・
せやな。
- k8sコンポーネントとは何か
- k8s標準リソースとは何か
- k8sカスタムリソースとは何か
を語るか
k8sコンポーネントって
k8sクラスタが機能するために必要な構成員。
参考: https://kubernetes.io/ja/docs/concepts/overview/components/
引用: https://kubernetes.io/docs/concepts/architecture/cloud-controller/#design
大きく
- マスターコンポーネント(k8s master)
- ノードコンポーネント(k8s minions)
がある。
マスターコンポーネント
んで、マスターコンポーネントは以下のような構成員がある。
Master component
|_ kube-apiserver
|_ etcd
|_ kube-scheduler
|_ kube-controller-manager
|_ cloud-controller-manager
以降は何番煎じくらいの説明なので盛り上がりもクソもない。
kube-apiserver
k8sのAPIを提供するサーバ(コンポーネント)。
こやつがk8sマスターノードの顔。
マスターノードに何かをリクエストする時はこいつにアクセスしる。
etcd
ただのKVS。
全クラスタ情報はここに保存される。
クラスタ情報といってもコンテナ個別のデータではないことに注意。
kube-scheduler
新規のポッドにノードが割り当てられているか監視して、割り当てられていなかったらポッドにノードを割り当てるやつ。
kube-controller-manager
コントローラっていうプログラムを実行するためのコンポーネントや。
まぁコントローラと一口に言っても色んなやつがいるんやが、そいつらはただのプログラムなので1プロセスとして動作する。
ただ、バラバラだと複雑だとかなんだとかで k8s では 実行ファイルを1つにまとめてしまって単一プロセスとして実行できるようにしたのがこれや。
標準のコントローラは彼らやね。
- ノードコントローラ: ノードがダウンした時の通知と処理を行う
- レプリケーションコントローラ: pod数を正しく保つためのもの
- エンドポイントコントローラ: serviceとpodの紐付けを行う
- サービスアカウントとトークンコントローラ: 長ったらしいな。まぁ名前空間毎にデフォルトアカウントとAPIアクセストークンを発行する
ほんと、何番煎じなんだって感じの説明ですまんな。
cloud-controller-manager
k8sクラ歌が稼働しているクラウドプロバイダー用のコントローラ。
これはよう説明できん。ほな。
ノードコンポーネント
まぁマスター以外やな。構成員はこれ。
Node component
|_ kubelet
|_ kube-proxy
|_ コンテナランタイム
kubelet
コンテナがPodで実行されていることを保証する、つまりk8sのマニフェストに従ってどれだけのコンテナを配置するとかそういったPodの管理をする。
kube-proxy
クラスタの内部外部からPodへのネットワーク通信をプロキシする。
コンテナランタイム
コンテナを動かすソフトウェア。はい、そんだけ。
ここまでで何がわかったか
コントローラが通信するお相手。
これはもう絶対に kube-apiserverね。
それかkubelet。
じゃあ次はどんなプロトコルでそいつらと通信しているかがわかれば良さそうやね。
Master-Node Communication
ここ見れ。
参考: https://kubernetes.io/docs/concepts/architecture/master-node-communication/
へいへい、ざっくり解説をば。
ノードからマスターへの通信
これね、APIサーバを経由しますね、ええ。
全ての通信がね。
んで、クライアント認証付きでHTTPSですよ。
さらに1つまたは複数の認証で匿名リクエストやサービスアカウントでのアクセスも可能。
マスターからノードへの通信
大きく2つあって、
- マスター(APIサーバ)からkubeletへの通信
- APIサーバからノード、Pod、サービスへの通信
これらはHTTPSで通信できるが、まぁHTTPなことが一般的。
ここまでで何がわかったか
通信はHTTP(S)。以上。
どうやってカスタムリソースを扱うか
選択肢は以下のとおり。
- Admission webhook: APIリクエストを変更・検証する仕組み
- CRD: 自分で独自のリソースを定義してこれを操作するようなコントローラを合わせて実装
- API aggregation: APIをaggregation layerに追加
設定の容易さとかからCRDが一番選ばれています!
なのでうちもCRD使うで。
必要なもの
- CRD(custom resource definition)用のyaml
- cR(custom resource)用のyaml
- カスタムコントローラをデプロイするためのyaml
- カスタムコントローラ(実体)
- カスタムコントローラビルド用のDockerfile
カスタムコントローラ作るためのツール
こんなのありますね。
- client-go / apimachinery / code-generator
- kubebuilder
- Operator SDK
その他、サポート言語のclientライブラリ
待て待て・・・わしはOCamlって言語使いたいんじゃ・・・
え?サポート外・・・?
やってやんよ
ポイントはこれ。
- 所詮コントローラはただのプログラム
- 通信はHTTP(S)
はい、もうわかりましたね。HTTPクライアントを実装すればよいです。
実装
見れ。
https://github.com/Asya-kawai/ocaml-custom-controller
TODO: 後で綺麗にする(予定は未定)
最後に
眠い。おやすみ。