ジョギング
- 山王公園を走った
- 懸垂 x 5
- 途中に腹痛で博多公民館にかけこんだ
色々あって
- 鹿児島の両親が急遽来福してりでバタバタだった
- 改めて奥さんを支えなければと思った次第
妻と TypeTalk で会話することにした.
— Yohei Kawahara(かっぱ) (@inokara) 2019年2月21日
楽しみ.
今更次郎な話かもしれないけど, 「そうなんだ〜」と思うことがあったのでメモっておきます.
「Amazon ECS のコンテナインスタンスってインスタンスタイプの変更は出来ない」ということです.
厳密に言うと, コンテナインスタンス EC2 自体のインスタンスタイプは変更は完了して無事に起動するのですが, コンテナインスタンス上で動く ecs-agent コンテナが起動しません.
コンテナインスタンスに SSH でログインして, ecs-agent を手動で起動させると /var/log/ecs-agent.log に以下のようなログを吐いてコンテナが異常終了します.
2019-02-20T02:49:28Z [ERROR] Unable to register as a container instance with ECS: ClientException: Container instance type changes are not supported. Container instance xxxxxxxxxxxxx-db72-4694-934b-xxxxxxxxxxxxxx was previously registered as t2.large.
status code: 400, request id: 23c5fd6b-34ba-11e9-8259-a997a65d9f18
2019-02-20T02:49:28Z [ERROR] Error re-registering: ClientException: Container instance type changes are not supported. Container instance xxxxxxxxxxxxx-db72-4694-934b-xxxxxxxxxxxxxx was previously registered as t2.large.
status code: 400, request id: 23c5fd6b-34ba-11e9-8259-a997a65d9f18
2019-02-20T02:49:28Z [CRITICAL] The current instance type does not match the registered instance type. Please revert the instance type change, or alternatively launch a new instance: ClientException: Container instance type changes are not supported. Container instance xxxxxxxxxxxxx-db72-4694-934b-xxxxxxxxxxxxxx was previously registered as t2.large.
status code: 400, request id: 23c5fd6b-34ba-11e9-8259-a997a65d9f18
えー, そうなんだと思った次第です.
— Yohei Kawahara(かっぱ) (@inokara) 2019年2月20日
コンテナインスタンスを停止してそのインスタンスタイプを変更することはできません。代わりに、コンテナインスタンスを終了し、必要なクラスター内の最新の Amazon ECS-optimized Amazon Linux 2 AMI で、必要なサイズの新しいコンテナインスタンスを起動することをお勧めします。
— Yohei Kawahara(かっぱ) (@inokara) 2019年2月20日
ドキュメント読め案件でした.
— Yohei Kawahara(かっぱ) (@inokara) 2019年2月20日
各コンテナインスタンスに、それぞれに固有の状態情報がコンテナインスタンスにローカルで保存され、Amazon ECS にも保存されているため、以下のような制限があります。
コンテナインスタンスに固有の情報が保存されるが所以の話で, その情報との整合性が取れない (取らない?) 為, ecs-agent が起動しないようです. 固有の情報がプレーンなテキストでコンテナインスタンスに保存されているのであれば, そのテキストを書き換えてしまえば良いのではと思いましたが, 試せていません. そんなことをするよりも, 新しく作り直した方が早いですし, リソースは使い捨てという考え方からするとこちらの仕様の方が正しいのかもしれません.
学びの多い日常の 1 コマでした.
学びの多い毎日. 勉強せねばと思う毎日.
gdb とか strace とか使いこなせるようになりたいと思った火曜日でした.
— Yohei Kawahara(かっぱ) (@inokara) 2019年2月19日
あと, バイナリエディタで JPEG を開いて, 「おおっ, これがスタートマーカーで, これがエンドマーカーかっ」と学びの多い一日だった.
— Yohei Kawahara(かっぱ) (@inokara) 2019年2月19日
あと, ペパボの P 山さんが,
本来の用途とは違うのに、それでできるから使うみたいなの、本来の用途ではないがゆえに、未来保証性が薄いのと、ハイコンテキストになって可読性や仕様認識が困難になるから避けてる。
— P山 (@pyama86) 2019年2月19日
このツイートから始まるスレッド, 「まさにそうだよなー」と思ったので引用させて頂いた.
この場合は代償か。この感覚は歴史のあるサービスを運用開発してるからこそ得られた感覚かもしれないなぁとは思う。それ次やるときどうなんだっけ?3年後どうなんだっけ?はじめてみた人すぐわかる?みたいな問いをする感覚があって、触らないと、経験しないとわからなのはなくしたい。
— P山 (@pyama86) 2019年2月19日
このツイートを読んで, 「はっ」としてしまって, 自分が今までやってきたこととか振り返ると反省しかないけど, こういう意識を常に持って設計とかしていきたいなと思った次第. 今度, P 山さんに会ったらお礼を言いたい.
ここ数日良くなくて, 明日, 朝一で病院に行く. 健康診断の結果で精密検査となっていたので一緒に検査してもらう予定.
おはようございます. どうも, 処理待ち隆史 (反町隆史) です.
おはようございます. 処理待ち (反町) 隆史です.
— Yohei Kawahara(かっぱ) (@inokara) 2019年2月15日
Lambda を使った RDS スナップショットのコピー自動化を実装するにあたって, コピーの完了を待つ (処理完了待ち) という処理をどのように実装するか考えてみた際のメモです.
処理完了待ちを実装するにあたり, 以下のような手法を検討しました.
何か を用意して, 別の Lambda で処理のプロセスを監視するまず, Lambda のタイムアウトを利用する手法です.
タイムアウト (15 分) 以内に確実に処理が終わることが保証されているのであれば, この手法が一番手軽なのかもしれません. ところが, 実際にスナップショットコピーを動かしてみたところ 15 分以上掛かってしまいコピー完了を確認することが出来ない状況になりました. (コピー自体は完了していることをマネジメントコンソールで確認しています)
Lambda のタイムアウトに頼ったら負け.
— Yohei Kawahara(かっぱ) (@inokara) 2019年2月13日
まさにこんな気持ちになりました.
以下のような仕組みを考えました.

(1) 〜 (3) までの処理は, 今回は RDS のスナップショットコピーという処理になっていますが, 似たような処理完了を待つような処理を当てはめることが出来ると考えています.
コピー用の Lambda 関数はスナップショット作成完了の通知を受けると, スナップショットをコピーする処理がを実行します. 正常にコピー処理が開始されると, SQS キューにに処理を開始した旨のメッセージをキューイング (4) します. メッセージの内容は以下のような JSON となります.
{"snapshot": "コピーするスナップショット名", "count": "処理待ち用 Lambda 関数が呼ばれた回数"}
JSON は以下のような内容となります.
snapshot キーの値にはコピーするスナップショット名が入ります, ここには処理完了を監視する対象物が定義されますnum キーの値には処理待ち用 Lambda 関数が何回呼ばれたかが定義され, これは関数が呼ばれる度にインクリメントされますポイントは num キーとなります. これは, 処理が永遠に完了しない場合, しきい値を設けてサーキットブレーカー的に待機処理 (処理が完了することを監視する処理) を終了する為に利用します.
キューイング以降, 処理待ち用の Lambda 関数は SQS キューのメッセージを受け取ると, メッセージを削除後, スナップショットのコピーが完了しているかどうかをチェックします. スナップショットのコピーが完了していたら完了した旨を通知して Lambda 関数は終了します. コピーが完了していなければ, 改めて SQS キューにメッセージを放り込みます.
処理待ち用の Lambda 関数はメッセージを利用して SQS キューとピンポンしている状態になりますが, 永遠にピンポンするわけにはいかないので, 処理待ち用 Lambda 関数が呼ばれた回数を記録しておいて, しきい値を超えたら待機処理を終了するような流れになります.
実際に雰囲気を伝えたくて, 以下のような処理の流れを考えてみました.

S3 バケットにオブジェクトが放り込まれたら Lambda 関数が起動するやつです. そして, 放り込まれたオブジェクトが削除されるまで待機するという, 場合によっては, 永遠に待ち続けるような処理です.
雑な感じで.
俺たちの Serverless Framework を利用します.
bundle exec rake deploy
でデプロイします. Slack に通知したい場合には, Incoming Webhook の URL を KMS で暗号化した内容を SLACK_ENCRYPTED_URL に記載します.
上記のコードの実行例です.
test.json ファイルを S3 にアップロードすると, PUT イベントをトリガーにして Lambda 関数が起動して SQS キューにメッセージが放り込まれます. メッセージは以下のような内容となります.
{"bucket":"serverless-waiting","key":"test.json","count":3}
count が 3 になっているので, 3 回目の削除待ち用 Lambda 関数が呼ばれていることになります. この実装例では, 10 回削除待ち用 Lambda 関数が呼ばれると削除待ちを終了するようになっています.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 START RequestId: f983604b-281a-5f35-93cf-34a90b14cb80 Version: $LATEST
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Deleted queue message.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] 10 回目の待機です.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 [INFO] Lambda 関数内でオブジェクトが削除されるまで待機します.
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 Error raised from handler method
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 {
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 "errorMessage": "[ERROR] 待機制限 (10 回) を超えたので, 待機を終了します.",
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 "errorType": "Function<RuntimeError>",
/aws/lambda/serverless-waiter-dev-waiter 2019/02/16/[$LATEST]9855e4f958a04501abaa541cd3823e52 "stackTrace": [
尚, 削除待ち用 Lambda 関数内でも指定した回数待機する処理になっています.
処理完了待ちを実装してみました. 実際に運用していますが, 今のところ処理待ちが滞っている等のトラブルはありません. また, 実装例も何度か試していますが意図したような挙動を確認しています. ただ, Lambda と SQS 間における例外処理等が不十分な状態が懸念され, 完璧な処理完了待ちになっていない可能性がありますので, あくまでも緩い感じの実装になっていることをお許し下さい.
良い処理完了待ちライフを.