BioErrorLog Tech Blog

試行錯誤の記録

SageMakerでlocal training jobが実行できない時の対処法 | Unable to locate credentials

Unable to locate credentials

のエラーで、SageMaker instanceのlocal training jobが実行できないときの対処法をまとめます。

はじめに

SageMakerでは、SageMaker Python SDKを利用して簡単にtraining job/学習ジョブを実行することができます。

SageMaker SDKのtraining jobには、

  • オンデマンドに別インスタンスが立ち上がってジョブを実行する通常ジョブ
  • 作業中のNotebookインスタンス上でジョブを実行するlocalジョブ

の2種類があります。

この後者、local training jobを実行する際に、Unable to locate credentialsエラーが発生してジョブが実行できない現象に遭遇しました。

対処法を見つけたので、備忘録としてまとめておきます。

SageMakerでlocal training jobが実行できない時の対処法

事象

  • SageMaker instanceでlocal training jobを実行した際に、ジョブコンテナでUnable to locate credentialsエラーが発生してジョブが異常終了する

ただし、私はまだ確実なエラー再現手順を特定できてません。
同様の現象は下記のようにいくつか報告があがっています:

原因

  • ジョブ実行コンテナからインスタンスメタデータエンドポイント(169.254.169.254)にアクセスできていないこと

インスタンスメタデータエンドポイント(169.254.169.254)は、インスタンスのメタデータを取得するためのリンクローカルアドレスです。

Localのジョブ実行コンテナがインスタンスに付与されたIAM権限を参照/Token取得する際に、このエンドポイントにアクセスする必要があります。

しかし、このエンドポイントにアクセスできていないことで、ジョブ実行コンテナがIAMのTokenを取得できない = 権限を取得できない = Unable to locate credentials、という状況です。

対処法

  • 下記のようなスクリプトを実行し、ジョブ実行コンテナから169.254.169.254へアクセスできるように設定変更する
#!/bin/bash

# check if we need to configure our docker interface
SAGEMAKER_NETWORK=`docker network ls | grep -c sagemaker-local`
if [ $SAGEMAKER_NETWORK -eq 0 ]; then
  docker network create --driver bridge sagemaker-local
fi

# Get the Docker Network CIDR and IP for the sagemaker-local docker interface.
SAGEMAKER_INTERFACE=br-`docker network ls | grep sagemaker-local | cut -d' ' -f1`
DOCKER_NET=`ip route | grep $SAGEMAKER_INTERFACE | cut -d" " -f1`
DOCKER_IP=`ip route | grep $SAGEMAKER_INTERFACE | cut -d" " -f9`

# check if both IPTables and the Route Table are OK.
IPTABLES_PATCHED=`sudo iptables -S PREROUTING -t nat | grep -c $SAGEMAKER_INTERFACE`
ROUTE_TABLE_PATCHED=`sudo ip route show table agent | grep -c $SAGEMAKER_INTERFACE`

if [ $ROUTE_TABLE_PATCHED -eq 0 ]; then
  # fix routing
  sudo ip route add $DOCKER_NET via $DOCKER_IP dev $SAGEMAKER_INTERFACE table agent
  echo "route tables for Docker setup done"
else
  echo "SageMaker instance route table setup is ok. We are good to go."
fi

if [ $IPTABLES_PATCHED -eq 0 ]; then
  # fix ip table
  sudo iptables -t nat -A PREROUTING  -i $SAGEMAKER_INTERFACE -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 169.254.0.2:9081
  echo "iptables for Docker setup done"
else
  echo "SageMaker instance routing for Docker is ok. We are good to go!"
fi

重要なのは下記2つの設定変更部分です。

# fix routing
sudo ip route add $DOCKER_NET via $DOCKER_IP dev $SAGEMAKER_INTERFACE table agent

# fix ip table
sudo iptables -t nat -A PREROUTING  -i $SAGEMAKER_INTERFACE -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 169.254.0.2:9081

SageMaker SDKのlocal training jobでは、sagemaker-localという名前のdocker networkが利用されます (存在しない場合は作成する処理をスクリプト冒頭で行っています)。

このsagemaker-localを変更(ip routeの追加とiptablesのdestination変更)することによって、ジョブ実行コンテナから169.254.169.254へアクセスできるようになる -> インスタンスメタデータ取得できるようになる -> IAM権限Tokenを取得できるようになる、で、エラーを解消できました。

※上記スクリプトは、AWS公式が提供しているSageMaker examples内で見つけたセットアップスクリプトから一部を抽出/改変したものです。

おわりに

以上、Unable to locate credentialsエラーでSageMakerのlocal training jobが実行できないときの対処法をまとめました。

再現方法が特定できていないなどモヤモヤが残る部分はありますが、取り急ぎ解決にたどり着くことができました。

思わぬハマりポイントだったので、この記事が同じ目に遭ったどなたかの参考になれば幸いです。

[関連記事]

www.bioerrorlog.work

参考

amazon web services - Assume Sagemaker Notebook instance role from Docker container with default network mode - Stack Overflow

Local mode: role chaining/assumed role on notebook instances does not forward correct credentials · Issue #3464 · aws/sagemaker-python-sdk · GitHub

https://github.com/aws/amazon-sagemaker-examples/blob/main/sagemaker-python-sdk/mxnet_gluon_mnist/setup.sh

GitHub - aws/sagemaker-python-sdk: A library for training and deploying machine learning models on Amazon SageMaker

Access instance metadata for an EC2 instance - Amazon Elastic Compute Cloud

Link-local address - Wikipedia