機雷がなんだ! 全速前進!

SEというかプログラマというか、日々のエンジニア生活の中で体験したことなどを中心に書き残しています。

AWS Fargate のアーキテクチャで気になること

はじめに

最近AWS Fargateのバックグラウンドの仕組みが気になったので、これまでに読んだ書籍やAWS公式ドキュメント、個人ブログなどの情報を一旦まとめておこうと思いました。ここに記載する内容は、同じ情報収集を再度やりたくないために書き留めるもので、何かしらの結論があるような内容でもありません。あらかじめご了承ください。

AWS Fargate

言わずと知れたAWSのマネージドなコンテナ向けサーバーレスコンピューティングのサービスです。具体的には、コンテナオーケストレーションのマネージドサービスであるAmazon ECSもしくはAmazon EKSのワーカーノード(データプレーンとも呼ぶ)として実際にコンテナをデプロイして動作させる環境のインスタンスとして利用します。EC2のようなセルフマネージドなインスタンスとは違い、インスタンスそのものの管理(パッチ適用など)の手間をAWSに委ねることで、アプリケーションやシステムの構築に注力することができます。これ以上の詳細は、ここで説明するまでもないと思いますので、AWSの公式サイトをご参照ください。

アーキテクチャに関する情報(時系列)

調査した内容を時系列で昇順(古い→新しい)で以下に記載していきます。

2018/11/27:Firecracker – サーバーレスコンピューティングのための軽量な仮想化機能

こちらはAWS公式ブログの記事としてFirecrackerについて説明されています。

そして、記事では以下のように記載されていました。

Battle-Tested – FirecrackerはBattle-Testedであり、既にAWS LambdaとAWS Fargateを含む複数のハイボリュームなAWSサービスに利用されています。

タイミング的に AWS re:Invent 2018 の直前の記事なので、満を持して発表されたものだと思われますが、Firecrackerは、既に実践でテスト済(Battle-Tested)で実用的であることがアピールされているように読み取れます。

2021/10/21:AWSコンテナ設計・構築[本格]入門

こちらの書籍はAWSでのコンテナ活用を学ぶに当たっての良書であり、巷の評価も高く個人的にも非常に参考になった書籍です。

そして、書籍中で以下のように記載されていました。(P.246)

Fargateでは、コンテナごとにFirecrackerと呼ばれるマイクロVMを起動させ、マイクロVM上でコンテナが稼働します。正確には、「タスク」と呼ばれる複数のコンテナをグループ化した単位ごとにマイクロVMが稼働します。

この記載から、最近のAWS Fargateは、すべからくマイクロVMのFirecrackerで動作しているように記載されています。

2022/04月頃:AWS公式ドキュメント「Security Overview of AWS Fargate」

こちらはAWS公式ドキュメントでAWS Fargateについて説明されています。

https://d1.awsstatic.com/whitepapers/AWS_Fargate_Security_Overview_Whitepaper.pdf

そして、ドキュメント中で以下のように記載されていました。(P.15~16)

EC2: Fargateデータプレーンスタックの最下部にあるEC2ハイパーバイザーは、信頼されたハードウェア仮想化を使用して、同じ物理サーバー上で実行されているインスタンスを分離する。前のセクションで述べたように、EC2インスタンスはAmazon Linux 2、Fargate Agent、コンテナランタイムを実行する。コンテナの分離境界はcgroups、namespaces、seccomp policiesのような抽象化で構成されている。これらはある程度の分離を提供しますが、タスクとインスタンスの1対1のマッピングを実行することで、タスクのコロケーションを避けることにしました。この実行モデルは何層もの分離を提供する。したがって、Fargateは同じEC2インスタンス上で2つのタスクをコロケーションすることはない。各インスタンスで実行されるタスクは1つだけだ。RunTask APIが呼び出されると、新しいEC2インスタンスが使用され、タスクが停止するとインスタンスは終了する。これにより、EC2のデータプレーン上でFargateのタスクレベルの分離が保証される。 

Firecracker: FirecrackerマイクロVMはホスト上に配置されたタスクごとに作成される。タスクに属するすべてのコンテナはmicroVM内で実行され、セキュアなタスク境界を促進します。FirecrackerはmicroVMをセキュアにする責任があります。firecrackerプロセス自体は、cgroupsとseccompプロファイルを使ってクイルされる。コンテナ/タスクのクレデンシャルとシークレットは、適切なFirecracker microVMだけが利用できるようにする。したがって、Firecrackerで考慮すべき主なセキュリティは、タスク同士を確実に分離することです。

この記載から、AWS Fargateは、2022年4月の段階においてEC2インスタンスとして動作するパターンとマイクロVMのFirecrackerで動作するパターンの2つあるように読み取れます。

2022/12/12:AWS側がしてきたECS / Fargate のスケーリング速度改善の話

元ネタのAWS公式ブログ記事は上記のAWS公式ドキュメント「Security Overview of AWS Fargate」が発表された頃と同じ2022年4月頃になっていますが、その内容を非常に分かりやすくまとめてくれています。

この記事によると、2020~2022年にかけてFargateのスケーリング速度は大幅に改善されており、これまでEC2に比べて遅いと言われていたFargateのスケーリングが、ことECSにおいてはEC2をベンチマークで大きく逆転するようになっているようです。但しEKSにおいては、そこまで達していないようです。上記ブログ内に元ネタのAWS公式のリンクがありますが、一応以下にも記載しておきます。

2024/02/08:Fargate Is Not Firecracker

そして今年の2月に発表された、この何とも衝撃的なタイトルのこの記事です。

今年の1月までAWSの中の人だったJustin Garrison氏が書いたブログ記事には、以下のように記載されていました。

There was an unspoken policy to never point out that Fargate didn’t actually use Firecracker to create “microVMs” for each container. Just let customers believe what they wanted to. Of course all of the documentation and blog posts make it sound like Fargate uses Firecracker, but you have to read between the lines and know how companies push you to believe something that’s not true.

Fargateが実際にはFirecrackerを使って各コンテナに「マイクロVM」を作成していないことは、決して指摘しないという暗黙のポリシーがあった。ただ、顧客が望むことを信じさせるだけだった。もちろん、すべてのドキュメントやブログ記事は、FargateがFirecrackerを使用しているように聞こえるが、行間を読み、企業がどのように真実ではないことを信じさせるかを知る必要がある。

Justin Garrison氏が本当にAWSの中の人だったのか正確には分かりませんが、2023年4月12日のAWS公式ブログ「Amazon EKS が Kubernetes 1.26 のサポートを開始」の中で氏の名前が何度も登場し、更にAWS のデベロッパーアドボケイトの 1 人として紹介されていました。また、同文中で紹介されているショート動画では、本人(※LinkedInと同一人物に見える)が顔と声を出して自ら語っていることから鑑みても、AWSの中の人だったことは本当だと思われます。

2024/04/20:AWS Fargateのアーキテクチャ探訪

最近の以下のブログ記事でAWS Fargateのアーキテクチャを解説してくれていました。

そして、最後の「おわりに」の中で以下のように記載されていました。

リソース効率からしておそらくFirecrackerによる方式が主流なのだろうなと推測しますが、EC2でもFirecrackerのどちらの方式にしてもVMレベルでECSタスクの分離が行われており、いずれにしても堅牢なセキュリティが確保されていると言えます。

確かに、近年のAWS Fargateのスケーリングの改善の結果を鑑みても、私も同じ所感です。

さいごに

AWS Fargateを支えるアーキテクチャについて気になってしまったので、調べた内容を時系列でつらつらと書き連ねてみましたが、調べる前よりモヤモヤしています(笑)。いずれこのモヤモヤを晴らしたいと思いますが、時間が空いてしまうことで、調べた内容やモチベーションが消えてしまわないよう、一旦ここに吐き出しました。

 

今回は以上です。

Kubernetes and Cloud Native Associate (KCNA-JP) 試験に合格しました【二冠】🐳🐳

先日(5/12)Kubernetes and Cloud Native Associate (KCNA-JP) 試験に合格しました。CKA(失効)→CKAD(失効)→CKS→KCNA の順番に取得したので、今更感が満載ですが、来年更新を迎えるCKSを更新するためには、前準備として失効してしまったCKAの再取得が必要となるため、それに向けたモチベーションUpのためにお試しで受けてみました。

Kubernetes認定資格

現在ではLinux Foundationが認定するKubernetesの認定資格は、次の5種類(KCNA/KCSA/CKA/CKAD/CKS)があります。2020年11月にCKS、2021年11月にKCNA、2024年2月にKCSAの認定試験が追加されており、ここ数年におけるKubernetesニーズの高まりを感じます。また、

2024 年認定有効期限ポリシーの変更 - Linux Foundation - トレーニング

で重要なポリシー変更の発表があったとおり、2024年4月1日から全ての認定期間が24ヶ月(2年)に変更されている点にも注意が必要です。

略称 正式名 概要

KCNA

KCNA-JP

  • Kubernetes and Cloud Native Associate(KCNA)
  • 認定Kubernetesクラウドネイティブアソシエイト(KCNA-JP)
Kubernetesと広範なクラウド ネイティブ エコシステムに関する基本的な知識とスキルを証明する(有効認定期間:2年間

KCSA

  • Kubernetes and Cloud Native Security Associate(KCSA)
  • 認定Kubernetesクラウドネイティブセキュリティアソシエイト (KCSA)
Kubernetesクラスタのベースラインセキュリティ設定を理解し、セキュリティ制御の強化/テストと監視/脅威と脆弱性の強化に参加し、コンプライアンス目標を達成できるスキルを証明します(有効認定期間:2年間

CKA

CKA-JP

  • Certified Kubernetes Administrator (CKA)
  • 認定Kubernetes管理者  (CKA-JP)
Kubernetes管理者の責任を遂行するスキル、知識、および能力を備えていることを保証する(有効認定期間:2年間

CKAD

CKAD-JP

  • Certified Kubernetes Application Developer (CKAD)
  • 認定Kubernetesアプリケーション開発者 (CKAD-JP)
ユーザーが Kubernetes 用のクラウドネイティブ アプリケーションを設計、構築、デプロイできることを証明する(有効認定期間:2年間

CKS

CKS-JP

  • Certified Kubernetes Security Specialist (CKS)
  • 認定Kubernetesセキュリティスペシャリスト (CKS-JP)
Kubernetesの熟練した実践者(CKA認定が必要)であり、コンテナベースのアプリケーションやKubernetesプラットフォームの構築、デプロイ、ランタイム時のセキュリティを確保するための幅広いベストプラクティス能力を実証する(有効認定期間:2年間

試験対策

対策はUdemyの過去問を、試験の1週間前と、前日に、ひととおり解いただけでした。

試験当日

これまでの試験(CKA/CKAD/CKS)と同様に、自宅の自分のPCから受験する方式です。例のごとく PSI Secure Browser という試験用のクライアントツールをインストールして試験を行います。個人的には、これまで何度も受験してきているので試験前の準備(クリアデスク、クリアスクリーンなど)は慣れたものでしたが、身分証明書(今回はパスポート)の提示の仕方が少し変わっていました。これまでは、試験官に対してWebカメラ越しにリアルタイムで手持ち提示していましたが、今回は試験準備操作の中で身分証明書を撮影してセルフチェックしたものが提出できるようになっていました。そのため、試験官から「見にくいから、やり直し!」みたいな指摘をチャット(しかも英語)でされて焦るというようなことがなく、これは良い改善だな、と感じました。

試験結果

受験後24時間後くらいにメールで試験結果が通知されます。今回のスコアは【88/100】でした。合格ライン(スコア75)を、ある程度余裕を持って上回ることができました。

所感

これまでの受験した試験(CKA/CKAD/CKS)のように、実際にコマンドを叩きながら課題をクリアしていく実技中心の試験と比べてかなり簡単な印象でした。試験はオンラインの多肢選択式試験なのですが、出題された問題に対する解答が必ずひとつであるため、AWS認定試験のように複数選択があり得る場合と比べると難易度は低い感触です。とはいえ過去問をやっていく中で、知らないことも出てきましたし、試験結果スコアも満点でなく、そこそこだったので、まだまだ精進が必要だなと感じました。

AWS Lambda で実行の冪等性を考慮しておくことの重要性

背景

AWS Lambda を使うと様々な処理を簡単かつサーバレスに実現することができます。お手軽に使える一方でいくつか考慮しておかないと実運用時に痛い目を見ることも沢山あります。いくつかある考慮ポイントの中で、実際にハマった冪等性の観点について少しまとめておこうと思います。

 

発生したこと

S3にオブジェクトをPutしたのをトリガとして S3 Object Lambda でオブジェクトの種類ごとに様々な処理を行っていました。当初は冪等性を考慮した作りになっていなかったのですが、多くないオブジェクト数(10~100)でテストした限りでは特段問題なく動作していたので本番環境へデプロイしました。実際の本番環境では、膨大な数のオブジェクト数(数百万~数億)を処理することになるのですが、次のような問題が発生してしまいした。

 

<問題点> 

  • 1.なぜかLambdaが複数回発火する場合がある
    • 対象データ処理済の場合は、後で発火したLambdaの実行がエラーになる
      • 前に発火したLambdaが正常終了でも最終ステータスがエラーになる
    • ほぼ同時だと複数処理がデータを取り合って待ちやデータ破損が発生する
  • 2.無駄なLambdaのリトライが発生(初期設定では2回)してコストが嵩む
    • データ起因なので、何度リトライしても確実に同じエラーが発生する
    • リトライ対象のオブジェクト(画像)が巨大な場合は、ハイスペックで高単価なLambda(OOMが発生しないようスペックアップしてある)が複数回実行されることでコストが嵩む
    • リトライ対象のオブジェクトが動画の場合は、後続の変換処理で高単価なAWS Elemental MediaConvertを使用していたためコストが嵩む

 

分析と対策

  • その1

今回はS3にオブジェクトをPutしたのをトリガとして S3 Object Lambda を発火させていますが、AWS Lambdaでは発火イベントが意図せず複数回発生してしまうことがあります。これは「At Least Once(最低一回)」という仕様なので、これを前提にする必要があります。

alt text

【AWS Black Belt Online Seminar】Serverless モニタリング 【P.48】から抜粋

 

AWS Lambdaのベストプラクティス「Lambda 関数を冪等にする | AWS re:Post」では、次のように記載されています。

DynamoDB など、スケーリングが容易でスループットが高いサービスを使用してセッションデータを保存します。

このベストプラクティスに従ってDynamoDBを用いてLambdaの冪等性を確保するよう対策しました。具体的な実装のサンプルのソースコードはGithubに置いておきます。

github.com

こちらDynamoDBの操作【新規登録:put_item()、更新:put_item() 】の条件の記載方法が若干ややこしいので詳細は公式ドキュメントを参照してください。

 

  • その2

無駄なLambdaのリトライについては単純にリトライしないようLambdaの「非同期呼び出し」の設定で「再試行(関数がエラーを返すときに再試行する最大回数)」を 0 に設定するだけで対策できます。

 

結果

以上の対策によりLambdaが複数回発火した場合でも、DynamoDBに登録したステータスのレコードをチェックすることで、直ちにLambdaを終了させることができるようになり、無事にAWS Lambdaの冪等性を確保することができました。これにより、前述の問題点をすべて解消することができました。

 

おわりに

前述したとおりAWS Lambdaでは発火イベントが意図せず複数回発生してしまう「At Least Once(最低一回)」という仕様なので、Lambdaが複数回発火すること自体を防ぐことはできません。そのため、Lambdaが複数回発火することを前提に冪等性を確保するよう実装する必要があります。また、Lambdaのリトライ回数や実行時間などの設定についても用途に合わせて適切にチューニングすることも併せて重要です。個々の処理は微々たるコストでも、今回のように取り扱うオブジェクト数が膨大になるとチリツモで、とんでもないコストを請求されることになりますので、くれぐれもご注意ください。(と、自戒の念を込めて…🙏)

 

参考

日の出・日の入を計算するWebアプリをMercuryで作成して公開してみた

今回も小技ネタですが、一応サンプルWebアプリ公開までやったのでブログに書いておこうと思います。

背景

以前から国立天文台公開データを手動でExcelに取り込んで可視化するということをやっていました。(※下図のイメージ:日の出&日の入の時刻の可視化.xlsx

手動で作成して運用していたExcelファイル

年に1回のことなので、自動化するまでもないと思っていたのですが、それすら面倒くさくなってしまったので Jupyter NotebookGoogle Colab)で自動化することにしました。

課題

Jupyter NotebookGoogle Colab)を使えば可視化まで実現できそうではありますが、次のような懸念点がありました。

  • 国立天文台公開データと比較して精度が大きく劣化する可能性がある
  • 作成したノートブックを いつでもどこでもだれでも 簡単に実行できない

結論

今回は、以下のソリューションを使って作成したノートブックをWebアプリとして公開することで前述の懸念点を解決しました。

公開したWebアプリのURLは次のとおりです。

https://daytime.runmercury.com/app/sample

Webアプリの画面イメージ
続きを読む

Amazon S3 ファイルのMD5ハッシュ値を効率的に計算するLambda

ちょっとした小技です。検索しても情報があまり無かったので一応書き留めておくことにします。

背景

S3にアップロードしたファイルが破損していないことを確認するため、アップロードしたファイルのMD5ハッシュ値を計算してチェックする仕組みが必要でした。S3に配置したタイミングで発火する S3 Object Lambda を用いて実現しようとしたところ、巨大なファイルをうまく処理できないという課題に遭遇しました。

課題

S3には大小さまざまなファイル(最低 0 バイトから最大 5 TB)を配置することができるため、場合によっては超巨大なファイルが処理対処となることもあり得ます。また、AWS Lambda は割り当てるメモリ量(128 MB から 10,240 MB までの任意の量のメモリを 1 MB 単位で関数に割り当て可能)によって単価が高くなるため、コストの観点からも不用意に高めることもできません。

やったこと

以下のように処理方法を変えました。

  • Before
 # S3から一気に全てダウンロードして計算する方式(メモリ不足の懸念あり)
s3_object2 = s3c.get_object(Bucket=src_bucket_name, Key=cpy_object_name)
all_body = s3_object2["Body"].read()
md5_hash_value2 = hashlib.md5(all_body).hexdigest().upper()
  • After
# S3から少しずつダウンロードしながら計算する方式(使用済みデータは捨てる)
s3_object1 = s3c.get_object(Bucket=src_bucket_name, Key=cpy_object_name)
md5 = hashlib.md5()
for chunk in s3_object1["Body"].iter_chunks(chunk_size=10240):
    md5.update(chunk)
md5_hash_value1 = md5.hexdigest().upper()

コピペで動作するサンプルコードとパフォーマンス比較計測結果をGithubにPushしておいたので実際に試してみたい人は以下をご覧ください。

github.com

まとめ

S3に格納されたオブジェクトには巨大なものもあり得るため、特別な理由がない限りは、基本的には【After】のようにMD5ハッシュ値の計算を実装すべきと考えられます。

 

Amazon S3で高速にクロスリージョン間ファイルコピーをする方法

背景

現在はマネージドサービスであるS3 クロスリージョンレプリケーション (CRR) があるのであまりニーズがないかもしれませんが、とある事情でクロスリージョン(東京R→大阪R)間でサイズの大きいS3オブジェクトをコピーし、かつ、コピー先のオブジェクトに既存のオブジェクトのメタデータを引き継ぐだけでなく、新しいユーザー定義のメタデータ(x-amz-meta-xxxx)を追加付与しなくてはいけない要件がありました。

やったこと

S3にオブジェクトをPutしたのをトリガとして S3 Object Lambda から

  • boto3.client('s3').copy_object()
  • boto3.resource('s3').meta.client.copy()

などを使ってリージョン間ファイルコピーを試してみました。しかし、ファイルサイズ制限に引っかかったり、転送速度に難があったり、メタデータを引き継げなかったりと、いずれもやりたい要件をうまく満たすことができませんでした。なるべく独自実装したくなかったのですが、やむを得ず

  • boto3.client('s3').upload_part_copy()

を用いて、マルチスレッドかつマルチパートな通信を実装することで、今回の要件を満たすことができました。処理のサンプルのソースコードはGithubに置いておきます。

github.com

達成したこと

前述した方式は、僅かな差ですが最も速くデータを転送できました。(下図)

alt text

また、コピー元オブジェクトのタグやメタデータを引き継ぎ、新しいユーザー定義のメタデータ(x-amz-meta-xxxx)を追加付与することもできました。

参考

XP祭り2023登壇メモ:日本初のスクラム本「アジャイルソフトウェア開発スクラム」から20年の節目に翻訳者にいろいろ聞く

今更ながら、やりっぱなしでとっ散らかってままになっていた昨年のXP祭り2023の資料や情報を少しまとめて記録しておくことにします。

XP祭り2023について

プロポーザル

XP祭り2023 - 日本初のスクラム本「アジャイルソフトウェア開発スクラム」から20年の節目に翻訳者にいろいろ聞く | ConfEngine - Conference Platform

当日の資料

speakerdeck.com

当日の動画

日本初のスクラム本「アジャイルソフトウェア開発スクラム」から20年の節目に翻訳者にいろいろ聞く - Fumihiro Sunada / akon highfive - YouTube

※動画は公開期限が切れたら見れなくなってしまうかも…

ブログなど

その他

おわりに

ふりかえってみれば準備も覚束ないまま当日を迎えてしまい、下手くそファシリで akon さんの良いところや深い話をうまく引き出し切れなかったな、と反省しつつも、個人的には念願叶って一緒に登壇できてとても楽しかったのでまた挑戦したいです。ご協力&ご参加ありがとうございました🙇(打ち上げ🍶も最高でした😀)

九頭龍蕎麦 本店(飯田橋)