LoginSignup
18
8

More than 5 years have passed since last update.

Google Cloud Functions(Python)からGoogle Kubernetes Engine(GKE)のジョブを登録する

Last updated at Posted at 2018-09-27

概要

Google Kubernetes Engine(GKE)でバッチジョブを実行することができるのですが、Cloud Functionsからジョブ実行できたらCloud Storageなどのイベントをトリガーにできて捗るなぁと思いついて実際に可能か試してみました。

GKEのジョブ実行については下記を参照ください。

GKEを使ったバッチジョブ実行
http://otiai10.hatenablog.com/entry/2017/12/19/162430

前提

下記記事の環境を流用しています。
実際に環境構築する際は、合わせてご参考ください。

Google Kubernetes EngineでUnity ML-Agentsを動かしてみる(V0.5.0対応)
https://qiita.com/kai_kou/items/3a4d860f8353ff1b3110

  • ローカルにDockerがインストール済み
  • ローカルにgcloudkubectl がインストール済み
  • GKEでクラスタ作成済み
  • ジョブ実行するDockerイメージがGoogle Container RegistryにPUSH済み

Cloud Functions関数の実装

Cloud Functionsにデプロイするファイルを用意します。

kubernetesのジョブ登録をPythonから行うのに、公式のClient Libraryを利用しました。

kubernetes-client/python
https://github.com/kubernetes-client/python

kubernetesのClient Libraryが利用できるようにします。

requirements.txt
kubernetes

GKEへジョブ登録するのに必要な情報をYamlファイルとして用意します。
内容は先の記事のものを流用しています。

job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: GKEクラスタのpod名(任意)
spec:
  template:
    spec:
      containers:
      - name: unity-ml-agents-on-gke
        image: gcr.io/[GCPのプロジェクトID]/unity_ml_agents_on_gke:latest
        command: ["mlagents-learn", "trainer_config.yaml", "--env", "3DBall", "--train"]
      restartPolicy: OnFailure

GKEのクラスタへアクセスできるようにconfigファイルを用意します。

> gcloud container clusters get-credentials [GKEのクラスタ名]

上記コマンドで、クラスタへの接続情報が~/.kube/config ファイルに保存されます。
このファイルをCloud Functionsにデプロイする際に含めるようにします。

ローカル環境でジョブ登録などのコマンドを実行していると、ファイルにaccess-tokenexpiry が含まれている可能性があります。

Cloud Functionsで実行する場合、GKEへアクセスするのに必要なaccess-token はCloud Functionsのデフォルトのサービス アカウントを参照してくれるので、自前でサービスアカウントを作成する必要はありませんでした。

configファイルにもaccess-tokenexpiry は不要となるので、行ごと削除して問題ありません。

サーバー間での本番環境アプリケーションの認証の設定
https://cloud.google.com/docs/authentication/production#auth-cloud-implicit-python

configファイルにはクラスタのIPアドレスなどが含まれるため、実運用の際にはCloud KMSなどを利用してファイルを暗号化しておきましょう。

> cp ~/.kube/config .

Cloud Functionsで実行するソースコードです。

main.py
import os
from kubernetes import client, config
import subprocess
import yaml

def create_gke_job(request):

  subprocess.check_output(['cp', './config', '/tmp/config'])
  config.load_kube_config('/tmp/config')

  with open(os.path.join(os.path.dirname(__file__), "./job.yaml")) as f:
    dep = yaml.load(f)

    k8s = client.BatchV1Api()
    resp = k8s.create_namespaced_job(body=dep, namespace="default")
    print("Deployment created. status='%s'" % str(resp.status))

ポイントとしては、kubernetesのconfigファイルをload_kube_config メソッドで呼び出すと、ファイルの読み込みだけでなくaccess-token などの追記がされるので、/tmp ファルダにコピーして書き込み可能にする必要がありました。

job.yamlに定義している、metadata.name がpodの名称となり一意である必要があるため、今回の実装だと、関数を複数回実行すると、pod名の重複エラーとなるため、yaml.load 後に、書き換えが必要となります。

kubernetesのClient Libraryについては、APIが多くて、どのAPIを利用すればよいのか(非常に)わかりにくいですが、ドキュメントがしっかり用意されているので、探せば大抵のことはわかるっぽいです(未確認)

python/kubernetes/README.md
https://github.com/kubernetes-client/python/blob/master/kubernetes/README.md

あとはCloud Functionsにデプロイして良しなに。
今回は関数が実行できたら良いだけので、トリガを--trigger-http にしています。

> gcloud functions deploy create_gke_job --trigger-http --runtime=python37

※いつのまにかgcloud functions コマンドで、--runtime=python37 の指定ができるようになっていました。(Google Cloud SDK 216.0.0)

参考

GKEを使ったバッチジョブ実行
http://otiai10.hatenablog.com/entry/2017/12/19/162430

Google Kubernetes EngineでUnity ML-Agentsを動かしてみる(V0.5.0対応)
https://qiita.com/kai_kou/items/3a4d860f8353ff1b3110

kubernetes-client/python
https://github.com/kubernetes-client/python

python/kubernetes/README.md
https://github.com/kubernetes-client/python/blob/master/kubernetes/README.md

サーバー間での本番環境アプリケーションの認証の設定
https://cloud.google.com/docs/authentication/production#auth-cloud-implicit-python

Cloud FunctionsでPython利用記事まとめ
https://qiita.com/kai_kou/items/2f65db5305ba280ad81e

18
8
0

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
  3. You can use dark theme
What you can do with signing up
18
8