最初に結論を書いておくと、kubectl
でやったほうが基本的には楽です。
止むに止まれずPythonからKubernetes操作をする必要が出た方向けです。
使い方を調べてもあまり日本語の記事が出てこなかったので。
使用するのはKubernetes公式のクライアントです。
以下でインストールできます。
pip install kubernetes
このライブラリは(おそらく)ドキュメントも含めて大部分が自動生成されたものです。
コードが読みにくかったり、知りたい説明が書いてなかったりするのが辛いポイントです。
一方で、examplesは結構充実しているのでそこを見れば色々解決する可能性は高いです。
コード例
動かす前にKubernetesの設定ファイルを用意する必要があります。
~/.kube/config
にファイルが置いてある状態であれば大丈夫です。
例として載せるコードでは以下でkubeconfigを読み込んだ前提で書いていきます。
また、マニフェストファイルをPythonの辞書として読み込んでおく必要があるのでそれも行います。
マニフェストファイルの内容はDeploymentの話だったらkind: Deployment
に合わせた内容みたいな感じで、それぞれのコードの内容に合わせていい感じに書いてあるものとし、namespaceは全てdefault
とします。
import yaml
from kubernetes import config, client
config.load_kube_config()
with open('path/to/manifest.yaml') as f:
manifest = yaml.safe_load(f)
namespace = 'default'
ちなみにリソース作成については以下で書く話を全部やってくれそうなサンプルコードがあったのでそれでいいかもしれません。
以下のapply_from_*.py
系です。
Deploymentを操作する
Deploymentの操作はAppsV1Api
から行えます。
ドキュメント 上を操作したいリソースの名前で検索するとどのAPIのクラスを使えばいいかわかります。
api = client.AppsV1Api()
# Deploymentを作成
api.create_namespaced_deployment(namespace, manifest)
# namespace内のDeployment一覧を取得
api.list_namespaced_deployment(namespace)
# 作成したDeploymentを削除
name = 'metadata.nameで設定した名前'
api.delete_namespaced_deployment(name, namespace)
createで返却されるV1Deployment
を受け取って色々情報を見るとかもできます。
Serviceを操作する
Serviceの操作はCoreV1Api
から行えます。
api = client.CoreV1Api()
# Serviceを作成
api.create_namespaced_service(namespace, manifest)
# namespace内のService一覧を取得
api.list_namespaced_service(namespace)
# 作成したServiceを削除
name = 'metadata.nameで設定した名前'
api.delete_namespaced_service(name, namespace)
createで返却されるV1Service
を受け取って色々情報を見るとかもできます。
もうおわかりかと思いますが、どのリソースについても同じような書き方で操作できます。
操作説明の記事も自動生成できそう。
Custom Objectを操作する
Kubernetesにはデフォルトで使えるDeploymentやService以外の独自のリソースを定義できます。
ここでは例としてSpark Operatorを操作してみます。
Custom Objectの操作はCustomObjectsApi
から行えます。
今までよりも少し引数が増えます。
# カスタムリソースの種類を特定するための情報
group = 'sparkoperator.k8s.io'
version = 'v1beta2'
plural = 'sparkapplications'
api = client.CustomObjectsApi()
# Custom Objectを作成
api.create_namespaced_custom_object(group, version, namespace, plural, manifest)
# namespace内のCustom Object一覧を取得
api.list_namespaced_custom_object(group, version, namespace, plural)
# 作成したCustom Objectを削除
name = 'metadata.nameで設定した名前'
api.delete_namespaced_custom_object(group, version, namespace, plural, name)
リソースが特定の状態になるまで待つ
kubectl wait
相当のことができます。
以下ではSpark Operatorで作成された特定のSpark ApplicationのステータスがRUNNING
になるのを待ち、そのSpark ApplicationのIDを取得するコードです。
from kubernetes import watch
# カスタムリソースの種類を特定するための情報
group = 'sparkoperator.k8s.io'
version = 'v1beta2'
plural = 'sparkapplications'
name = 'metadata.nameで設定した名前'
api = client.CustomObjectsApi()
# Custom Objectを作成
api.create_namespaced_custom_object(group, version, namespace, plural, manifest)
# ステータスがRUNNINGになるまで待機
# field_selectorでnameを絞り込んでいる
w = watch.Watch()
for event in w.stream(
api.list_namespaced_custom_object,
group=group,
version=version,
namespace=namespace,
plural=plural,
field_selector=f'metadata.name={name}'
):
if 'status' in event['object'] and event['object']['status']['applicationState']['state'] == 'RUNNING':
spark_application_id = event['object']['status']['sparkApplicationId']
w.stop()
試したのはCustom Objectだけですが、一覧を取得するlist_namespaced_custom_object
はwaitで使えて特定のオブジェクトを取得するget_namespaced_custom_object
は使えなかったので、使えるのはlist_*
系だけかもしれません。
おまけ: プロキシを経由してクラスタにアクセスする
Kubernetesクラスタのアクセスにプロキシを経由する必要がある場合、自分の環境ではそのままだとできませんでした。
あまりきれいではないですが回避策を見つけたので書いておきます。
from kubernetes import config, client
config.load_kube_config()
client.Configuration._default.proxy = 'プロキシのURL'
issueでも同じ解決をしてたので他にないかもしれませんが、もっといいやり方があれば教えて下さい。