search
LoginSignup
1

More than 1 year has passed since last update.

posted at

PythonでKubernetes Operatorを作る

概要

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に多数のサンプルコードが用意されているため、基本的にはそこを見ると機能を理解できるかと思います。
以下にサンプルコードの一部を引用して解説していきたいと思います。

リソースの作成に反応

kopf/examples/01-minimal/example.py
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コマンドで内容を確認することができます。

子リソースの作成

kopf/examples/02-children/example.py
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作成をしてみるのはいかがでしょうか。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1