こんにちは。Inagora東京オフィス技術チームの高崎です。 先日技術チームでは、基盤チームの張 朕檳(ちょうちんびん、通称:bin)さん主催の、Docker勉強会を開催しました!
弊社は、日本の製品を中国のお客様にお届けするという越境ECというビジネスを行っています。日本の技術チームは主に、日本側のメーカー、卸様から、商品を仕入れ、それを中国の倉庫まで輸出するところまでを管理するSCM(Supply Chain Management System)を外部パッケージなどを利用せず、すべて自社で内製しています。 創業から4年近くたち、既存のシステムでは性能面などで不安な点もあり、現在基盤チームの2名が中心となって、システムのベースの改修が進められています。
Dockerとは何か?
Dockerは、「コンテナ(Container)」と呼ばれる開発のための仮想環境を簡単に構築することの出来るツールです。 仮想環境と言えばVirtualBoxやVagrantを使って、仮想環境を作っている方も多いと思いますが、VirtualBoxは、ゲストOSをインストールして、ハードウェアを仮想化し、その中で様々なアプリケーションを動かしています。それに対して、コンテナは一つ一つのアプリケーション(プロセス)の実行に関わる環境を仮想化します。
Dockerと仮想マシンの違い
(引用:https://www.docker.com/resources/what-container) 上記の図を見て分かる様に、左側のコンテナ化されたアプリケーションでは、あくまでOSは一つであり、その上にDockerが管理する複数のアプリケーションが稼働しています。つまり、Docker はコンテナに対するオペレーティングシステム (ランタイム) と考えられます。 それに対して、右側の図(仮想マシン)では、仮想マシン一つ毎に、それぞれゲストOSをインストールする必要があります。そのため、ディスク使用量が大きくなり、仮想環境 (インスタンス) 作成や起動が遅くなったり、性能が劣化すると言われています。 仮想化という概念は、決して新しいものではありませんが、Dockerは、これまでの仮想化の問題点を解決し、かつ仮想化の恩恵を受けやすくするためのツールと理解すれば良さそうです。 概念を理解したところで、実際に手を動かしながらDockerを確認した方が分かりやすいと思うので、実際に今回の勉強会で扱った、簡単なサンプルとしてNginxのコンテナを作成してみましょう。 Dockerの操作は、基本的にターミナルからDockerクライアントを通して行います。 まずDockerクライアントがインストールされていることを確認しておきましょう。 今回は、Macの環境を前提として、作業を進めていきます。 もし、Dockerをインストールされていない場合は、公式サイト(https://docs.docker.com/docker-for-mac/install/)からインストールしておきましょう。
インストール後、ターミナルでdockerコマンドが使用出来れば準備OKです。
まず、コンテナを作成するためには、Docker imageと呼ばれるファイルを取得する必要があります。Docker imageとはコンテナを定義する読み取り専用のテンプレートです。imageには、実行されるコードと、コードに必要なライブラリや依存関係の定義が含まれています。 imageは、自分で作成することも出来るのですが、今回は簡単に試すために、既存のimageを利用しましょう。 今回はサンプルとしてWebサーバのnginxのimageを使って、コンテナを作成します。 imageの取得方法ですが、Dockerクライアントを使って、pullコマンドで簡単に取得出来ます。
pullする際に、バージョン指定も出来ますが、指定しない場合は最新版がダウンロードされます。 今回は指定していないので、最新版(latest)がインストールされました。 ダウンロードが完了したかどうかは、docker image ls(もしくはdocker images)コマンドで確認出来ます。
いきなりgitでお馴染みのpullコマンドが出てきましたが、これはgitのpullとは無関係です。 では、どこからimageを取得したかと言うと、Docker Hubというサイトから、ダウンロードしています。
(引用:https://hub.docker.com/) こちらはDocker社が提供するサービスで、様々なimageを公開・管理しています。 この様にimageを管理する公式のサービスがあるおかげで、すぐに必要なimageを探すことが出来るんですね(便利☺)。 つまり、先程のpullコマンドで、DockerHubに公開されている、こちらのimageをダウンロードしてきたことになります。
(引用:https://hub.docker.com/_/nginx) ちなみに、imageファイルをホストするサービスは、Docker Hubだけでなく、AWSの管理するAmazon Elastic Container Registry (ECR)(https://aws.amazon.com/jp/ecr/)などもあります。 それでは、早速取得したimageを使って、dockerコンテナを生成しましょう。 コンテナ生成のためにはdocker run コマンドを使用します。なんとこのコマンドだけで、コンテナの生成は完了です。
docker run は、指定したimageから、コンテナを生成します。なので、docker run nginx でnginxのimageから、コンテナを作成して下さいと、Dockerクライアントを通してリクエストしています。 また、今回は実行に際し、いくつかオプションを設定しています。 -dは、起動したコンテナを対話式ではなく、バックグラウンドで動かしたい時に、設定するオプションです。(切り離す、という意味のdetachの略です。) また、-pで使用するポート番号を指定しています。今回はアクセスするポート番号に8080、コンテナ側のポート番号に80を指定しました。 なので、今回はlocalhostの8080ポートに、アクセスした時に、自動的にコンテナの80番ポートに転送されることになります。(この様な仕組みをport forwardと言います。) では、ここまで出来れば、実際にコンテナが立ち上がります。ステータスを確認してみましょう。
作成したコンテナの一覧を表示するには、docker container ls もしくは、docker psコマンド(旧体系)を使用します。 今回作成したnginxのコンテナが、いい感じに立ち上がっているのが確認出来ます。 コンテナの起動が確認出来たら、早速、nginxにアクセスしてましょう。
今回は、クライアント側のportに8080番を指定しているので、http://localhost:8080/ にアクセスすれば、nginxの初期画面が表示されるはずです。 はい🎉簡単ではありますが、レスポンスが正常に返ってくることが確認出来ました。 あっと言う間に、nginxのインストールから、dockerコマンドを数回叩いただけで、簡単に開発環境の一部をつくることが出来ました。 このように、各自がマニュアル等に従ってローカル開発環境を整備せずに、imageに基づいた同じ環境を素早く構築出来ることがDockerを使う最大の利点です。 現場毎にある秘伝の書の様な開発環境セットアップマニュアルや、個々のマシンの微妙なバージョンの違いによる不具合に、煩わされることも減りそうですね。 チーム開発が前提となる現在のソフトウェア開発では、その恩恵は非常に大きそうです。 最後に、作ったコンテナを停止&削除してみます。
削除できたか、確認したい場合は、再度docker container lsコマンド(もしくはdocker ps)で、コンテナ一覧を確認してみましょう。何も表示されなければOKです。 さて、ここまでで、一通りのdockerコンテナの作成方法を確認にてきましたが、実際の業務では、nginxだけでなくデータベースや特定バージョンのプログラミング言語やフレームワークなど様々なソフトウェアをインストールして環境構築する必要があると思います。 そんな時に、一つ一つimageをダウンロードして管理して行くのは、現実的ではありませんし、ミスも起きやすいです。そんな時に使うのが、docker-composeファイルです。 docker-composeとは、文字通り、dockerコンテナの構成を記述したファイルで、YAML形式で記述出来ます。 docker-composeにアプリケーションに必要なミドルウェアなど、記述しておくことによって、それらをコマンド一発でコンテナとして立ち上げることが可能です。 docker-composeファイルは、開発用環境、本番用環境で切り分けたりすることも可能なので、実運用の際のメンテナンスもしやすいのも嬉しいですね。
ここでは、詳細は述べませんが、docker-composeに関しても、調べてみて下さい。 ここまで簡単ですが、Dockerのインストール及び、コンテナの作成方法まで見てきました。 今回紹介したのは、Dockerの導入のほんの一部のみですが、少しでもDocker化のメリットが伝われば嬉しいです。 Inagora技術チームでは、これからも定期的に勉強会を開催して、最新技術や、興味のある技術、役に立たないかもしれないけれど、面白い技術など、このブログを通してアウトプットして行く予定です。引き続き、よろしくお願いします!💪💪💪