NGINX.COM
Web Server Load Balancing with NGINX Plus


注記 -このブログは、 2020年5月時点での更新となります。この時点でのDockerコマンドに準拠し、DebianおよびAlpine Linuxディストリビューション用NGINX Plusの Dockerfileを提供しています。

Dockerは、コンテナ(軽量でスタンドアロンで実行が可能なソフトウェアパッケージであり、アプリケーションを実行するために必要なものをすべてが含んで動作する)とよばれる形式で分散型アプリケーションを構築、デプロイ、実行するためのオープンなプラットフォームです。コンテナは、Kubernetesなどのコンテナオーケストレーションプラットフォームによってデプロイや横断的な管理を行うことが可能です(このブログで取り上げたDockerコンテナの他に、 NGINXはNGINX Open SourceとNGINX Plus Ingress Controllers for Kubernetesを提供しています。NGINX Plusご利用の方は、追加料金なしでサポートを利用いただけます)。

ソフトウェアアプリケーションの観点において、NGINX Open SourceとNGINX Plusは、Dockerを利用した優れたユースケースであり、NGINXはDockerイメージのリポジトリであるDocker HubNGINX Open Source イメージを公開しています。このブログでは、Docker Hubのイメージを使用して、NGINX Open Sourceをデプロイする方法と、お客様環境でご利用いただくためのNGINX PlusのDockerイメージを作成と作成舌イメージをプロイする方法について説明します。

はじめに

Dockerオープンプラットフォームには、コンテナを構築、実行、オーケストレーションするオープンソースのランタイムであるDocker Engineと、Docker化されたアプリケーションを開発コミュニティの全体にわたって、あるいは特定の組織内で配布、共有、コラボレーションするためのホストサービスであるDocker Hubが含まれます。

Dockerコンテナは、アプリケーションをインフラストラクチャによる制約から切り離すことで、開発者がアプリケーションの動作ロジック等を含む「プログラム」に集中できるようにします。Docker化されたアプリケーションは、ラップトップ、ベアメタルサーバー、VM、クラウドなど、あらゆるインフラストラクチャで簡単に動作させることができます。モジュール型のコンポーネントにすることで、分散型アプリケーションに必要となる機能を満たした上で、簡単にデプロイや再デプロイが可能であり、継続した機能開発をリアルタイムに行うことが可能となります。

Dockerの詳細については、「Dockerとは(英語)」またはDockerのドキュメントをご覧ください。

NGINX Open SourceのDockerイメージの使用

Docker HubにあるNGINX Open Sourceイメージを使用して、DockerコンテナでNGINXインスタンスを作成できます。

まず、非常にシンプルな例から見てみましょう。コンテナとしてデフォルトのNGINX設定を使用したNGINXのインスタンスを起動するためには、次のコマンドを実行します。

# docker run --name mynginx1 -p 80:80 -d nginx
fcd1fb01b14557c7c9d991238f2558ae2704d129cf9fb97bb4fadf673a58580d

このコマンドは、NGINXイメージをベースにした、mynginx1という名前のコンテナを作成します。このコマンドは、ログファイルの名前に使用されるコンテナIDを返します。「ログの管理」を参照してください。

-pオプションは、NGINXイメージによってコンテナで公開されるポート(ポート80)を、Dockerホストの指定のポートにマッピングするようにDockerに指示します。最初のパラメータはDockerホストのポートを指定し、2番目のパラメータはコンテナで公開されるポートにマッピングされます。

-dオプションはコンテナがバックグラウンド(デタッチドモード)で実行されることを指定します。つまり、コンテナを停止するまで動作し続けますが、コマンドラインで実行されるコマンドには反応しません。次のセクションでは、コンテナとの対話方法を説明します。

コンテナが作成され、実行されていることを確認し、ポートのマッピングを確認するために、docker psを実行します(ここでは読みやすくするために出力を複数行に分けています)。>

# docker ps
CONTAINER ID  IMAGE         COMMAND               CREATED         STATUS        ...  
fcd1fb01b145  nginx:latest  "nginx -g 'daemon of  16 seconds ago  Up 15 seconds ... 

    ... PORTS              NAMES
    ... 0.0.0.0:80->80/tcp mynginx1

出力にあるPORTSフィールドは、Dockerホストのポート80がコンテナ内のポート80にマッピングされていることを示しています。NGINXが実行していることを確認するもう一つの方法は、そのポートにHTTPリクエストを行うことです。デフォルトのNGINXのウェルカムページが表示されます。

# curl http://localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
 body {
 width: 35em;
 margin: 0 auto;
 font-family: Tahoma, Verdana, Arial, sans-serif;
 }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="https://www.nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

NGINX Dockerコンテナを使った作業

これでNGINX Dockerコンテナが動作するようになりましたが、コンテンツとNGINXの構成はどのように管理すればいいのでしょうか?また、ログはどうするのでしょうか?

SSHについての注意

NGINXインスタンスへのSSHアクセスを有効にしていることが一般的ですが、Dockerコンテナは一般的に単一の目的(この場合はNGINXを実行すること)に使用されるという観点から、このNGINXイメージにはOpenSSHがインストールされていません。代わりに、Dockerでサポートされている他の方法を使います。 これらのコマンドの代わりに、以下のコマンドを実行すると、実行中のNGINXコンテナに対して(SSHセッションを起動する代わりに)インタラクティブシェルを開くことができます。ただし、この方法は、上級ユーザーにのみ推奨されます。

  • Debianシステムの場合:

    # docker exec -it NGINX_container_ID bash
  • Alpine Linuxシステムの場合:

    # docker exec -it NGINX_container_ID sh

コンテンツと構成ファイルの管理

NGINXが公開するコンテンツとNGINXの設定ファイルの両方を管理する方法として複数の方法かあります。ここでは、いくつかの方法について説明します。

オプション1 – Dockerホスト上でコンテンツと設定を管理する

コンテナを作成する際に、Dockerホスト上のローカルディレクトリをコンテナ内のディレクトリにマウントするようにDockerに指示することが可能です。NGINXイメージはデフォルトのNGINXの設定を使用しており、/usr/share/nginx/htmlをコンテナのルートディレクトリとして使用し、/etc/nginxに設定ファイルを保存しています。 Dockerホストでは、ローカルディレクトリの/var/wwwにコンテンツを置き、設定ファイルは/var/nginx/confにあるの場合、次のコマンドを実行します(読みやすくするために複数行に分けて表示しています)。

# docker run --name mynginx2 --mount type=bind source=/var/www,target=/usr/share/nginx/html,readonly --mount type=bind,source=/var/nginx/conf,target=/etc/nginx/conf,readonly -p 80:80 -d nginx

これで、Dockerホスト上のローカルディレクトリ/var/www/var/nginx/confにあるファイルへのすべての変更は、コンテナにあるディレクトリ/usr/share/nginx/html/etc/nginxに反映されるようになります。readonlyオプションを使用すると、これらのディレクトリはコンテナ内からは参照のみで、Dockerホスト上でのみ変更できるようになります。

オプション2 – Dockerホストからファイルをコピーする

もう1つのオプションは、コンテナを作成する時に、DockerにDockerホストのローカルディレクトリからコンテンツと構成ファイルをコピーさせる方法です。コンテナが一度作成されると、ファイルが変更されたときに新しいコンテナを作成するか、コンテナ内のファイルを変更したりすることでファイルの管理がなされます。ファイルをコピーする簡単な方法は、Docker Hubの新しい NGINXイメージをベースにしたDockerイメージを生成するときに、DockerfileDockerfile内のファイルコピー((COPY)コマンドでは、ローカルディレクトリのパスは、Dockerfileが配置されている場所からの相対パスになります。

この例では、コンテンツはcontentディレクトリに、構成ファイルはconfディレクトリにあります。これらは、Dockerfileが配置されているディレクトリのサブディレクトリです。NGINXイメージには、/etc/nginx/nginx.conf/etc/nginx/conf.d/default.conf.として、デフォルトのNGINX設定ファイルが含まれます。イメージに含まれるファイルではなく、ホストの設定ファイルを使用したいので、デフォルトのファイルを削除するRUNコマンドを含めます。

FROM nginx
RUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginx

Dockerfileがあるディレクトリで次のコマンドを実行して、独自のNGINXイメージを作成します。コマンドの最後にピリオド( . )があることに注意してください。これは、カレントディレクトリを、Dockerfileとコピー対象のディレクトリが含まれるビルドコンテキストとして定義します。

# docker build -t mynginx_image1 .

ここで、このコマンドを実行して、mynginx_image1イメージをベースにしたmynginx3というコンテナを作成します。

# docker run --name mynginx3 -p 80:80 -d mynginx_image1

コンテナ内のファイルを変更する場合は、オプション3で説明するヘルパーコンテナを使用します。

オプション 3 – コンテナ内のファイルを管理する

前述の「SSHについての注意」で説明したように、SSHを使用してNGINXコンテナにアクセスすることはできないため、コンテンツや構成ファイルを直接編集する場合は、シェルアクセスが可能なヘルパーコンテナを作成する必要があります。ヘルパーコンテナがファイルにアクセスできるようにするには、このイメージ用の適切なDockerデータボリュームを定義した新しいイメージを作成する必要があります。ボリュームを定義した状態で、オプション2の方法でファイルをコピーする場合、次のDockerfileを使用します。

FROM nginx
RUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginx
VOLUME /usr/share/nginx/html
VOLUME /etc/nginx

次に、以下のコマンドを実行して新しいNGINXイメージを作成します(ここでも、最後のピリオドに注意してください)。

# docker build -t mynginx_image2 .

ここで、このコマンドを実行して、mynginx_image2 イメージをベースにしたmynginx4というNGINXコンテナを作成します。

# docker run --name mynginx4 -p 80:80 -d mynginx_image2

次に、以下のコマンドを実行して、ヘルパーコンテナmynginx4_filesを起動し、このコンテナのシェルに入ると、先ほど作成したmynginx4コンテナのコンテンツと構成ディレクトリにアクセスできます。

# docker run -i -t --volumes-from mynginx4 --name mynginx4_files debian /bin/bash
root@b1cbbad63dd1:/#

新しいmynginx4_filesヘルパーコンテナは、常に標準入力を使用し(-iオプション)、tty(-tオプション)を使用してフォアグラウンドで実行されます。mynginx4で定義されたすべてのボリュームは、ヘルパーコンテナのローカルディレクトリとしてマウントされます。

引数debianを使用すると、ヘルパーコンテナはDocker Hubの Debianイメージを使用します。NGINXイメージもDebianを使用しているので(これまでの例ではすべてこのNGINXイメージを使用しています)、Dockerに別のオペレーティングシステムをロードさせるよりも、ヘルパーコンテナにDebianを使用するのが最も効率的です。引数/bin/bashを使用すると、bashシェルがヘルパーコンテナで実行され、必要に応じてファイルを修正するためのシェルプロンプトが表示されます。

コンテナを起動したり停止したりするには、以下のコマンドを実行します。

# docker start mynginx4_files
# docker stop mynginx4_files

シェルを終了してコンテナを実行したままにするには、Ctrl+pを押した後にCtrl+pを押します。実行中のコンテナでシェルをもう一度使用するには、次のコマンドを実行します。

# docker attach mynginx4_files

シェルを終了してコンテナを終了するには、exitコマンドを実行します。

ログの管理

デフォルトまたはカスタマイズしたログを構成できます。

デフォルトのログの使用

NGINXイメージは、デフォルトで、メインのNGINXアクセスログとエラーログをDockerログコレクタに送信するように構成されています。これは、stdoutstderrに紐付けられており、両方のログのすべてのメッセージは、Dockerホスト上のファイル /var/lib/docker/containers/container-ID/container-ID-json.logに書き込まれます。例えば、前述の「NGINXオープンソースDockerイメージの使用」で作成した最初のコンテナは次の通りでした。fcd1fb01b14557c7c9d991238f2558ae2704d129cf9fb97bb4fadf673a58580d

既存コンテナのコンテナIDを取得するには次のコマンドを実行します。ここでいう、container‑nameは、コンテナの作成時に--nameパラメータによって設定された値のことです(上記のコンテナIDの場合、mynginx1など)。

# docker inspect --format '{{ .Id }}' container-name

container-ID-json.logファイルを直接開くことでログを表示できますが、通常は次のコマンドを実行する方が簡単です。

# docker logs container-name

Docker Unixソケットに対してGETリクエストを発行することにより、Docker Engine APIを使用してログメッセージを抽出することもできます。 このコマンドは、アクセスログ(stdout=1で表される)とエラーログ(code>stderr=1)の両方を返しますが、単独で要求することもできます。

curl --unix-socket /var/run/docker-sock http://localhost/containers/container-name/logs?stdout=1&stderr=1

その他のクエリパラメータについては、Docker Engine APIのドキュメントをご覧ください(ページ内で「Get container logs」を検索してください)。

カスタマイズしたログの使用

ログを収集する際に別の方法を実装する場合や、特定の構成ブロック(server{}やlocation{}など)で別のログの設定を行う場合は、コンテナ内でログファイルを保存するディレクトリのためにDockerボリュームを定義し、ログファイルにアクセスするヘルパーコンテナを作成することで、希望するlogツールを自由に使用できます。これを実装するには、ログファイル用のボリューム(複数可)が含まれる新しいイメージを作成してください。

たとえば、ログファイルを/var/log/nginx/logに保存するようにNGINXを構成するには、オプション3で説明したDockerfileから開始して、このディレクトリのVOLUME定義を単に追加します。

FROM nginx
RUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginx
VOLUME /var/log/nginx/log

次に、上記で説明したようにイメージを作成し、そのイメージを使用して、ログディレクトリにアクセスできるNGINXコンテナとヘルパーコンテナを作成できます。ヘルパーコンテナには、任意のログツールをインストールできます。

NGINXの制御

NGINXコンテナのコマンドラインには直接アクセスできませんので、nginxコマンドを使用してNGINXを制御することはできません。幸いにも、シグナルを使用するとNGINXを制御できるので、Dockerではコンテナにシグナルを送信するためにkillコマンドを利用できます。

NGINXの設定をリロードするには、次のコマンドを実行します。

# docker kill -s HUP container-name

NGINXを再起動するには、次のコマンドを実行してコンテナを再起動します。

# docker restart container-name

EBOOK

NGINXクックブック
設定レシピ集(日本語版)

無料ダウンロード

Dockerを使用したNGINX Plusのデプロイ

ここまでは、NGINX Open SourceをDockerコンテナとして使用する方法について説明してきましたが、商用版のNGINX PlusでもDockerを利用できます。商用版とオープンソースの違いは、商用版のNGINX PlusはDocker Hubでは利用できないため、最初にNGINX Plusのイメージを作成する必要があることです。NGINX Plusのイメージはとても簡単に作成できます。

:NGINX PlusイメージをDocker Hubのようなパブリックリポジトリにアップロードしないでください。このような行為は、ライセンス契約違反となります。

NGINX PlusのDockerイメージの作成

NGINX Plusのイメージを生成するには、最初にDockerfileを作成します。ここで説明する例では、ベースのDockerイメージとしてDebian 10(Buster)Alpine Linux 3.11を使用しています。NGINX PlusのDockerイメージを作成する前に、お使いのバージョンのnginx-repo.crtnginx-repo.keyファイルをダウンロードする必要があります。NGINX Plusのお客様は、カスタマーポータル(MyF5)からダウンロードできます。NGINX Plusの無料トライアルを利用されている場合は、これらのファイルはトライアルパッケージと一緒に提供されます。Dockerfileがあるディレクトリ(Dockerビルドコンテキスト)にファイルをコピーします。

NGINX Open Sourceと同じように、デフォルトでは、NGINX PlusのアクセスログとエラーログはDockerログコレクタにリンクされます。ボリュームは指定されていませんが、必要に応じてボリュームを追加することができます。また、各Dockerfileを使用してベースイメージを作成し、そのイメージから前述のようにボリュームを指定して新しいイメージを作成することもできます。

NGINX Plusの新しいリリースにアップデートしたときにファイルを編集する必要がないよう、このサンプルのDockerfileでは、意図的にNGINX Plusのバージョンを指定していません。ただし、関連する手順にバージョンをコメントとして追加していますので、ファイルバージョンを指定する場合にはコメントを外してください。

同じように、NGINX Plusの正式な動的モジュールをインストールするための手順も追加(コメントアウト)しています。

デフォルトでは、コンテナの作成時にDockerホストからコピーされるファイルはありません。各DockerfileCOPY定義を追加することができます。また、作成したイメージを上記で説明したように別のイメージのベースとして使用することもできます。

NGINX Plus Dockerfile(Debian 10)

NGINX Plus Dockerfile(Alpine Linux 3.11)

NGINX Plusのイメージの作成

Dockerfilenginx-repo.crtnginx-repo.keyファイルを同じディレクトリに保存して、次のコマンドを実行し、nginxplusという名前のDockerイメージを作成します(先ほどと同じように、最後のピリオドに注意してください)。

# docker build --no-cache -t nginxplus .

--no-cache optionオプションを使用すると、Dockerはイメージをスクラッチから構築し、NGINX Plusの最新バージョンが必ずインストールされます。以前にイメージを構築するのにDockerfileを使用しており、--no-cache optionオプションを指定しなかった場合、新しいイメージでは、DockerキャッシュにあるNGINX Plusのバージョンを使用します(NGINX Plusの新バージョンがリリースされるたびにファイルを変更する必要がないように、Dockerfileでは意図的にバージョンを指定していません)。前に構築したイメージのNGINX Plusバージョンをそのまま使用される場合は、--no-cache optionオプションを省略してください。

docker images nginxplusコマンドから以下のような出力が返されると、イメージは正常に作成されています。

# docker images nginxplus
REPOSITORY  TAG     IMAGE ID      CREATED        VIRTUAL SIZE
nginxplus   latest  ef2bf65931cf  6 seconds ago  91.2 MB

このイメージをベースにして、mynginxplusという名前のコンテナを作成するには、次のコマンドを実行します。

# docker run --name mynginxplus -p 80:80 -d nginxplus

NGINX Plusコンテナは、NGINXコンテナと同じように制御および管理できます。

概要

NGINX、NGINX Plus、Dockerは、とてもスムーズに連携します。Docker HubからNGINX Open Sourceのイメージを使用する場合でも、独自のNGINX Plusのイメージを作成する場合でも、NGINXとNGINX Plusの新しいインスタンスをDockerコンテナで簡単に起動し、Kubernetes環境にデプロイできます。また、ベースのイメージから新しいDockerイメージを簡単に作成できますので、コンテナの制御や管理がさらに簡単になります。Dockerコンテナで実行しているすべてのNGINX Plusインスタンスが、サブスクリプションの範囲内であることを確認してください。さらなる詳細のご希望、ご質問等ございましたら、お問合せフォームよりご連絡ください。

Hero image
Kubernetes のテスト環境から本番環境への移行

快適なKubernetes環境を実現するには、Kubernetesネイティブなやり方でトラフィックを理解し、管理する必要があります。
このEBOOK では、POC からカナリアリリース、ブルーグリーンデプロイメントを利用し本番環境にいたるまで、トラフィックフローを柔軟に効果的に管理する際に必要となる情報や、Kubernetes 戦略に求められる要素を明確でわかりやすい解説と共に提供いたします。



著者について

Rick Nelson

Rick Nelson

RVP, Solution Engineering

Rick Nelson is the Manager of Pre‑Sales, with over 30 years of experience in technical and leadership roles at a variety of technology companies, including Riverbed Technology. From virtualization to load balancing to accelerating application delivery, Rick brings deep technical expertise and a proven approach to maximizing customer success.

著者について

Alessandro Fael Garcia

Alessandro Fael Garcia

Technical Marketing Engineer

About F5 NGINX

F5 NGINXについて
F5, Inc.は、人気のオープンソースプロジェクト「NGINX」を支援しています。NGINXはモダンアプリケーションを開発・構築するためのテクノロジースイートを提供しています。NGINXとF5製品との併用で、コードからユーザーまでの広範なアプリケーション領域をサポートし、マルチクラウドアプリケーションサービスとしてNetOpsとDevOps間の課題を解決します。

詳しくはnginx.co.jpをご覧ください。Twitterで@nginxをフォローして会話に参加することもできます。