概要
KubernetesのOperatorはCustomResourceを通してKubernetesの機能を自動化したり拡張したりできる便利な機能です。
Operatorを作成するにあたって主に使われている言語はgoですが、goでしかかけないというわけではありません。
この記事ではPythonでOperatorを作成するフレームワークと、簡単な使い方について紹介していきます。
kubernetes operatorとは
KubernetesのOperatorは自分で作成したカスタムリソースの定義に従い、DBやwebサーバなどのアプリケーションを自動でデプロイしてくれる拡張機能です。
通常のコンテナの作成に加え、自作したコードに従った自動化を行うことができるため、Kubernetesのデフォルト機能を使うのみに対して、外部クラウドサービスとやKubernetes外のデータベースへの連携といったもう一歩踏み込んだ自動化を実現することができます。
Operatorを作成するフレームワークにはoperator-frameworkなどがあり、go言語で作成することが多いです。
参照:kubernetes公式ドキュメント(https://kubernetes.io/ja/docs/concepts/extend-kubernetes/operator/)
kopfについて
kopf(Kubernetes Operator Pythonic Framework)はPyhonでKubernetes Operatorを作成するためのフレームワークです。
自動化したいコードにデコレータをつけるだけで、Kubernetesのリソース変化に合わせてコードを実行することが可能になっています。
参照:https://github.com/nolar/kopf
インストール方法
実施環境:
- Ubuntu18.04
- python3.7.0
インストールはpipからできます。
pip install kopf
使い方
実行方法は簡単で、インストール時に導入されたkopfコマンドで実行したいOperatorのコードを指定するだけです。
kopf run your_code.py --verbose
TIPS:
- OperatorがKubernetesAPIにアクセスするためにKubeconfigを用意する必要があります。デフォルトでは
$HOME/.kube/config
を参照します。 - カスタムリソースを参照するOperatorの場合、Operator起動前にリソースを作成しておかないと404エラーとなります。
サンプルコード
githubに多数のサンプルコードが用意されているため、基本的にはそこを見ると機能を理解できるかと思います。
以下にサンプルコードの一部を引用して解説していきたいと思います。
リソースの作成に反応
import kopf
@kopf.on.create('zalando.org', 'v1', 'kopfexamples')
def create_fn(spec, **kwargs):
print(f"And here we are! Creating: {spec}")
return {'message': 'hello world'} # will be the new status
kopfでは関数にデコレータをつけることにより、kubernetesのリソースの変化に応じてコードを実行することができます。このサンプルコードではkopfexamples
リソースが作成された時に標準出力にリソースの定義を出力します。
また、返り値は作成されたリソースのstatusに保存され、kubectl describe
コマンドで内容を確認することができます。
子リソースの作成
import kopf
import pykube
import yaml
@kopf.on.create('zalando.org', 'v1', 'kopfexamples')
def create_fn(spec, **kwargs):
# Render the pod yaml with some spec fields used in the template.
doc = yaml.safe_load(f"""
apiVersion: v1
kind: Pod
spec:
containers:
- name: the-only-one
image: busybox
command: ["sh", "-x", "-c"]
args:
- |
echo "FIELD=$FIELD"
sleep {spec.get('duration', 0)}
env:
- name: FIELD
value: {spec.get('field', 'default-value')}
""")
# Make it our child: assign the namespace, name, labels, owner references, etc.
kopf.adopt(doc)
# Actually create an object by requesting the Kubernetes API.
api = pykube.HTTPClient(pykube.KubeConfig.from_env())
pod = pykube.Pod(api, doc)
pod.create()
api.session.close()
# Update the parent's status.
return {'children': [pod.metadata['uid']]}
リソースの作成時に、リソース内容に応じた定義を持ったPodを新たに作成しています。
ポイントはkopf.adopt(doc)
で、これを実行すると作成したPodのownerReferences
フィールドにトリガーとなったリソースの情報が記録されます。
この情報を持つことでトリガーとなったリソースと作成されたPodに親子関係が形成され、親リソースが削除されると子のPodも同時に削除されるようになります。
まとめ
kopfのフレームワークを使ったPythonでkubernetesのOperator作成を紹介してみました。
goは手をつけてないけどPythonならという方もこれを機にKubernetesのOperator作成をしてみるのはいかがでしょうか。