LoginSignup
1
2

More than 5 years have passed since last update.

k8s Pullpolicyの勘違いでspark-submitでどハマりした話

Last updated at Posted at 2018-06-27

Azure k8sを使ったSpark-submitを実行するのにハマったので同じ人が出ないよう共有です

実行環境

  • kubernetes: Azure K8s Service(AKS) version 1.10.3
  • dockerイメージレジストリ: Azure Container Registry
  • spark: spakr2.3をgithubからDLし、-Pkubernetesオプションをつけて、jar化

実行手順

AKS での Apache Spark ジョブの実行というAzureのマニュアルに沿って実行

やりたかったこと

Spark-Pi example Jarをコンテナ内にADDした状態でspark-submitしたかった
↓のコマンドのようにlocal://をつけてspark-submitしたかったということ

spark-submit
./bin/spark-submit   
--master k8s://http://0.0.0.1:8001   
--deploy-mode cluster   
--name spark-pi   
--class org.apache.spark.examples.SparkPi   
--conf spark.executor.instances=1  
--conf spark.kubernetes.container.image=hoge
local:///opt/spark/work-dir/SparkPi.jar

起きた現象

↓のようにSparkPiをAzure Blob Storageに置いて実行する場合は正常終了する

成功コマンド例
jarUrl=$(az storage blob url --container-name $CONTAINER_NAME --name $BLOB_NAME | tr -d '"')

./bin/spark-submit \
  --master k8s://http://127.0.0.1:8001 \
  --deploy-mode cluster \
  --name spark-pi \
  --class org.apache.spark.examples.SparkPi \
  --conf spark.executor.instances=3 \
  --conf spark.kubernetes.container.image=$REGISTRY_NAME/spark:$REGISTRY_TAG \
  $jarUrl

しかしJarをContainerにいれ、local Jarを見るようにすると失敗する.
なおコンテナ内にJarが格納されていることはdocker runした上で確認済み.

失敗コマンド例
# マニュアル内[コンテナー イメージを使用して jar をパッケージ化する]箇所
./bin/spark-submit \
    --master k8s://https://<k8s-apiserver-host>:<k8s-apiserver-port> \
    --deploy-mode cluster \
    --name spark-pi \
    --class org.apache.spark.examples.SparkPi \
    --conf spark.executor.instances=3 \
    --conf spark.kubernetes.container.image=<spark-image> \
    local:///opt/spark/work-dir/<your-jar-name>.jar
エラーメッセージ
Error: Could not find or load main class org.apache.spark.examples.SparkPi

原因

k8s経由のspark-submit時にはimageをPullするPolicyが設定されている

Property Name Default Meaning
spark.kubernetes.container.image.pullPolicy IfNotPresent Container image pull policy used when pulling images within Kubernetes.

(Spark 2.3.0マニュアルより抜粋)

DefaultはIfNotPresent、つまり変更があればImageをPullするPolicyであると思っていた.
にもかかわらずDocker Imageを更新してもPullされず、古いものが使われ続けていた.

そのためJarをADDしたイメージでRegistryを更新したにも関わらず、 k8s内ではADDしていない時に登録したイメージがずっと使われため、Jarが存在せずエラーで落ちていた.
またAzure Container Registryから該当イメージをPullしてdocker runした場合には、最新イメージが使われていたためJarが存在しており、トラブルシュートをややこやしくしていた.

解決策

  1. Regsitryのtagを毎回変えた上でPushする
  2. latestタグを使う
  3. 以下のオプションをspark-submitに加えてk8sでも毎回強制Pullさせる
追加オプション
--conf spark.kubernetes.container.image.pullPolicy=Always

詳しくは↓の[Updating Images]項を参考
https://kubernetes.io/docs/concepts/containers/images/

1
2
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
1
2