AWS Startup ブログ

スタートアップのためのコンテナ入門 – 導入編

こんにちは、スタートアップ ソリューションアーキテクトの松田 (@mats16k) です。

今回はコンテナのお話です。今日、多くのスタートアップのお客様が本番環境でコンテナを採用し、ビジネスに活かしております。その一方で、「そろそろコンテナやった方がいいか?」「なんとなく使い始めたけれどこれでいいのか?」「コンテナ自体は分かったけど、サービスでの利用に踏み切れていない」といったご相談も数多く頂いております。

本記事ではコンテナ技術のサービス利用を検討されている方向けに、AWS 上でどうコンテナ化を進めていけばいいのかをお話致します。

目次

コンテナとは

まずはじめに改めてコンテナ技術についての復習です。

アプリケーションコードを実行するには、そのコードだけではなく関連するコンポーネントが揃っている必要があります。例えば、 Ruby on Rails で書かれたアプリケーションを実行する際にはそのコードの他に、(もちろん Node.js でも Golang でも構いません)

  • ランタイム:Ruby 2.x
  • 依存ライブラリ:rails, rmagick, etc…
  • 依存パッケージ:ImageMagick, etc…
  • 設定

などが揃っており、適切に設定されている必要があります。また、これらのコンポーネントには依存関係があるため、

  • アプリケーションエンジニア:gem 等での依存ライブラリの管理
  • インフラエンジニア:ランタイム、依存パッケージ、OSや環境変数の設定

のような役割分担で業務を行っている際に、「必要なパッケージが入っていない」あるいは 「ランタイムとライブラリの整合性が取れていない」といった場面に遭遇することも多いのではないでしょうか。環境のコード化などで管理を助けてくれるツールも多くありますが、これらの整合性を保つためにそれなりの労力を払う必要があります。

アプリケーションを構成するコンポーネント

このような依存関係の問題を解決するための手段として「コンテナ」が利用されます。

アプリケーションの実行に必要な依存物を全てコンテナの中にパッケージングし、このパッケージをそのままデリバリーすることで、開発環境から本番環境まで同一の環境(コンテナ)でアプリケーションを動作させることが出来るようになります。

上の図では設定が含まれていませんが、コンテナワークロードでは環境によって異なる設定(例えばデータベースの接続先など)を外部から環境変数として引き渡すことがベストプラクティスとされます。例えば、WordPress の Docker イメージ では WORDPRESS_DB_HOST や WORDPRESS_DB_USER などが環境変数から設定可能になっています。これにより、開発・ステージング・本番などの環境で、同一の Docker イメージを利用できるようになります。

このようにパッケージングされたコンテナを実行するツールとして、デファクトスタンダードとなっているのが Docker になります。Docker Engine が動いている環境であればどこでも docker pulldocker run といったコマンドでコンテナを実行することが出来ます。(Linux 上で Windows コンテナが動かないなどの制約はあります。)

Docker Engine の管理するスコープとしては、単一のホストマシン上でのコンテナの動作になります。それ以外の部分、例えばコンテナのオートスケーリングや複数のホストマシンにまたがるような配置、ローリングアップデートなどは別の仕組みとして実装する必要があります。

 

コンテナオーケストレーション

そこで登場するのがオーケストレーションツールになります。

Amazon ECSAmazon EKS といったサービスがこれにあたり、複数のホストマシンにまたがるコンテナの配置やコンテナのアップデート、ロードバランサーへの紐づけなどを管理してくれます。ユーザはこれらのサービスに API 経由で変更後の状態を指示し、オーケストレーションツールはその状態になるように、あるいは維持するように動作します。これを「宣言的デプロイメント」と呼んだりします。

Amazon ECS を利用した宣言的デプロイメントのイメージ図

Amazon ECS を利用した宣言的デプロイメントのイメージ図

コンテナ技術により解消したい技術課題は企業により様々ですが、何かしらのオーケストレーションツール抜きにコンテナワークロードを考えるのは現実的に難しいでしょう。MVP (Minimum Viable Product) として開発してる場合など、docker-compose で本番稼働しているサービスを動かしているケースも見られますが、サービスの信頼性を考えると単一のホストマシンのみで動かすことは望ましくなく、複数のホストマシンにまたがる運用をオーケストレーションツール抜きに実装することはなかなか困難を伴います。

コンテナ技術そのものとオーケストレーションツールがもたらすメリットや特性をしっかりと認識することがより良いアーキテクチャや運用に繋がります。

 

コンテナ利用時・検討時によくある誤解

これからコンテナ化していきたいというお客様から相談をいただく中で、よくある誤解や認識違いがあります。多くは実際にコンテナに触れていく中で解消されるものですが、予め把握していることでスムーズに移行を進められるでしょう。

 

誤解1:コンテナに移行「しなければならない」と漠然と思っている

そろそろうちもコンテナを。。という相談は正直多く頂いており、これからはコンテナだと主張するエンジニアが増えているのも事実です。もちろんコンテナが解決する技術課題は多くありますが、解決したい課題をあまり明確化せずに漠然とコンテナ化を検討しているお話もよく耳にします。

上手くコンテナを活用されている企業の多くは技術特性を踏まえた上で、コンテナだけではなく Amazon EC2 (仮想マシン)や AWS Lambda 等を使い分けております。社内のエンジニアのスキルとの相性も重要です。私達もご相談を頂いた際に、あえてコンテナ化を勧めないケースが多くあります。もし、コンテナ利用のイメージが沸かないまま漠然と今より良くなると思い、移行の必要性を感じているようであれば、その技術が具体的に何を解決するのかを改めて検討することをオススメします。

 

誤解2:コンテナ化により仮想マシンの管理・運用が不要になる

ランタイムやパッケージ等をコンテナとして管理することが出来るようになるので、ホストマシン上でそれらの管理をする必要が無くなる、あるいはコンテナとして管理出来るのでより容易になる、ということであれば正しいです。ですが、ホストマシンそのものの管理・運用が不要になるかというと、そのようなことはありません。

コンテナが動くホストマシンでは当然 OS が動いていますし、Docker の利用には Docker Engine が動いている必要があります。ecs-agent (Amazon ECS)kubelet (Kubernetes) 等のオーケストレーションツールのデーモンが動いていることもあるでしょう。これらへのパッチ当てやバージョンアップは依然として必要です。また、コンテナをスケールさせ数を増やす際は、コンテナの実行環境となるホストマシンを増やす必要があります。

コンテナが動くホストマシンのイメージ図(シマシマの箱がコンテナ)

コンテナが解決する技術課題は多くありますが、その一方で「コンテナ」と「コンテナの実行環境となるホストマシン」の両方を管理・運用しなければならない ことを認識する必要があります。

このような一般的なコンテナワークロードにおける二重管理の課題を解決するために、AWS では AWS Fargate という機能を提供しております。こちらについては次回以降詳しく解説する予定です。

 

誤解3:まずはじめにオーケストレーションツールを選定しなければならないと思っている

お客様コンテナの利用を検討されている場合に、オーケストレーションツールの選定から始められるケースが多々あります。「コンテナへ移行を考えているのですが、今始めるのであれば○○がいいでしょうか?」といった質問を頂くことも多くありますが、移行の初手でこうした選択をする必要性はあまりありません。

自社の技術的な課題や優先したい方針によって適したツールは変わります。これは今ツールを決定したとしても、将来的に変わる可能性があることを意味します。また、コンテナに関する知見が深まる中で選択が変化することもあるでしょう。アプリケーションがコンテナに最適化されていればその移行は比較的容易で不可逆ではありません。むしろアプリケーションがコンテナに最適化されているかどうかの方が重要であると言えます。後述していますが、アプリケーションをコンテナに最適化し Docker イメージをレジストリに登録するところまでは、ツールに依らず必要になるので、これらの作業から進めていく方が好ましいでしょう。

 

誤解4:コンテナを使うならマイクロサービス化しなければならない。(あるいは)マイクロサービス化するならコンテナ化しなければならない。

特性的に相性がいい点があるのは事実ですが、依存関係はありません。あくまでユースケースのうちの1つです。コンテナを利用せずにマイクロサービス化しているケースもありますし、モノリシックなアプリケーションをコンテナで運用されているケースも多くあります。

 

コンテナへの移行ステップ

ではどの様にコンテナ移行していけばいいのでしょうか。比較的容易な移行パスは既存のアプリケーションをコンテナ化し本番稼働まで持っていくことです。具体的には次の様なステップです。

  1. コンテナ化するアプリケーションを選定する
  2. コンテナでアプリケーションが動くようにする、適した設計にする
  3. Docker イメージをビルドする
  4. イメージレジストリに登録する
  5. 本番環境の構成を考える、実装する (with オーケストレーションツール)
  6. CI/CD のパイプラインを実装する

実際にサービス提供をするとなると、5, 6 が非常に重要になりますが、まずは 4 までをしっかり行うことをおすすめします。アプリケーションを正常に実行できるコンテナがあれば、様々な環境で実行し Try & Error を行うことが出来るようになるからです。

コンテナの実行環境やオーケストレーションツールの選定から始められる方がいらっしゃいますが、実際にコンテナ上で動くアプリケーションが手元にあることで、検証をスムーズに行え実挙動を自前のアプリケーションで確認することが出来るのでおすすめです。(もちろん、コンテナに精通されているエンジニアの方はこの限りではありません。)

それぞれのステップで注意すべき点について触れていきます。

 

1. コンテナ化するアプリケーションを選定する

特に言語等の制約はありませんが、シンプルでモノリシックなアプリケーションの方が初めてのコンテナという観点では容易かと思います。複数の機能がある場合などは、それぞれ分けて検討を進めるなども有効です。例えば、Ruby on Rails で実装された Web アプリケーションと sidekiq で実装された非同期処理を分けて考えるなどです。このような場合、まずは「Web アプリケーションをどうコンテナで動かすか」にフォーカスし進めたほうが、早く次のステップに進め、結果としてコンテナのへの理解を深めることにも役立つでしょう。

 

2. コンテナでアプリケーションが動くようにする、適した設計にする

重要なことはステートレスにアプリケーションを設計することです。具体的にはセッション情報をファイルやメモリに持たず外部の Amazon ElastiCache に置いたり、画像ファイルをローカルのファイルシステムではなく Amazon S3 に配置するなどです。ログも /var/log 配下に溜め込まず、標準出力経由で Amazon CloudWatch Logs 等で保管できるといいでしょう。(Docker にはコンテナから標準出力されたログデータをハンドリングするための logging driver という仕組みがあり、その中の awslogs logging driver を利用することで Amazon CloudWatch Logs にログを送ることが可能です。)

より体系化された方法としては The Twelve-Factor App があげられます。全てを網羅せずともコンテナ上でアプリケーションを動かすことは可能ですが、どの様なアプリケーションが向いているかの理解を深めるためにもひと通り目を通しておいた方がいいでしょう。

※昨今の技術進歩によりコンテナでステートフルな要素を扱うことは日々現実味を増してきていますが、入門としては上記の内容を踏まえた上で検討されるのがいいでしょう。

 

3. Docker イメージをビルドする

Docker イメージをビルドするには、どの様なイメージを作成するかという設計図が必要です。最も一般的な方法は Dockerfile の利用です。Dockerfile により構成をコード化することで、 docker build コマンドで Docker イメージを安定的にビルド出来るようになります。

docker run コマンドで起動したコンテナ内で任意のコマンドを実行し docker commit で保存するという、手動でホストマシンを管理・運用しているようなことも機能的には可能ですが、よいコンテナワークロードのためには Dockerfile によるコード化は必須と言えるでしょう。

 

4. イメージレジストリに登録する

Docker Hub や Amazon ECR といったイメージレジストリに Docker イメージを登録します。Docker イメージには一意な URI が振られ、本番環境等で実行する際はこの URI を指定することになります。例えば 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my_app:v1.1 のような感じです。

ここまで出来ればこの Docker イメージを任意の環境で動かせるようになります。逆にいうと、クラウドの利用やオーケストレーションツールの選択に依らず必要な作業と言えます。

 

5. 本番環境の構成を考える、実装する (with オーケストレーションツール)

ここまで来てようやくアプリケーションの実行環境について考えることが出来ます。AWS であれば Amazon ECSAmazon EKS といったサービスを利用し、サービスの実行環境を整備していくことになります。

このタイミングで当初想定されていたオーケストレーションツールから乗り換えられるケースも多くありますし、アプリケーションがコンテナ上で動くようになっているのであればオーケストレーションツールの移行は比較的容易になります。

 

6. CI/CD のパイプラインを実装する

サービス提供上は必須ではありませんが、コンテナ利用に伴い発生する Docker イメージのビルド等の手間は自動化していくことが望ましいでしょう。コンテナの活用により便利になる部分が多くあるとの同時に、やらなければならないことが増えるのも事実です。コンテナを利用している多くのお客様は、アプリケーションのテストやデプロイに伴う Docker イメージのビルドや登録を CI/CD (継続的インテグレーション/継続的デリバリー)のパイプライン内で自動化しています。これらを自動化し上手く付き合っていくことがコンテナワークロードの成功に大きく影響します。こちらについては別途詳しく解説する予定です。

 

まとめ

いかがでしょうか。コンテナについてイメージが湧きましたでしょうか。

「コンテナを利用したい」とご相談を頂く多くのお客様が、具体的なイメージが無いまま相談に来られます。もちろんきっかけは興味関心やトレンドであってもいいかと思いますが、自社のサービスで活用する際には解決できる技術的課題や必要になる作業を具体化していくことが重要になります。

次回からは具体的に AWS のコンテナ関連サービスを利用してどうサービスを提供していくかについてご紹介していきます。

 

このブログの著者

Kazuki matsuda

松田 和樹 (Kazuki Matsuda) @mats16k

コンテナやビッグデータが得意分野なスタートアップソリューションアーキテクト。好きなサービスは AWS Fargate, AWS Chalice 。最近は AWS Amplify が好きです。