プレイヤーズ・ハイ

 雑多な日記

AWS CLI のタイムアウトとリトライについて

AWS CLI のタイムアウトとリトライについてのまとめ

【目次】

AWS CLI のタイムアウト

2 種類のタイムアウトがあります.個別にタイムアウト値を設定することができます.

各 AWS CLI タイムアウトのデフォルト値と変更方法

タイムアウトの種類 デフォルト値 変更方法
コネクトタイムアウト 60 秒 AWS CLI のオプション (--cli-connect-timeout 秒数)
リードタイムアウト 60 秒 AWS CLI のオプション (--cli-read-timeout 秒数)

AWS CLI コネクトタイムアウトの説明

AWS CLI の各種コマンドを実行すると,対応する AWS API エンドポイントに対して AWS CLI が http または https 接続でにいきます. 主にネットワークの不調などで,コネクション確立を待たされることがあります.そのときに何秒待つか,の設定値です.

AWS CLI リードタイムアウトの説明

AWS CLI の各種コマンドを実行すると,対応する AWS API エンドポイントに対して AWS CLI が http または https 接続でにいきます. コマンドの内容が AWS API に伝わると,問い合わせに応じた回答を返します. このとき,AWS (API) 側の原因,またはこちらのネットワーク不調などの原因で,回答の受取を待たされることがあります,そのときに何秒待つか,の設定値です.

AWS CLI のリトライ

AWS CLI のリトライ回数のデフォルト値

コネクトタイムアウト,またはリードタイムアウトが発生した場合に,何回リトライするかというと,デフォルトでは 5 回です. botocore の以下にデフォルト値は 5 ですよ,と記述されています("max_attempts": 5,).

github.com

その他の JSON 部分を読んでみると,AWS サービス毎にデフォルトリトライ回数をハードコードしたり,exponential backoff なリトライにするか,またそのときの挙動についても書かれているようです.

docs.aws.amazon.com

ちなみに,リトライ回数がデフォルトの 5 回だとして,コネクトタイムアウトが 3 回発生し,次にリードタイムアウトが発生したとしたら,リードタイムアウトのリトライ回数は 2 回なのか,一旦リセットされて 5 回までリトライするのか,は,実測もしていませんし,そこまでコードも読んでいませんので分かりません.すみません(実測していませんが「合計」5 回となるようです).

AWS CLI のリトライ回数の変更方法

AWS CLI のオプションにリトライ回数を変更するオプションは存在せず,

botocore/_retry.json を編集し上書きするしかないようです.

または AWS CLI 実行時のリトライ回数を制御するラッパーを書く,というのも考えられます(しかし,タイムアウト系はデフォルトリトライ回数を変更 (1 回タイムアウトしたら異常終了) するには,_retry.json を変更するしかありません.逆に 30 回までリトライさせるためにラッパーを書くという道もありますが,_retry.json を変更した場合と比べると,厳密に言えば動作は異なります.独自のラッパーのメリットとしては,タイムアウト系以外のエラーハンドリングを自由に定義できるところになると思います).

AWS CLI のタイムアウトとリトライについて調べたこと

AWS CLI は AWS SDK for Python の botocore というものを使用しており,タイムアウトとリトライは,その実装によるようです.

先ほども書きましたが,botocore の GitHub リポジトリーは以下です.

github.com

botocore は The low-level, core functionality of boto 3. だよ,という説明があります.

boto 3 (Boto3) とは,最新版 (2017/1/16 現在) の AWS SDK for Python のことで,pip install boto3 でインストールします. ちなみに Boto のオリジナル版は AWS SDK for Python バージョン 2 だそうです.

まとめると AWS SDK for Python (Boto3) の中に botocore があり,それの処理の中に,タイムアウトとリトライの制御が入っています.

また,詳細は以下にありますが「Amazon S3 の自動マルチパート転送」や,AWS リソースにおける事前定義ステータスの変化を自動的にポーリングする "waiter" も,Boto3 で実装されています.

AWS SDK for Python | AWS

AWS CLI のタイムアウトについて追記

以下の環境で,AWS CLI のタイムアウトについて,どのコードで定義されているか,もう少し調査してみました. (コネクトタイムアウト,リードタイムアウトともに,AWS CLI のオプションで変更できますので,以下の調査にあまり意味はないかもしれません)

  • Red Hat Enterprise Linux Server release 7.2 (Maipo)
  • 3.10.0-327.28.3.el7.x86_64
  • Python 2.7.5
  • pip 8.1.2 from /usr/lib/python2.7/site-packages (python 2.7)
    • boto3 (1.4.1)
    • botocore (1.4.49)

botocore の config に関しては,以下のウェブサイトに書かれています.タイムアウトに関する記述もあります.

Config Reference — botocore 1.8.13 documentation

ほんで,上記環境で適当に find や grep してみましたが,具体的には上記環境ですと, タイムアウトのデフォルト値は /usr/lib/python2.7/site-packages/botocore/config.py の中で記述されているようです.

更に深追いするには,適当に grep して掘っていきましょう(なんか雑になった.すみません).

唐突に番外小ネタ.su と sudo

当たり前過ぎて恥ずかしい記述もありますが...

root 権限を必要とするコマンドの手動実行は,sudo -i [コマンド] で,毎回パスワードを求められるスタイルがセキュアなのかな.

しかしそれだと障害対応のときに死ねる.

普段はパスワードを毎回要求し,障害対応用に,パスワードを要求しないようにするワンライナーを保持しておくのがいいのかな.

以下を読むと,色々と柔軟に設定できそうなので,また今度詳細に詰めてみようと思う.

sudo - Wikipedia

  • Amazon Linux
  • bash
  • 一般ユーザーから root になりたい.
  • 結論は su -sudo -i 使おう.
    • su - は,環境変数 $PATH に /usr/local/bin が含まれ「る」.
    • sudo -i は,環境変数 $PATH に /usr/local/bin が含まれ「ない」.
    • su - は,root (スイッチユーザー先) のパスワードが要求される(/etc/pam.d/su を編集し auth sufficient pam_wheel.so trust use_uid を有効化すれば,wheel グループに属するユーザーはパスワードなしで root に su できます.ちなみに wheel グループに属するユーザーのみに su を許可する場合は auth required pam_wheel.so use_uid を有効にします).
    • sudo -i は,スイッチユーザー元のパスワードが要求される.また root になるには /etc/sudoers 内での許可が必要.

その他詳細は,以下の Qiita にすばらしくまとめられています.

qiita.com

また PAM まわりは以下のブログにすばらしくまとめられています.

suコマンドによるrootへのスイッチを制限する | VPSサーバーでWebサイト公開 備忘録 ~Linux、MySQLからAJAXまで

唐突に小ネタ2

お恥ずかしながら POSIX 互換モードを知りませんで,

「sh は /bin/sh で,これはシンボリックで実体は /bin/bash なのに,なんで $ sh foo.sh と実行したときに bash 独自機能を使っているとエラーになるのか? シェバンも /bin/bash なのに」

という疑問があり,うやむやにしてしまっていました.

以下は,シェルスクリプトがどのシェルから呼び出されたのかを判別する部品です(メッセージが寒くてすみません).

#!/bin/bash

shell_prog=`ps h $$ | awk '{ print $5; }'`

case "${shell_prog}" in
    sh) echo '$ sh foo.sh ってやっちゃダメ.POSIX 互換モードのせいで bash 独自機能が使えないゾ☆'
        echo 'bash で出直してこい.'
        exit 1
        ;;
    *bash) echo 'bash マンセー!!'
        :
        ;;
    ksh) echo 'Korn Shell とかシブいね!!'
        :
        ;;
    zsh) echo 'zsh とか厨二ですか?'
        :
        ;;
    *csh) echo 'そなたが伝説の(ry'
        :
        ;;
    *) echo '「」'
        :
        ;;
esac

# シェルスクリプト本体の処理

以上