CLOSE

アプリケーション開発者は Amazon ECS あるいは Kubernetes をどこまで知るべきか(全3記事)

アプリケーション開発者はどこまで知っているべきなのか? 前提知識整理のための、コンテナワークロード超入門

今押さえておくべき知識をアップデートし、ノウハウを共有し、さらなるスキルアップを実現する場として開催されている、AWS で最も Developer に特化したカンファレンス「AWS Dev Day Online Japan」。ここでSr. Product Developer Advocate, Elastic Containersの原氏が登壇。まずは、コンテナワークロード超入門として、コンテナのデプロイ時とクラッシュ時に起こることを紹介します。全3回。

自己紹介

原トリ氏:オーナーシップの塊、トリです。本日はタイトルにあるとおり、アプリケーション開発者はAmazon ECSあるいはKubernetesといったコンテナオーケストレータのことを、どこまで知るべきかについて話します。もともと「どこまで知ればいいのか」というタイトルでしたが、思いが強すぎて「知るべきか」に変わりました。

あらためて、原と言います。あるいはトリ、どちらでもかまいません。今日の話題に関係するので、キャリアの話をします。新卒で、ERP(Enterprise Resources Planning)パッケージの製品を開発・販売している会社に、ソフトウェアエンジニアとして入りました。その会社の運用は完全に開発組織から切り離されていたので、今考えると身の毛もよだつようなコードをたくさん書いてしまったことを反省しています。

転機はそのあとの会社です。クラウド利用のSI(System Integration)+MSP(Managed Service Provider)をやっている会社では、入社した時からAWSを使っていました。入社当時の社員数は、8~9人だったと記憶しています。全員が開発者でした。

当たり前ですが、その人数なのでみんながコードを書き、AWS環境の設計や構築、運用も自分たちでやってました。僕が運用を意識したコードを書けるようになった、あるいはそれを書けるようになる必要性が生まれたのは、この会社での経験があってこそです。

Amazon ECSが2015年の春くらいにGA(General Availability)しましたが、その前から準備をして、GAと同時にこの会社で本番投入しました。なぜそんなことをしたか。仮想マシンの運用をもっとシンプルにして、運用負荷を下げて、もっとコードを書きたかったことが根幹にありました。余談ですが、そういう意味で、今日のセッションの内容は、僕にとっては生存者バイアスのようなものが影響している可能性が往々にしてあります。

その後、AWSジャパンに入社して、コンテナのスペシャリストSA(Solutions Architect)として、AWSのお客さまの技術支援を行う業務を1年半くらいやった後、2020年の冒頭からはシアトルを拠点にするコンテナサービスの開発・運用チームに異動しました。

今は、AWSのコンテナサービスをユーザーにとってよりよいものにするために、プロダクトチームとしての役割から、設計上のディスカッション、あるいは開発者から最も近い位置にいるコンテナサービスユーザーとして、さまざまな活動を行っています。

自分で運用したことがある開発者なら誰しも同意してくれると思うのですが、運用コストを低く抑えて、ビジネスロジックの開発に集中させてくれるタイプのAWSのサービスが大好きです。運用はしていましたが、特に好きではありません。

セッション対象者とゴール

(スライドを指して)最初に、セッション対象者とゴールについて話します。まず「運用」が必要なアプリケーション(Webアプリケーションなど)を書いている開発者の方。ほかに、コンテナ技術そのものは聞いたことがある、あるいはふだんの開発で使っているという方。

さらに、自分のアプリを書いた後に「どうやって運用されてるかは知らないけどコンテナを使っているらしい」という街の噂を聞いたことがある方。それから、コンテナワークロードでのアプリケーション開発者の責務の範囲になんらかのガイドラインが欲しいという方。

このような方々が本日のセッションの想定聴講者なので、ある意味、知っている人には当たり前な話がいくつも出てきます。

では、ゴールは何か。運用を難しくしてしまうアプリケーション実装には、どのようなものがあるかを学び、その対処策を実践できるようになる。さらに、少なくともECSのタスク定義やサービス定義、Kubernetesのマニュフェストを開発者自身が書けるようになる必要性を理解して実践できるようになる。

また、開発から運用というソフトウェアのライフサイクルに関わるステークホルダーが、システムに共同で責任を持つことの重要性と妥当性を理解して、自社に適用できるように取り組むという気持ちを持つ。これらが本日のセッションのゴールです。

コンテナとコンテナイメージとは

まず、初学者のための「コンテナワークロード超入門」をサッと見ていきましょう。まず、コンテナとは何でしょうか。

アプリケーションはアプリケーションコードだけでは動きません。まず必要になるのはランタイムで、例えばJavaの場合はJVM(Java Virtual Machine)ですね。依存ライブラリ/パッケージは、みなさんコードを書く時にいっぱい使うと思います。よく、どこかからloggerなどを持ってきて使いますよね。さらに、みなさん自身が書くアプリケーションコード。これらが揃うと、アプリケーションが動かせる状態の直前まできます。もちろん、最後に設定も必要です。

開発環境用、ステージング用、本番用などの設定を合わせるとアプリケーションが動きますが、コンテナはこれらを1つにパッケージングしたもので、これを“コンテナイメージ”と呼びます。必要なものが全部入っているので、あとは各実行環境で設定値を渡して実行すればどこでも動きます。つまりコンテナイメージとは、必要なものが全部入った実行可能なバイナリのようなものだと思ってください。

コンテナはどのようにデプロイされ、どのように実行されるか

では、コンテナをデプロイする時はどういう流れになるのかを見ていきましょう。まず、コンテナワークロードには、必ずといっていいほど“コンテナオーケストレータ”というものが存在します。Amazon ECSやKubernetesがこれに当たります。

「Amazon EKSじゃないの?」と思う方がいると思いますが、違います。Amazon EKSはKubernetesクラスターを管理するためのサービスなので、Amazon EKSそのものはコンテナオーケストレータではありません。正確には、Amazon ECSとKubernetesがコンテナオーケストレータです。

みなさんは定義ファイルを用意して、手元のラップトップあるいはCI/CDパイプラインからAPIを呼んで、定義ファイルをぶん投げます。

すると、実際にコンテナが走る場所、(スライドを指して)右下に「ノード×N」と書いてありますが、EC2インスタンスだったり、あるいはAWSがフルマネージドなEC2インスタンスを提供するFargateと呼ばれる機能によって提供されるコンテナの実行環境が必要になるわけですが、その環境の中には、各ノード(EC2 インスタンス)に必ずコンテナエージェントとコンテナランタイムというものが常駐しています。いわゆるデーモンです。

ECSの場合はECS Agent、Kubernetesの場合はKubeletと呼ばれるコンテナエージェントが走っています。

さらに超有名なDockerのようなコンテナランタイムも、一緒に走っています。先ほどみなさんはオーケストレータに指示をしたので、オーケストレータがコンテナエージェントに「お前のところでコンテナを走らせてくれ」と言うと、コンテナエージェントはコンテナランタイムに対して「こんな指示が来たからコンテナを走らせてくれ」と言います。

すると、先ほどみなさんに話したコンテナイメージ、必要なものが全部入っているバイナリのようなパッケージが、コンテナイメージ置き場(スライドの右上)からダウンロードされていきます。

コンテナイメージ置き場として、AWSならAmazon ECRというサービス、あるいは有名なDocker Hubというサービスがありますが、このようなイメージ置き場からコンテナイメージをダウンロードしてきます。ダウンロードが終わったら、実際にコンテナとして実行する。このような一連の流れでみなさんのコンテナをデプロイできます。

実行したコンテナがクラッシュすると次に何が起きる?

仮に、今実行されたコンテナがクラッシュしたり、いなくなったりしたとしましょう。次に何が起こるか。コンテナオーケストレータは常にループのような、While文だと思ってかまいません、これを回しながら、最初に渡された定義ファイルに書かれたコンテナがきちんと実行されているかを常に監視しています。(スライドを指して)図で表したとおり、データプレーンの中の先ほど起動したコンテナはクラッシュしてしまいました。

すると、オーケストレータは「コンテナがクラッシュした」と検知します。でも定義ではコンテナを実行していなければならないので「もう1回実行してくれ」とコンテナエージェントにお願いするわけです。するとコンテナエージェントは先ほどと同じく、コンテナランタイムを通してコンテナを起動します。

これがコンテナの基本的なデプロイメントモデルであり、オートヒーリングと呼ばれるものの仕組みです。みなさんが宣言した定義ファイルに則って、常にその状態を維持するように、コンテナオーケストレータやエージェントが協調して動くのが、コンテナのデプロイメントモデルです。

ここで大事なことは、コンテナの実行は自動処理で非同期です。みなさんは定義ファイルを渡して「実行して」「この状態にして」とお願いしますが、そのタイミングですぐ実行されるかは誰も担保してくれません。どこかのタイミングできちんと空いているリソース、CPUやメモリのリソースに空きがあるノードを見つけたら、そこでコンテナを実行する処理が非同期で行われます。

プロダクションで提供していく場合のアプリケーション環境例

コンテナに限った話ではありませんが、アプリケーションをプロダクションで提供していく場合には、複数の環境でそれらが構成されます。一般にローカルで開発する時には開発者が何人かいて、各ラップトップでアプリケーションを起動して、コードを書いて、デバッグしながら開発します。

コードをフリーズした後リリースしていくと、テスト環境やステージング環境、本番環境があり、これらはAWS上に作られることが多いです。各環境では、みなさんが書いたアプリケーションが、コンテナにパッケージングされて実行されているわけですが、動いている数は環境によって当然違うと思います。

テスト環境はなるべくコストを低く抑えたいので、コンテナは1個しか動いていませんが、ステージング環境ではできるだけ本番に寄せつつも、そんなにたくさん走らせるほどお金を使いたくないので、2個動く。本番は実際のユーザートラフィックがくる場所で、たくさん捌ける必要があるので、6個動いてるということがあるんです。

これは一般的な環境構成の話ですが、この先に理想の世界があります。どんな理想の世界かというと、ある環境を別AWSアカウントにシュッと動かしたいニーズが出てくることがあります。

例えば、アプリケーションを作り始めた時は1個のAWSアカウントで全環境を一緒に作っていたけれど、開発者が増えてきて、例えば会社が上場することになってコンプライアンス上のいろいろなルールを決めなければならなくなってきたので、テスト環境だけ別のところに移したい。本番環境だけ別のAWSアカウントに分離したい。こういったニーズはサービスの提供期間が長くなるほど出てきます。主に運用観点で出てくるものです。

ほかにもあります。任意のタイミングでポッと環境を増やしたい。今はテスト環境、ステージング環境、本番環境がありますが、もう1つ欲しい。これは、たぶん開発者のみなさんにもすごくわかりやすいです。

例えば、プルリクエストのたびに新しい環境を作って、チャチャッとテストできたら便利だから新しい環境を作ってほしい。あるいは、すごく大きなリリースをする前にしっかり検証したいから、もう1つステージング環境を作って、大きなリリースは新しい環境で検証しつつ、並行して行われているバグフィックスなどは普通のステージング環境でやろう、といったニーズもあります。

さらに、お金がもったいないし面倒臭いので、使い終わったらサクッと環境を減らしたいニーズもきっとあるはずです。複数の環境構成の先には、このような理想の世界があります。では、これらは実現可能か。それを決める重要な要素の1つが「アプリケーションがどう実装されているか」です。

アプリケーション開発者はAmazon ECS、Kubernetesをどこまで知るべきか

コンテナワークロードは完全に理解したと思うので、セッションの本題であるアプリケーションレイヤーの話に移ります。(スライドを指して)本日のセッションタイトル「アプリケーション開発者はAmazon ECSあるいはKubernetesをどこまで知るべきなのか」。

まず結論として理想を言います。当たり前ですが、理想は自分ですべてを管理・運用できるレベルで、開発者はECSとKubernetesを知っていることです。知っていて損はないので、たぶんこれに反論する方はいないと思います。すべてを知っている、完全に理解していることが理想です。

ただ、開発と運用が完全に分断された世界で働く開発者もたくさんいます。そんな開発者にとっての現実的なゴールは何かというと、自身のアプリケーションがコンテナとして動作するために必要な各種定義を書き、それを運用できるレベルです。「どこまで知ればいいのか」という問いに対する解です。

この各種定義には、Dockerファイルなどがあります。コンテナイメージを作るためのDockerファイルを書く。ECSでいうとタスク定義・サービス定義です。どのようにコンテナを実行したいかという定義を書く。Kubernetesの場合、例えばDeploymentのマニフェストは開発者自身が書けるべきです。

たとえ会社のルールで自分では書かないにしても、それを実際に書いている人と「どういう設定にすべきか」というディスカッションができる程度の知識は必須です。さらに、定義を書くだけではなく、アプリケーション、コンテナの障害調査ができる程度の知識も必要です。

ただ、運用経験がないアプリケーション開発者がいきなり障害調査を始めるのは難易度が高くて当然です。そのため、運用知見のあるメンバーの協力が非常に重要ですが、たとえ開発と運用が分断されているとしても、開発者が責任を持つ範囲は、アプリケーションの動作に必要な定義を書き、それを実行し、運用するところまでです。

残念ながら、本日は具体的なDockerファイルやタスク定義の書き方まで踏み込むことはできませんが、この先の話を聞くうえで、これが本セッションの主張であることを頭の片隅に置いておいてもらえたら幸いです。

ここまでの話をまとめると、本日のセッションタイトルは、アプリケーション開発者がどこまで運用を知っているべきなのかという話に他なりません。少しずつ本題に入っていきます。

(次回に続く)

続きを読むには会員登録
(無料)が必要です。

会員登録していただくと、すべての記事が制限なく閲覧でき、
著者フォローや記事の保存機能など、便利な機能がご利用いただけます。

無料会員登録

会員の方はこちら

関連タグ:

この記事のスピーカー

同じログの記事

コミュニティ情報

Brand Topics

Brand Topics

  • 今までとこれからで、エンジニアに求められる「スキル」の違い AI時代のエンジニアの未来と生存戦略のカギとは

人気の記事

新着イベント

ログミーBusinessに
記事掲載しませんか?

イベント・インタビュー・対談 etc.

“編集しない編集”で、
スピーカーの「意図をそのまま」お届け!