Webinarのご案内AWSソリューションアーキテクトの篠原英治(@shinodogg)です。Webinarを開催しておりますが、7月はデプロイ強化月間とさせていただきます!以下のラインナップでお届けしますので是非ご参加ください。Webinarは、Ctrix社のGoToMeetingで配信します。セミナーの申込みおよび参加方法に関しましては、こちら(http://aws.amazon.com/jp/webinar-flow/)に詳細を記載しております。iOSアプリやAndroidアプリもございますのでご活用ください。(@thekentiest)です。ElasticBeanstalkがDockerに対応したという発表がされて以来、実際に利用してくれるお客様や、ブログを書いてくれる方がたくさんいて、嬉しい限りです。最近ではローンチ当初に比べてDeployの仕組みも改善され、Deploy時にはStagingコンテナが立ち上がり、その立ち上げが完了した後に旧コンテナとの切り替えが行われるようになり、よりダウンタイムが短くなったので、使い勝手も良くなってきたかと思っています。ところで皆さん、Dockerを使ったDevOpsを行う際、コンテナイメージを置くレポジトリはどうされていますでしょうか?ベースイメージだけを公開レポジトリ等から取得して、毎回コンテナをBuildする場合にはそれほど悩まないかもしれませんが、構築済みのコンテナイメージをPullしてDeployしたい場合には、どこかのレポジトリにイメージを置くことになるかと思います。公開可能なコンテナについては公開レポジトリでも良いかもしれませんが、そうでなければプライベートレポジトリが必要です。Deploy時間の短縮のためにネットワーク的に近い場所にレポジトリが欲しいという場合にもやはりプライベートレポジトリを用意することになるかと思います。プライベートレポジトリ自体は簡単に構築可能ですが、開発環境と本番環境どちらからもセキュアにアクセスが出来て、大規模なクラスタへのDeployにも耐えられるキャパシティと高い可用性を持つように運用するのはなかなか手間がかかります。S3をバックエンドにしたDockerプライベートレポジトリを用意して、SPOFのない、お手軽・低コスト・高信頼なプライベートレポジトリ経由のDeployを行う方法を解説します。DockerのプライベートレポジトリDockerのプライベートレポジトリを立てるのは簡単です。registryというgunicornのアプリケーションを動作させればプライベートレポジトリとして動作します。Registryを適切な設定で立ち上げれば、いつでも高い堅牢性を持つプライベートレポジトリを用意することが出来ます。registryをセットアップ済みのコンテナイメージが公開されているので、それを立ち上げるだけであれば、Dockerの動く環境で下記のコマンドを叩くだけで指定したS3バケットをバックエンドとしたプライベートレポジトリが立ち上がります。Registryを載せたインスタンスを、必要なアクセス制限を行いつつ、必要なキャパシティと可用性を維持しながら運用することを考えると、運用コストもインスタンスコストも増えてしまいます。registryの認証はベーシック認証のため、SSLが必要なのはもちろん、ユーザ名/パスワードの管理運用が発生してしまいます。Registryを、必要な時だけインスタンス上にローカルサービスとして立てるというものです。RegistryはDocker環境があればすぐ立ち上げられますし、バックエンドにS3バケットを使っていればステートレスであるため、必要な時だけ立ち上げる形でも問題ありません。ローカルでのみ利用するので、認証周りに神経質にならなくても済みます。Registry経由でイメージをPullしてDeployという流れが実現できます。ElasticBeanstalk環境のインスタンスではBuild済みのコンテナイメージをPullするだけになるので、イメージをBuildするための作業をそれぞれで行う必要がなく、Deploy時のリソース消費や所要時間の削減が可能です。上記の仕組みを実装するには、ElasticBeanstalkがアプリケーションをDeployする前後に実行するフックに必要な処理を記述したスクリプトを登録する方法が考えられます。Registryを起動するスクリプトをアプリケーションDeploy前のフックに、停止するスクリプトをDeploy後のフックに登録すれば、目的の動作を実現できるというわけです。Registryを起動するという目的を実現できます。次に、どうやってElasticBeanstalkのインスタンスに上記のようなスクリプトを配置すればよいでしょうか?SSHログインして置いたとしても、新規作成されるインスタンスには反映されません。カスタムAMIを用いることも出来ますが、その後AMIの更新の面倒を見なければいけなくなってしまいます。ElasticBeanstalkにはこういう時に便利な仕組みとして、Deployするプロジェクト内にコンフィグファイルを用意することで、環境をカスタマイズする仕組みがあります。具体的には、Deployするプロジェクト内に.ebextensionsというディレクトリを用意して、*.configという名称のファイルを配置してDeployすれば、その内容を参照して環境をカスタマイズしてくれます。上記の仕組みを使って上記のようにフックを登録する例を以下に示します。registry上記の内容を.ebextensions/setup-docker-registry.configなどのファイル名で保存して、DockerfileやDockerrun.aws.jsonと共にDeployすれば、期待通りDeploy時にのみローカルにプライベートレポジトリのフロントエンドが立ち上げる環境が構築できます。ディレクトリ構成例は以下の通りです。Registryを経由して、指定したS3バケット上のコンテナイメージを取得するという動作になります。下記はそのようなDockerfileの例です。Registryのイメージを取得することになりますが、特に指定しなければ公開レポジトリからの取得となるため、インスタンスタイプや配置するリージョンにもよりますが、結構時間がかかります。RegistryのイメージをExportしたアーカイブを置いておいて、ダウンロードしてImportとすることで解消できます。RegistryのExportは下記のようにして実行できます。registry-image.tgz次に下記のようにすれば、出来上がったアーカイブをプライベートレポジトリとして利用するS3バケットに保存できます。registry:latest上記の方法であれば、公開レポジトリからのPullに比べて大分所要時間を短縮できます。新インスタンスの起動時にのみ発生するオーバーヘッドなので、現実的には大きな問題にならない範囲かと思います。上記のような動作を実行するスクリプトを用意して、下記のように環境カスタマイズのファイルに追加しておけば、新規に起動したインスタンスもすぐに準備を整えてクラスタに参加することが出来ます。スクリプトでは、既にregistryという名称でイメージが登録されているかどうかをチェックすることで、2回目以降の無駄な作業の発生を防げます。上記の流れを実現するためのShellスクリプトのサンプルをご参考までに下記に置きました。https://gist.github.com/kntyskw/c9ec984b18249272f7e4また、上記のスクリプトを使いながら、一連の流れを組み込むためのカスタムコンフィグファイルが下記は下記の通りです。実際に試してみたい方はまずこちらを使っていただくのが早道かもしれません。registryなお、上記の設定はElasticBeanstalkの環境設定で下記の環境変数が正しく設定されていて、バケットの作成等が済んでいることが前提になっています。AWSシークレットキーまた、repositoryイメージのアーカイブが指定されたS3バケットの直下に置かれていないとダウンロードが失敗して公開レポジトリからイメージ取得となり、時間がかかるかと思いますのでご注意ください。おわりにいかがでしたでしょうか?この方法なら一度導入すれば低コスト・高信頼なプライベートレポジトリとしてS3を利用できて、しかも同一リージョン内にレポジトリを置けるので、Deployの高速化にも繋がると思います。Infrastructureを実現する一助になれば幸いです。Facebookこのブログの最新情報はTwitter、Facebookでもお知らせしています。お気軽にフォローください。