完全なDockerチュートリアル:ゼロからAWSクラスターへ









内容









質疑応答



Dockerとは何ですか?



ウィキペディアでのDockerの定義は次のとおりです。







オペレーティングシステムレベルの仮想化環境でのアプリケーションの展開と管理を自動化するためのソフトウェア。 すべての環境と依存関係を含むアプリケーションをコンテナに「パック」できます。また、コンテナを管理するための環境も提供します。









わあ! どのくらいの情報。 簡単に言えば、Dockerは開発者、システム管理者、およびその他の専門家がLinuxなどのターゲットオペレーティングシステムで実行するためにサンドボックス( コンテナと呼ばれる )にアプリケーションを展開できるツールです。 Dockerの主な利点は、アプリケーションのすべての依存関係を開発用の標準化されたモジュールパックできることです。 仮想マシンとは異なり、コンテナはこのような追加の負荷を作成しないため、システムとリソースをより効率的に使用できます。







コンテナとは何ですか?



今日の業界標準は、仮想マシンを使用してアプリケーションを実行することです。 仮想マシンは、サーバーのメインオペレーティングシステムの仮想ハードウェアで実行されるゲストオペレーティングシステム内でアプリケーションを実行します。







仮想マシンは、アプリケーションのプロセスを完全に分離するのに最適です。メインオペレーティングシステムの問題はゲストOSのソフトウェアにほとんど影響を与えず、その逆も同様です。 しかし、あなたはそのような孤立にお金を払わなければなりません。 ゲストOSハードウェアを仮想化するには、かなりの計算負荷が必要です。







コンテナは異なるアプローチを使用します。仮想マシンと同様のレベルの分離を提供しますが、メインオペレーティングシステムの低レベルメカニズムを適切に使用することにより、負荷を大幅に削減してこれを行います。







なぜ使用する必要があるのですか?



Dockerの離陸は本当に壮大でした。 コンテナー自体は新しいテクノロジーではないという事実にもかかわらず、Docker以前は、コンテナーはそれほど一般的でなく人気もありませんでした。 Dockerは、コンテナの作成と使用を大幅に簡素化する標準APIを提供することで状況を変え、コミュニティがコンテナライブラリで連携できるようにしました。 2014年半ばにThe Registerで公開された記事によると、Googleは1週間に20億個以上のコンテナをサポートしています







「Docker」という言葉のGoogleトレンド

興味







Dockerの継続的な成長に加えて、開発会社Docker Inc. 20億ドル以上の価値がありました! 効率性と移植性の利点により、Dockerはますます多くのサポートを受け始め、 コンテナ化の動きの先頭に立っています。 現代の開発者として、私たちはこの傾向を理解し、それから得られる利益を見つけなければなりません。







このマニュアルは何を教えてくれますか?



これは、Dockerを使用するすべての側面に関する単一の完全なガイドです。 Dockerとそのエコシステムに関する神話を明確にすることに加えて、クラウドで独自のWebアプリケーションを構築およびデプロイする際に少し経験を積むことができます。 Amazon Web Servicesを使用して静的サイトをデプロイし、2つの動的WebアプリケーションをElastic BeanstalkElastic Container Serviceを使用してEC2にデプロイします 。 何も展開したことがない場合でも、このガイドは必要なものすべてを提供します。







このドキュメントの使用方法



このドキュメントにはいくつかのセクションが含まれており、各セクションはDockerの特定の側面に専念しています。 各セクションでは、コマンドを入力するか、コードを記述します。 すべてのコードはgithubリポジトリで利用可能です











はじめに







注:このチュートリアルでは、Dockerバージョン1.12.0-rc2を使用します。 互換性がない場合は、 問題を送信してください。 よろしくお願いします!













前提条件







このチュートリアルを完了するために必要なのは、コマンドラインとテキストエディタの基本的なスキルだけです。 Webアプリケーションの開発経験は役立ちますが、必須ではありません。 作業の過程で、いくつかのクラウドサービスに遭遇します。 次のサイトでアカウントを作成する必要があります。













コンピューターのセットアップ







必要なツールをすべてインストールして構成するのは難しい作業ですが、幸いなことにDockerは非常に安定しており、どのOSでもDockerをインストールして実行するのは非常に簡単な作業になりました。 そのため、Dockerをインストールします。







Docker


数リリース前、OS XとWindowsでDockerを起動するのは問題がありました。 しかし、開発チームは素晴らしい仕事をしており、今日ではプロセス全体がどこにも簡単ではありません。 この入門チュートリアルには、 MacLinux、およびWindowsの詳細なインストール手順が含まれています







すべてが正しくインストールされているかどうかを確認します。







$ docker run hello-world Hello from Docker. This message shows that your installation appears to be working correctly. ...
      
      





Python


Pythonは通常、OS XおよびほとんどのLinuxディストリビューションにプリインストールされています。 Pythonをインストールする必要がある場合は、 こちらからインストーラーをダウンロードしてください







バージョンを確認してください:







 $ python --version Python 2.7.11
      
      





pipを使用して、アプリケーションのパッケージをインストールします。 pipがインストールされていない場合は、システムのバージョンをダウンロードします。







確認するには、次のコマンドを実行します。







 $ pip --version pip 7.1.2 from /Library/Python/2.7/site-packages/pip-7.1.2-py2.7.egg (python 2.7)
      
      





Java(オプション)


開発中のアプリケーションは、ストレージと検索にElasticsearchを使用します。 Elasticsearchをローカルで実行するには、Javaが必要です。 このチュートリアルでは、すべてがコンテナ内で実行されるため、ローカルでJavaを使用する必要はありません。 Javaがインストールされている場合、 java -version



で同様の出力が生成されます。







 $ java -version java version "1.8.0_60" Java(TM) SE Runtime Environment (build 1.8.0_60-b27) Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
      
      












1.0 Busyboxで遊ぶ







必要なものがすべてインストールされたので、作業を始めましょう。 このセクションでは、システムでBusyboxコンテナーを起動し、 docker docker run



を起動しdocker run









開始するには、次のコマンドを実行します。







 $ docker pull busybox
      
      





警告:Dockerをシステムにインストールした方法に応じて、 permission denied



メッセージが表示permission denied



場合があります。 Macを使用している場合は、Dockerエンジンが実行されていることを確認してください。 Linuxを使用している場合は、 sudo



このコマンドを実行します。 または、この問題を取り除くためにdockerグループ作成できます









pull



コマンドは、 Dockerレジストリからbusyboxイメージをダウンロードし、ローカルに保存します。 docker images



を使用して、システム上のイメージのリストを表示できます。







 $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE busybox latest c51f86c28340 4 weeks ago 1.109 MB
      
      









1.1 Docker Run







いいね! 次に、この画像を使用してdocker コンテナを実行します。 これを行うには、 docker run



magicコマンドを使用します。







 $ docker run busybox $
      
      





待って、何も起こらなかった! これはバグですか? まあ、いや。 内部では、多くのことが起こりました。 Dockerクライアントはイメージ(この場合はbusybox)を見つけ、コンテナーをロードし、このコンテナー内でコマンドを実行しました。 docker run busybox



を作成しましたが、コマンドを指定しなかったため、コンテナーがロードされ、空のコマンドが開始され、プログラムが終了しました。 ええ、それは一種のin辱なので、もっと面白いことをしましょう。







 $ docker run busybox echo "hello from busybox" hello from busybox
      
      





やったー、最後にある種の結論。 この場合、Dockerクライアントはコンテナ内でecho



コマンドを素直に実行してから終了しました。 おそらく、すべてが非常に迅速に行われていることに気づいたでしょう。 次に、仮想マシンを起動し、その中でコマンドを実行し、オフにする方法を想像してください。 コンテナが高速だと言う理由が明らかになりました!







では、 docker ps



見てみましょう。 実行中のすべてのコンテナのリストが表示されます。







 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      
      





コンテナは現在ないため、空の文字列が表示されます。 あまり便利ではないので、もっと便利なオプションを実行してみましょう: docker ps -a









 $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 305297d7a235 busybox "uptime" 11 minutes ago Exited (0) 11 minutes ago distracted_goldstine ff0a5c3750b9 busybox "sh" 12 minutes ago Exited (0) 12 minutes ago elated_ramanujan
      
      





これで、起動したすべてのコンテナのリストを確認できます。 STATUS



列では、コンテナが数分前に作業を完了したことがわかります。







おそらく、コンテナで複数のコマンドを実行する方法を疑問に思っているでしょう。 試してみましょう:







 $ docker run -it busybox sh / # ls bin dev etc home proc root sys tmp usr var / # uptime 05:45:21 up 5:58, 0 users, load average: 0.00, 0.01, 0.04
      
      





-it



フラグを指定したrun



コマンドは、インタラクティブttyをコンテナに接続します。 これで、内部で好きなだけコマンドを実行できます。 試してみてください。







危険! :スリルが必要な場合は、コンテナでrm -rf bin



を試してください。 ただし、 外部はなくコンテナ内で実行してください。 これを外部で行うと、コンピューター上で非常に悪くなり、 ls



echo



などのコマンドが機能しなくなります。 コンテナ内のすべてが機能しなくなったら、終了してdocker run -it busybox sh



再起動します。 Dockerは起動時に新しいコンテナを作成するため、すべてが再び機能します。









docker run



の機能のエキサイティングなツアーはこれで終わりです。 ほとんどの場合、このコマンドは頻繁に使用します。 そのため、処理方法を理解することが重要です。 run



詳細についてrun



docker run --help



を使用すると、サポートされているフラグの完全なリストが表示されます。 間もなくdocker run



を使用するいくつかの方法が表示されます。







続行する前に、コンテナの削除について簡単に見てみましょう。 docker ps -a



を使用すると、完成したコンテナーの残りを引き続き表示できることが上で確認できました。 このチュートリアルでは、 docker run



数回docker run



ます。残りのホームレスコンテナーはディスク領域を使い果たします。 そこで、コンテナの使用を終えた後にコンテナを削除することをルールにしました。 これを行うには、 docker rm



使用します。 上記の出力からID(複数可)をコピーし、パラメーターをコマンドに渡すだけです。







 $ docker rm 305297d7a235 ff0a5c3750b9 305297d7a235 ff0a5c3750b9
      
      





削除すると、識別子が再び表示されます。 多くのコンテナを削除する必要がある場合は、手動でコピーして貼り付ける代わりに、これを行うことができます。







 $ docker rm $(docker ps -a -q -f status=exited)
      
      





このコマンドは、 exited



ステータスのすべてのコンテナを削除します。 -q



フラグは数値IDのみを返し、 -f



フラグは指定された条件に基づいて出力をフィルターします。 最後の便利な詳細--rm



フラグを--rm



docker run



--rm



に渡すと、コンテナは完了時に自動的に削除されます。 これは、Dockerを使用した1回限りの起動および実験に非常に役立ちます。







docker rmi



不要な画像を削除することもできます。











1.2用語







前のセクションでは、多くのDocker固有の専門用語を使用しましたが、多くは混乱を招く可能性があります。 続行する前に、Dockerエコシステムでよく使用される用語のいくつかを見てみましょう。













2.0 WebアプリケーションとDocker







いいね! ここで、 docker run



方法を学び、いくつかのコンテナで遊んで用語を理解しました。 この知識を身につけて、DockerでWebアプリケーションをデプロイするという本物の話に進む準備ができました!











2.1静的サイト







小さく始めましょう。 まず、最も単純な静的Webサイトを検討します。 Docker Hubからイメージをダウンロードし、コンテナーを起動して、Webサーバーを簡単に起動できることを確認します。







行こう 1ページのサイトの場合、このチュートリアル用に事前に作成し、それをregister - prakhar1989/static-site



配置したイメージが必要です。 docker run



して、イメージを直接ダウンロードできます。







 $ docker run prakhar1989/static-site
      
      





イメージはローカルに存在しないため、クライアントは最初にレジスタからイメージをダウンロードしてから起動します。 すべてが問題ない場合、ターミナルでNginx is running...



メッセージが表示されます。 これでサーバーが実行されます。 動作中のサイトを見る方法は? サーバーはどのポートで動作しますか? そして、最も重要なのは、ホストコンテナーからコンテナーに直接到達する方法ですか?







この場合、クライアントはポートを開かないため、ポートを公開するにはdocker run



を再起動する必要があります。 同時に、ターミナルが実行中のコンテナに接続されていないことを確認しましょう。 この場合、ターミナルを安全に閉じることができ、コンテナは引き続き機能します。 これは分離モードと呼ばます。







 $ docker run -d -P --name static-site prakhar1989/static-site e61d12292d69556eabe2a44c16cbd54486b2527e2ce4f95438e504afb7b02810
      
      





-d



フラグはターミナルをデタッチし、 -P



フラグはすべての開いているポートを公開およびランダムにし、最後に--name



フラグはコンテナに付ける名前です。 これで、 docker port [CONTAINER]



を使用してポートを表示できます。







 $ docker port static-site 80/tcp -> 0.0.0.0:32769 443/tcp -> 0.0.0.0:32768
      
      





ブラウザでhttp:// localhost:32769を開きます。







注:docker-toolboxを使用する場合、 docker-machine ip default



docker-machine ip default



してIPアドレスを取得する必要がある場合があります。









ポートを指定することもできます。 クライアントは接続をリダイレクトします。







 $ docker run -p 8888:80 prakhar1989/static-site Nginx is running...
      
      





静的







コンテナーを停止するには、 docker stop



を実行して、コンテナーID(ID)を指定します。







同意して、すべてが非常に簡単でした。 実サーバーにインストールするには、Dockerをインストールして上記のコマンドを実行するだけです。 画像内でWebサーバーを起動する方法を見てきたので、おそらく疑問に思われますが、独自のdocker画像を作成する方法はありますか? このトピックについては、次のセクションで学習します。











2.2画像







前に画像について触れましたが、このセクションでは、Docker画像とは何か、独自の画像を作成する方法について詳しく見ていきます。 最後に、独自のイメージを使用してアプリケーションをローカルで起動し、 AWSにデプロイして友人に見せます。 かっこいい かっこいい! 始めましょう。







画像はコンテナの基本です。 最後の例では、レジスタからBusyboxと呼ばれるプーリーイメージをダウンロードし、このイメージに基づいてコンテナー開始するようにDockerクライアントに要求しました。 ローカルで利用可能な画像のリストを表示するには、 docker images



使用しdocker images









 $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE prakhar1989/catnip latest c7ffb5626a50 2 hours ago 697.9 MB prakhar1989/static-site latest b270625a1631 21 hours ago 133.9 MB python 3-onbuild cf4002b2c383 5 days ago 688.8 MB martin/docker-cleanup-volumes latest b42990daaca2 7 weeks ago 22.14 MB ubuntu latest e9ae3c220b23 7 weeks ago 187.9 MB busybox latest c51f86c28340 9 weeks ago 1.109 MB hello-world latest 0a6ba66e537a 11 weeks ago 960 B
      
      





これは、私がレジスタからダウンロードした画像のリストと、私が自分で作成した画像のリストです(すぐにこれを行う方法がわかります)。 TAG



は特定のスナップショットまたは画像のスナップショットであり、 IMAGE ID



は対応する画像の一意の識別子です。







簡単にするために、イメージをgitリポジトリとして扱うことができます。 イメージは変更にコミットでき、複数のバージョンを持つことができます。 特定のバージョンを指定しない場合、クライアントはデフォルトでlatest



バージョンを使用します。 たとえば、 ubuntu



イメージの特定のバージョンをダウンロードできます。







 $ docker pull ubuntu:12.04
      
      





新しいDockerイメージを取得するには、レジストリ(Docker Hubなど)からダウンロードするか、独自のイメージを作成します。 Docker Hubには何万もの画像があります。 docker search



を使用して、コマンドラインから直接検索できます。







ベースイメージと子イメージの違いを理解することが重要です。









公式画像とカスタム画像があり、それらはいずれも基本的なものであり、子供のものである場合があります。













2.3最初の外観







画像とは何かをよりよく理解できたので、今度は独自の画像を作成します。 このセクションの目的は、シンプルなFlaskアプリケーションで画像を作成することです。 このチュートリアルでは、猫からランダムなGIFを表示する小さなアプリケーションを作成しました。 さて、猫が嫌いなのは誰ですか? このリポジトリをローカルマシンにクローンします。







まず、アプリケーションがローカルで実行されることを確認しましょう。 cd



flask-app



ディレクトリを入力し、依存関係をインストールします。







 $ cd flask-app $ pip install -r requirements.txt $ python app.py * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
      
      





すべてが順調であれば、上記の例のような出力が表示されます。 http:// localhost:5000に移動して、アプリケーションの動作を確認します。







注: pip install



コマンドが「permission denied」エラーでクラッシュpip install



場合は、 sudo



実行してみてください。 システムレベルでカスタムパッケージをインストールしない場合は、 pip install --user -r requirements.txt



コマンドを使用します。









良さそうですね。 ここで、アプリケーションを使用してイメージを作成する必要があります。 前述のように、すべてのユーザー画像はベース画像に基づいています。 アプリケーションはPythonで記述されているため、基本的なPython 3イメージが必要です。 特に、 python:3-onbuild



バージョンが必要ですpython:3-onbuild



ベースイメージのpython:3-onbuild









onbuild



バージョンは何ですか?







これらのイメージにはいくつかのONBUILDトリガーが含まれており、通常はアプリケーションを迅速にデプロイするのに十分です。 アセンブリ中に、 requirements.txt



ファイルがコピーされ、このファイルを使用してpip install



が起動され、次に現在のディレクトリが/usr/src/app



コピーされます。









つまり、 onbuild



バージョンには、退屈なアプリケーションの起動プロセスを自動化するヘルパーが含まれています。 これらのタスクを手動で実行する(またはスクリプトを作成する)代わりに、イメージがすべてを行います。 これで、イメージを作成するためのすべての要素、つまり、機能するWebアプリケーションと基本イメージができました。 どうやってやるの? 回答: Dockerfileを使用します











2.4 Dockerfile







Dockerfileは、 Dockerクライアントコマンドのリストを含む単純なテキストファイルです。 これは、イメージを作成するプロセスを自動化する簡単な方法です。 最もクールなのは、DockerfileのコマンドがLinuxのコマンドほとんど同じであることです。 つまり、原則として、dockerfilesの操作を開始するために新しい構文を学ぶ必要はありません。







アプリケーションのディレクトリにはDockerfileがありますが、すべてを初めて行うため、最初から作成する必要があります。 お気に入りのテキストエディタで新しい空のファイルを作成し、Flaskアプリケーションが置かれているのと同じディレクトリに保存します。 ファイルにDockerfile



名前を付けます。







最初に、基本的な画像を示します。 これを行うには、 FROM



キーワードを使用します。







 FROM python:3-onbuild
      
      





さらに、通常、ファイルをコピーして依存関係をインストールするためのコマンドを示します。 しかし、幸いなことに、ベースイメージのonbuild



バージョンがこれらのタスクを処理します。 次に、開く必要があるポートを指定する必要があります。 アプリケーションはポート5000で実行されるので、それを示します。







 EXPOSE 5000
      
      





最後のステップは、アプリケーションを起動するコマンドを指定することです。 これは単なるpython ./app.py



です。 これを行うには、 CMDコマンドを使用します。







 CMD ["python", "./app.py"]
      
      





CMD



の主な目的は、起動時に実行するコマンドをコンテナに伝えることです。 これで、 Dockerfile



準備Dockerfile



できました。 これは次のようなものです。







 # our base image FROM python:3-onbuild # specify the port number the container should expose EXPOSE 5000 # run the application CMD ["python", "./app.py"]
      
      





これで、画像を作成できます。 docker build



チームは、 Dockerfile



基づいてイメージを作成するという複雑なタスクに関与しています。







以下のリストにプロセスを示します。 自分でコマンドを実行する前に(最後のドットを忘れないでください)、自分のユーザー名ではなくユーザー名が存在することを確認してください。 ユーザー名は、 Dockerハブの登録時に使用されたものと一致する必要があります。 まだ登録していない場合は、コマンドを実行する前に登録してください。 docker build



非常に単純です。- -t



フラグとDockerfile



存在するディレクトリへのパスを含むオプションのタグを受け入れます。







 $ docker build -t prakhar1989/catnip . Sending build context to Docker daemon 8.704 kB Step 1 : FROM python:3-onbuild # Executing 3 build triggers... Step 1 : COPY requirements.txt /usr/src/app/ ---> Using cache Step 1 : RUN pip install --no-cache-dir -r requirements.txt ---> Using cache Step 1 : COPY . /usr/src/app ---> 1d61f639ef9e Removing intermediate container 4de6ddf5528c Step 2 : EXPOSE 5000 ---> Running in 12cfcf6d67ee ---> f423c2f179d1 Removing intermediate container 12cfcf6d67ee Step 3 : CMD python ./app.py ---> Running in f01401a5ace9 ---> 13e87ed1fbc2 Removing intermediate container f01401a5ace9 Successfully built 13e87ed1fbc2
      
      





python:3-onbuild



がない場合、クライアントはまずそれをダウンロードしてから、イメージの作成を開始します。 そのため、画面への出力は私の出力と異なる場合があります。 注意深く見て、onbuildトリガーを見つけてください。 すべてがうまくいけば、画像の準備は完了です! docker images



を起動すると、リストにイメージが表示されます。







最後のステップは、イメージを開始して操作性を確認することです(ユーザー名を自分のものに置き換えます)。







 $ docker run -p 8888:5000 prakhar1989/catnip * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
      
      





指定されたURLに移動すると、アプリケーションが動作していることがわかります。







静的







おめでとうございます! 初めてのDockerルックの作成に成功しました!











2.5 AWSのDocker







友だちに見せられないアプリは何が良いでしょうか? このセクションでは、すばらしいアプリケーションをクラウドにデプロイする方法を学びます。 AWS Elastic Beanstalkを使用して、数クリックでこの問題を解決します。 Beanstalkがどのようにアプリケーションを簡単に管理およびスケーリングできるかを確認します。







Dockerプッシュ


AWSにデプロイする前に最初に行うことは、レジストリにイメージを公開して、AWSからダウンロードできるようにすることです。 いくつかのDockerレジスタがあります(または、独自の レジスタを作成できます )。 はじめに、 Docker Hubを使用しましょう。 ただやる:







 $ docker push prakhar1989/catnip
      
      





これが最初の投稿である場合、クライアントはログインを求めます。 Docker Hubへのログインに使用するものと同じ情報を入力します。







 $ docker login Username: prakhar1989 WARNING: login credentials saved in /Users/prakhar/.docker/config.json Login Succeeded
      
      





画像の名前を自分のものに置き換えることを忘れないでください。 クライアントが画像を公開する場所を理解できるように、 username/image_name



形式を維持することは非常に重要です。







その後、Docker Hubで画像を見ることができます。 たとえば、ここ私の画像のページがあります







注:続行する前に明確にする必要がある重要な点の1つは、AWSにデプロイするために、パブリックレジスタ(または一般に他のレジスタ)にイメージを保存する必要ないことです。 次の数百万ドルのユニコーンのスタートアップのコードを書いている場合は、このステップをスキップできます。 いくつかの構成手順をスキップして、展開を簡素化するためにイメージを公開します。









これで画像がオンラインになり、Dockerクライアントは簡単なコマンドで画像を操作できます。







 $ docker run -p 8888:5000 prakhar1989/catnip
      
      





過去にローカルの作業環境をインストールし、同僚と構成を共有しようとして苦労したことがあるなら、これがいかにクールか理解できます。 これが、Dockerが強力な理由です!







豆の木


AWS Elastic Beanstalk(EB)は、Amazon Web ServicesのPaaS(サービスとしてのプラットフォーム)です。 Heroku、Google App Engineなどを使用した場合、すべてがおなじみです。 開発者として、EBにアプリケーションの起動方法を指示すると、EBはスケーリング、監視、更新など、他のすべてを実行します。 2014年4月、EBはDockerコンテナーを起動する機能を追加しました。この特定の機会を使用して展開します。 EB , , - .







, AWS . , . . , , , .







始めましょう:









静的









静的









, Dockerrun.aws.json



. AWS, . EB .







 { "AWSEBDockerrunVersion": "1", "Image": { "Name": "prakhar1989/catnip", "Update": "true" }, "Ports": [ { "ContainerPort": "5000" } ], "Logging": "/var/log/nginx" }
      
      





, . , EB .







. EB .







静的







URL . , .







おめでとうございます! -! , , EB . , , . AWS single-container Docker environment , EB.







, , , . -. 行こう!











3.0







, . , Flask-. , . : .







, , . ( ). Redis Memcached -. , "" , .







, , -. , ? , , . ( ) .







, , . , . , , . . , ( ) .











3.1 SF Food Trucks







, , SF Food Trucks ( , — . . ). - ( ), -, , . .







sfフードトラック







(Flask), Elasticsearch . , Github . , - .







, (), , . Flask Elasticsearch. , : Flask, Elasticsearch (ES). , , .







, . , ? Flask- . Elasticsearch… , - :







 $ docker search elasticsearch NAME DESCRIPTION STARS OFFICIAL AUTOMATED elasticsearch Elasticsearch is a powerful open source se... 697 [OK] itzg/elasticsearch Provides an easily configurable Elasticsea... 17 [OK] tutum/elasticsearch Elasticsearch image - listens in port 9200. 15 [OK] barnybug/elasticsearch Latest Elasticsearch 1.7.2 and previous re... 15 [OK] digitalwonderland/elasticsearch Latest Elasticsearch with Marvel & Kibana 12 [OK] monsantoco/elasticsearch ElasticSearch Docker image 9 [OK]
      
      





, Elasticsearch. ES, docker run



, , ES.







 $ docker run -dp 9200:9200 elasticsearch d582e031a005f41eea704cdc6b21e62e7a8a42021297ce7ce123b945ae3d3763 $ curl 0.0.0.0:9200 { "name" : "Ultra-Marine", "cluster_name" : "elasticsearch", "version" : { "number" : "2.1.1", "build_hash" : "40e2c53a6b6c2972b3d13846e450e66f4375bd71", "build_timestamp" : "2015-12-15T13:05:55Z", "build_snapshot" : false, "lucene_version" : "5.3.1" }, "tagline" : "You Know, for Search" }
      
      





Flask. Dockerfile



. python:3-onbuild



. , , pip



, , Javascript- . Nodejs. , ubuntu



.







: , , . , Docker Hub Dockerfile



Github. — .









Dockerfile Flask- :







 # start from base FROM ubuntu:14.04 MAINTAINER Prakhar Srivastav <prakhar@prakhar.me> # install system-wide deps for python and node RUN apt-get -yqq update RUN apt-get -yqq install python-pip python-dev RUN apt-get -yqq install nodejs npm RUN ln -s /usr/bin/nodejs /usr/bin/node # copy our application code ADD flask-app /opt/flask-app WORKDIR /opt/flask-app # fetch app specific deps RUN npm install RUN npm run build RUN pip install -r requirements.txt # expose port EXPOSE 5000 # start app CMD [ "python", "./app.py" ]
      
      





. Ubuntu LTS , apt-get



, — Python Node. yqq



"Yes" . node. .







ADD



/opt/flask-app



. . , . , , . Node, npm , package.json . Python, CMD



, .







, ( prakhar1989



username ).







 $ docker build -t prakhar1989/foodtrucks-web .
      
      





, ubuntu, . docker build



.







 $ docker run -P prakhar1989/foodtrucks-web Unable to connect to ES. Retying in 5 secs... Unable to connect to ES. Retying in 5 secs... Unable to connect to ES. Retying in 5 secs... Out of retries. Bailing out...
      
      





! , Elasticsearch. ? — .











3.2 Docker







, , . , , .







, docker ps



, :







 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e931ab24dedc elasticsearch "/docker-entrypoint.s" 2 seconds ago Up 2 seconds 0.0.0.0:9200->9200/tcp, 9300/tcp cocky_spence
      
      





, ES 0.0.0.0:9200



, . , ES, ? , , .







 es = Elasticsearch(host='es')
      
      





Flask-, ES 0.0.0.0



( 9200



), , ? , , IP 0.0.0.0



- , . . , , ES? , .







, . , :







 $ docker network ls NETWORK ID NAME DRIVER 075b9f628ccc none null be0f7178486c host host 8022115322ec bridge bridge
      
      





bridge — , . , ES, bridge. , :







 $ docker network inspect bridge [ { "Name": "bridge", "Id": "8022115322ec80613421b0282e7ee158ec41e16f565a3e86fa53496105deb2d7", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.17.0.0/16" } ] }, "Containers": { "e931ab24dedc1640cddf6286d08f115a83897c88223058305460d7bd793c1947": { "EndpointID": "66965e83bf7171daeb8652b39590b1f8c23d066ded16522daeb0128c9c25c189", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" } } ]
      
      





, e931ab24dedc



Containers



. IP-, — 172.17.0.2



. ? : Flask- IP:







 $ docker run -it --rm prakhar1989/foodtrucks-web bash root@35180ccc206a:/opt/flask-app# curl 172.17.0.2:9200 bash: curl: command not found root@35180ccc206a:/opt/flask-app# apt-get -yqq install curl root@35180ccc206a:/opt/flask-app# curl 172.17.0.2:9200 { "name" : "Jane Foster", "cluster_name" : "elasticsearch", "version" : { "number" : "2.1.1", "build_hash" : "40e2c53a6b6c2972b3d13846e450e66f4375bd71", "build_timestamp" : "2015-12-15T13:05:55Z", "build_snapshot" : false, "lucene_version" : "5.3.1" }, "tagline" : "You Know, for Search" } root@35180ccc206a:/opt/flask-app# exit
      
      





. bash



. --rm



, . curl



, . , 172.17.0.2:9200



ES! いいね!







, , :







  1. /etc/hosts



    Flask-, , es



    172.17.0.2



    . IP- , .
  2. bridge , .


: . . /etc/hosts



, .







-, :







 $ docker network create foodtrucks 1a3386375797001999732cb4c4e97b88172d983b08cd0addfcb161eed0c18d89 $ docker network ls NETWORK ID NAME DRIVER 1a3386375797 foodtrucks bridge 8022115322ec bridge bridge 075b9f628ccc none null be0f7178486c host host
      
      





network create



bridge . . , .







. --net



. , ElasticSearch, bridge .







 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e931ab24dedc elasticsearch "/docker-entrypoint.s" 4 hours ago Up 4 hours 0.0.0.0:9200->9200/tcp, 9300/tcp cocky_spence $ docker stop e931ab24dedc e931ab24dedc $ docker run -dp 9200:9200 --net foodtrucks --name es elasticsearch 2c0b96f9b8030f038e40abea44c2d17b0a8edda1354a08166c33e6d351d0c651 $ docker network inspect foodtrucks [ { "Name": "foodtrucks", "Id": "1a3386375797001999732cb4c4e97b88172d983b08cd0addfcb161eed0c18d89", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ {} ] }, "Containers": { "2c0b96f9b8030f038e40abea44c2d17b0a8edda1354a08166c33e6d351d0c651": { "EndpointID": "15eabc7989ef78952fb577d0013243dae5199e8f5c55f1661606077d5b78e72a", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" } }, "Options": {} } ]
      
      





, , es



. , , , .







 $ docker run -it --rm --net foodtrucks prakhar1989/foodtrucks-web bash root@53af252b771a:/opt/flask-app# cat /etc/hosts 172.18.0.3 53af252b771a 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.18.0.2 es 172.18.0.2 es.foodtrucks root@53af252b771a:/opt/flask-app# curl es:9200 bash: curl: command not found root@53af252b771a:/opt/flask-app# apt-get -yqq install curl root@53af252b771a:/opt/flask-app# curl es:9200 { "name" : "Doctor Leery", "cluster_name" : "elasticsearch", "version" : { "number" : "2.1.1", "build_hash" : "40e2c53a6b6c2972b3d13846e450e66f4375bd71", "build_timestamp" : "2015-12-15T13:05:55Z", "build_snapshot" : false, "lucene_version" : "5.3.1" }, "tagline" : "You Know, for Search" } root@53af252b771a:/opt/flask-app# ls app.py node_modules package.json requirements.txt static templates webpack.config.js root@53af252b771a:/opt/flask-app# python app.py Index not found... Loading data in elasticsearch ... Total trucks loaded: 733 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) root@53af252b771a:/opt/flask-app# exit
      
      





やった! 動作します! /etc/hosts



, es:9200



— ES. いいね! Flask- -:







 $ docker run -d --net foodtrucks -p 5000:5000 --name foodtrucks-web prakhar1989/foodtrucks-web 2a1b77e066e646686f669bab4759ec1611db359362a031667cacbe45c3ddb413 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2a1b77e066e6 prakhar1989/foodtrucks-web "python ./app.py" 2 seconds ago Up 1 seconds 0.0.0.0:5000->5000/tcp foodtrucks-web 2c0b96f9b803 elasticsearch "/docker-entrypoint.s" 21 minutes ago Up 21 minutes 0.0.0.0:9200->9200/tcp, 9300/tcp es $ curl -I 0.0.0.0:5000 HTTP/1.0 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 3697 Server: Werkzeug/0.11.2 Python/2.7.6 Date: Sun, 10 Jan 2016 23:58:53 GMT
      
      





http://0.0.0.0:5000 , . , , , 4 . bash- .







 #!/bin/bash # build the flask container docker build -t prakhar1989/foodtrucks-web . # create the network docker network create foodtrucks # start the ES container docker run -d --net foodtrucks -p 9200:9200 -p 9300:9300 --name es elasticsearch # start the flask app container docker run -d --net foodtrucks -p 5000:5000 --name foodtrucks-web prakhar1989/foodtrucks-web
      
      





, . , . !







 $ git clone https://github.com/prakhar1989/FoodTrucks $ cd FoodTrucks $ ./setup-docker.sh
      
      





以上です! -, !







Docker Links


, , , docker network



, Docker 1.9 .







, network



, . , linking deprecated. , link



, network



( links legacy, — . .)











3.3 Docker Compose







. , . :







  1. Docker Machine - , -.
  2. Docker Compose — - .
  3. Docker Swarm — .


— Docker Compose, , .







Docker Compose . OrchardUp Fig. , . Hacker News - , , .







, Fig :







, : . API : ( , ) (shared volumes), - , , . : .

, "", , . Fig: . " " ( , " ") " ".









, . , Fig , Docker Inc. , Docker Compose.







, Compose ? -. docker-compose.yml



, .







, docker-compose.yml



SF-Foodtrucks , , .







Docker Compose. Windows Mac, Docker Compose — Docker Toolbox. Linux Docker Compose . Compose Python, pip install docker-compose



. :







 $ docker-compose version docker-compose version 1.7.1, build 0a9ab35 docker-py version: 1.8.1 CPython version: 2.7.9 OpenSSL version: OpenSSL 1.0.1j 15 Oct 2014
      
      





, docker-compose.yml



. yml



- , ,







 version: "2" services: es: image: elasticsearch web: image: prakhar1989/foodtrucks-web command: python app.py ports: - "5000:5000" volumes: - .:/code
      
      





. : es



web



. , image



— . es



Docker Hub elasticsearch



. Flask- — , .







command



ports



. volumes



, web



. , , . .







: docker-compose.yml



Compose.









いいね! , docker-compose



. , . Flask ES, :







 $ docker stop $(docker ps -q) 39a2f5df14ef 2a1b77e066e6
      
      





docker-compose



. Foodtrucks docker-compose up



.







 $ docker-compose up Creating network "foodtrucks_default" with the default driver Creating foodtrucks_es_1 Creating foodtrucks_web_1 Attaching to foodtrucks_es_1, foodtrucks_web_1 es_1 | [2016-01-11 03:43:50,300][INFO ][node ] [Comet] version[2.1.1], pid[1], build[40e2c53/2015-12-15T13:05:55Z] es_1 | [2016-01-11 03:43:50,307][INFO ][node ] [Comet] initializing ... es_1 | [2016-01-11 03:43:50,366][INFO ][plugins ] [Comet] loaded [], sites [] es_1 | [2016-01-11 03:43:50,421][INFO ][env ] [Comet] using [1] data paths, mounts [[/usr/share/elasticsearch/data (/dev/sda1)]], net usable_space [16gb], net total_space [18.1gb], spins? [possibly], types [ext4] es_1 | [2016-01-11 03:43:52,626][INFO ][node ] [Comet] initialized es_1 | [2016-01-11 03:43:52,632][INFO ][node ] [Comet] starting ... es_1 | [2016-01-11 03:43:52,703][WARN ][common.network ] [Comet] publish address: {0.0.0.0} is a wildcard address, falling back to first non-loopback: {172.17.0.2} es_1 | [2016-01-11 03:43:52,704][INFO ][transport ] [Comet] publish_address {172.17.0.2:9300}, bound_addresses {[::]:9300} es_1 | [2016-01-11 03:43:52,721][INFO ][discovery ] [Comet] elasticsearch/cEk4s7pdQ-evRc9MqS2wqw es_1 | [2016-01-11 03:43:55,785][INFO ][cluster.service ] [Comet] new_master {Comet}{cEk4s7pdQ-evRc9MqS2wqw}{172.17.0.2}{172.17.0.2:9300}, reason: zen-disco-join(elected_as_master, [0] joins received) es_1 | [2016-01-11 03:43:55,818][WARN ][common.network ] [Comet] publish address: {0.0.0.0} is a wildcard address, falling back to first non-loopback: {172.17.0.2} es_1 | [2016-01-11 03:43:55,819][INFO ][http ] [Comet] publish_address {172.17.0.2:9200}, bound_addresses {[::]:9200} es_1 | [2016-01-11 03:43:55,819][INFO ][node ] [Comet] started es_1 | [2016-01-11 03:43:55,826][INFO ][gateway ] [Comet] recovered [0] indices into cluster_state es_1 | [2016-01-11 03:44:01,825][INFO ][cluster.metadata ] [Comet] [sfdata] creating index, cause [auto(index api)], templates [], shards [5]/[1], mappings [truck] es_1 | [2016-01-11 03:44:02,373][INFO ][cluster.metadata ] [Comet] [sfdata] update_mapping [truck] es_1 | [2016-01-11 03:44:02,510][INFO ][cluster.metadata ] [Comet] [sfdata] update_mapping [truck] es_1 | [2016-01-11 03:44:02,593][INFO ][cluster.metadata ] [Comet] [sfdata] update_mapping [truck] es_1 | [2016-01-11 03:44:02,708][INFO ][cluster.metadata ] [Comet] [sfdata] update_mapping [truck] es_1 | [2016-01-11 03:44:03,047][INFO ][cluster.metadata ] [Comet] [sfdata] update_mapping [truck] web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
      
      





IP . , ? - . detached mode:







 web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) Killing foodtrucks_web_1 ... done Killing foodtrucks_es_1 ... done $ docker-compose up -d Starting foodtrucks_es_1 Starting foodtrucks_web_1 $ docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------- foodtrucks_es_1 /docker-entrypoint.sh elas ... Up 9200/tcp, 9300/tcp foodtrucks_web_1 python app.py Up 0.0.0.0:5000->5000/tcp
      
      





, . ? Compose . ? Compose ? , .







, . :







 $ docker-compose stop Stopping foodtrucks_web_1 ... done Stopping foodtrucks_es_1 ... done
      
      





, foodtrucks



, . , Compose .







 $ docker network rm foodtrucks $ docker network ls NETWORK ID NAME DRIVER 4eec273c054e bridge bridge 9347ae8783bd none null 54df57d7f493 host host
      
      





クラス! , Compose .







 $ docker-compose up -d Recreating foodtrucks_es_1 Recreating foodtrucks_web_1 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f50bb33a3242 prakhar1989/foodtrucks-web "python app.py" 14 seconds ago Up 13 seconds 0.0.0.0:5000->5000/tcp foodtrucks_web_1 e299ceeb4caa elasticsearch "/docker-entrypoint.s" 14 seconds ago Up 14 seconds 9200/tcp, 9300/tcp foodtrucks_es_1
      
      





. , - :







 $ docker network ls NETWORK ID NAME DRIVER 0c8b474a9241 bridge bridge 293a141faac3 foodtrucks_default bridge b44db703cd69 host host 0474c9517805 none null
      
      





, Compose foodtrucks_default



, , . , . hostname, . , /etc/hosts



.







 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bb72dcebd379 prakhar1989/foodtrucks-web "python app.py" 20 hours ago Up 19 hours 0.0.0.0:5000->5000/tcp foodtrucks_web_1 3338fc79be4b elasticsearch "/docker-entrypoint.s" 20 hours ago Up 19 hours 9200/tcp, 9300/tcp foodtrucks_es_1 $ docker exec -it bb72dcebd379 bash root@bb72dcebd379:/opt/flask-app# cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.18.0.2 bb72dcebd379
      
      





! , es



. ? :







 root@bb72dcebd379:/opt/flask-app# ping es PING es (172.18.0.3) 56(84) bytes of data. 64 bytes from foodtrucks_es_1.foodtrucks_default (172.18.0.3): icmp_seq=1 ttl=64 time=0.049 ms 64 bytes from foodtrucks_es_1.foodtrucks_default (172.18.0.3): icmp_seq=2 ttl=64 time=0.064 ms ^C --- es ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.049/0.056/0.064/0.010 ms
      
      





出来上がり! 動作します! - es



. , Docker 1.10 , DNS-. , release notes .







Docker Compose . , , . Docker Compose.







, Compose. AWS!











3.4 AWS Elastic Container Service







docker-compose



: docker-compose up



. , , , , . , AWS.







, , Docker — . . . , - AWS, Azure , Rackspace , DigitalOcean . Elastic Beanstalk, AWS Elastic Container Service ( ECS) .







AWS ECS — , . EC2 API. Beanstalk , ECS . ECS — .







, ECS (CLI) Docker Compose ECS! docker-compose.yml



, AWS . さあ始めましょう!







CLI. CLI- Windows. CLI Mac Linux . , :







 $ ecs-cli --version ecs-cli version 0.1.0 (*cbdc2d5)
      
      





— . EC2 Console keypair. . — . ecs



us-east-1



. .







keypair.png







CLI:







 $ ecs-cli configure --region us-east-1 --cluster foodtrucks INFO[0000] Saved ECS CLI configuration for cluster (foodtrucks)
      
      





configure



, , . , . AWS CLI , , .







CloudFormation .







 $ ecs-cli up --keypair ecs --capability-iam --size 2 --instance-type t2.micro INFO[0000] Created cluster cluster=foodtrucks INFO[0001] Waiting for your cluster resources to be created INFO[0001] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS INFO[0061] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS INFO[0122] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS INFO[0182] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS INFO[0242] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS
      
      





, ( ecs



), ( --size



) , . --capability-iam



, , IAM.







docker-compose.yml



. , , aws-compose.yml



. ( ):







 es: image: elasticsearch cpu_shares: 100 mem_limit: 262144000 web: image: prakhar1989/foodtrucks-web cpu_shares: 100 mem_limit: 262144000 ports: - "80:5000" links: - es
      
      





docker-compose.yml



mem_limit



cpu_shares



.







, version



services



, AWS 2 Compose. t2.micro



, 250 . Docker Hub. , ecs-cli build



. Docker Compose .







 $ docker push prakhar1989/foodtrucks-web
      
      





美人! , ECS!







 $ ecs-cli compose --file aws-compose.yml up INFO[0000] Using ECS task definition TaskDefinition=ecscompose-foodtrucks:2 INFO[0000] Starting container... container=845e2368-170d-44a7-bf9f-84c7fcd9ae29/es INFO[0000] Starting container... container=845e2368-170d-44a7-bf9f-84c7fcd9ae29/web INFO[0000] Describe ECS container status container=845e2368-170d-44a7-bf9f-84c7fcd9ae29/web desiredStatus=RUNNING lastStatus=PENDING taskDefinition=ecscompose-foodtrucks:2 INFO[0000] Describe ECS container status container=845e2368-170d-44a7-bf9f-84c7fcd9ae29/es desiredStatus=RUNNING lastStatus=PENDING taskDefinition=ecscompose-foodtrucks:2 INFO[0036] Describe ECS container status container=845e2368-170d-44a7-bf9f-84c7fcd9ae29/es desiredStatus=RUNNING lastStatus=PENDING taskDefinition=ecscompose-foodtrucks:2 INFO[0048] Describe ECS container status container=845e2368-170d-44a7-bf9f-84c7fcd9ae29/web desiredStatus=RUNNING lastStatus=PENDING taskDefinition=ecscompose-foodtrucks:2 INFO[0048] Describe ECS container status container=845e2368-170d-44a7-bf9f-84c7fcd9ae29/es desiredStatus=RUNNING lastStatus=PENDING taskDefinition=ecscompose-foodtrucks:2 INFO[0060] Started container... container=845e2368-170d-44a7-bf9f-84c7fcd9ae29/web desiredStatus=RUNNING lastStatus=RUNNING taskDefinition=ecscompose-foodtrucks:2 INFO[0060] Started container... container=845e2368-170d-44a7-bf9f-84c7fcd9ae29/es desiredStatus=RUNNING lastStatus=RUNNING taskDefinition=ecscompose-foodtrucks:2
      
      





, Docker Compose — . --file



( docker-compose.yml



). , desiredStatus=RUNNING lastStatus=RUNNING



.







かっこいい! . ?







 ecs-cli ps Name State Ports TaskDefinition 845e2368-170d-44a7-bf9f-84c7fcd9ae29/web RUNNING 54.86.14.14:80->5000/tcp ecscompose-foodtrucks:2 845e2368-170d-44a7-bf9f-84c7fcd9ae29/es RUNNING ecscompose-foodtrucks:2
      
      





http://54.86.14.14 , Food Trucks - ! , AWS ECS .







ECSクラスター







ECSクラスター







, ECS- 'foodtrucks', . .







以上です。 — AWS!











4.0







. , , ! , . , , - , , .







, . , , .











4.1







. . , . , , . , , , .







— . . — .







追加のリソース









, !











4.2







. ? , -?







( , — . .) prakhar@prakhar.me issue . , , .







( -, — . .).







. . , . .








All Articles