Ubuntu16.04でDockerコンテナのリバースプロキシとしてTraefikを使用する方法
序章
Docker は、本番環境でWebアプリケーションを実行するための効率的な方法ですが、同じDockerホストで複数のアプリケーションを実行したい場合があります。 この状況では、ポート80と443のみを他の世界に公開する必要があるため、リバースプロキシを設定する必要があります。
Traefik は、独自の監視ダッシュボードを含むDocker対応のリバースプロキシです。 このチュートリアルでは、Traefikを使用して、リクエストを2つの異なるWebアプリケーションコンテナーにルーティングします。WordpressコンテナーとAdminerコンテナーで、それぞれがMySQLデータベースと通信します。 Let's Encrypt を使用して、HTTPS経由ですべてを提供するようにTraefikを構成します。
前提条件
このチュートリアルに従うには、次のものが必要です。
- Ubuntu16.04初期サーバーセットアップガイドに従ってセットアップされた1つのUbuntu16.04サーバー。これには、sudo非rootユーザーとファイアウォールが含まれます。
- サーバーにDockerがインストールされています。これは、 Ubuntu16.04にDockerをインストールして使用する方法に従って実行できます。
- Ubuntu16.04にDockerComposeをインストールする方法の手順に従ってインストールされたDockerCompose。
- ドメインと3つのAレコード、
db-admin、blog、monitorで、それぞれがサーバーのIPアドレスを指します。 DigitalOceanのドメインとDNSドキュメントを読むことで、ドメインをDigitalOceanドロップレットにポイントする方法を学ぶことができます。 このチュートリアル全体を通して、構成ファイルと例でexample.comをドメインに置き換えてください。
ステップ1—Traefikの構成と実行
Traefikプロジェクトには公式Dockerイメージがあるため、これを使用してDockerコンテナーでTraefikを実行します。
ただし、Traefikコンテナを起動して実行する前に、構成ファイルを作成し、暗号化されたパスワードを設定して、監視ダッシュボードにアクセスできるようにする必要があります。
htpasswdユーティリティを使用して、この暗号化されたパスワードを作成します。 まず、apache2-utilsパッケージに含まれているユーティリティをインストールします。
sudo apt-get install apache2-utils
次に、htpasswdを使用してパスワードを生成します。 secure_passwordを、Traefik管理者ユーザーに使用するパスワードに置き換えます。
htpasswd -nb admin secure_password
プログラムからの出力は次のようになります。
Outputadmin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/
Traefic構成ファイルでこの出力を使用して、Traefikヘルスチェックおよび監視ダッシュボードのHTTP基本認証を設定します。 後で貼り付けることができるように、出力行全体をコピーします。
Traefikサーバーを構成するには、TOML形式を使用してtraefik.tomlという新しい構成ファイルを作成します。 TOML はINIファイルに似た構成言語ですが、標準化されています。 このファイルを使用すると、Traefikサーバーとさまざまな統合、または使用するプロバイダーを構成できます。 このチュートリアルでは、Traefikで利用可能な3つのプロバイダー[web、docker、およびacme)を使用します。これらは、Let'sEncryptを使用してTLSをサポートするために使用されます。
nano traefik.toml
まず、すべてのバックエンドがデフォルトでアクセスできる2つの名前付きエントリポイントhttpとhttpsを追加します。
traefik.toml
defaultEntryPoints = ["http", "https"]
このファイルの後半で、httpおよびhttpsエントリポイントを構成します。
次に、webプロバイダーを構成します。これにより、ダッシュボードインターフェイスにアクセスできるようになります。 ここに、htpasswdコマンドからの出力を貼り付けます。
traefik.toml
... [web] address = ":8080" [web.auth.basic] users = ["admin:your_encrypted_password"]
ダッシュボードは、Traefikコンテナ内で実行される別個のWebアプリケーションです。 ダッシュボードをポート8080で実行するように設定しました。
web.auth.basicセクションは、ダッシュボードのHTTP基本認証を構成します。 実行したhtpasswdコマンドからの出力を、usersエントリの値に使用します。 追加のログインは、コンマで区切って指定できます。
次に、エントリポイントを定義します。 entryPointsセクションは、Traefikとプロキシされたコンテナがリッスンできるアドレスを構成します。 次の行をファイルに追加します。
traefik.toml
...
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
httpエントリポイントはポート80を処理し、httpsエントリポイントはTLS/SSLにポート443を使用します。 ポート80のすべてのトラフィックをhttpsエントリポイントに自動的にリダイレクトして、すべての要求に対して安全な接続を強制します。
最後に、このセクションを追加して、TraefikのLet'sEncrypt証明書のサポートを構成します。
traefik.toml
... [acme] email = "[email protected]" storage = "acme.json" entryPoint = "https" onHostRule = true onDemand = false
ACME は、Let's Encryptと通信して証明書を管理するために使用されるプロトコルの名前であるため、このセクションはacmeと呼ばれます。 Traefikにホストの証明書を生成させるために、emailキーをメールアドレスに設定します。 次に、Let'sEncryptから受け取る情報をacme.jsonというJSONファイルに保存するように指定します。 entryPointキーは、エントリポイント処理ポート443(この場合はhttpsエントリポイント)を指す必要があります。
最後の2つのキー、onHostRuleとonDemandは、Traefikが証明書を生成する方法を指示します。 指定されたホスト名を持つコンテナが作成されたらすぐに証明書をフェッチする必要があります。これがonHostRule設定で行われます。 onDemand設定は、最初に要求が行われたときに証明書の生成を試みます。 これにより、最初のリクエストが遅くなり、訪問者に非常に目立つようになるため、これは避けます。
ファイルを保存して、エディターを終了します。 この構成がすべて整ったら、Traefikを起動できます。
ステップ2–Traefikコンテナを実行する
次に、プロキシがコンテナと共有するDockerネットワークを作成します。 Dockerネットワークは、DockerComposeを使用して実行されるアプリケーションで使用できるようにするために必要です。 このネットワークをproxyと呼びましょう。
docker network create proxy
Traefikコンテナが起動したら、このネットワークに追加します。 次に、後でTraefikがプロキシするために、このネットワークにコンテナを追加できます。
次に、Let'sEncrypt情報を保持する空のファイルを作成します。 これをコンテナに共有して、Traefikが使用できるようにします。
touch acme.json
Traefikは、コンテナ内のrootユーザーがこのファイルへの一意の読み取りおよび書き込みアクセス権を持っている場合にのみ、このファイルを使用できます。 これを行うには、acme.jsonの権限をロックダウンして、ファイルの所有者のみが読み取りおよび書き込み権限を持つようにします。
chmod 600 acme.json
ファイルがDockerに渡されると、所有者はコンテナ内のrootユーザーに自動的に変更されます。
最後に、次のコマンドを使用してTraefikコンテナを作成します。
docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $PWD/traefik.toml:/traefik.toml \ -v $PWD/acme.json:/acme.json \ -p 80:80 \ -p 443:443 \ -l traefik.frontend.rule=Host:monitor.example.com \ -l traefik.port=8080 \ --network proxy \ --name traefik \ traefik:1.3.6-alpine --docker
コマンドは少し長いので、分解してみましょう。
-dフラグを使用して、コンテナーをデーモンとしてバックグラウンドで実行します。 次に、docker.sockファイルをコンテナーに共有して、Traefikプロセスがコンテナーへの変更をリッスンできるようにします。 また、コンテナに作成したtraefik.toml構成ファイルとacme.jsonファイルを共有します。
次に、Dockerホストのポート:80と:443をTraefikコンテナー内の同じポートにマップして、TraefikがサーバーへのすべてのHTTPおよびHTTPSトラフィックを受信するようにします。
次に、トラフィックをホスト名monitor.example.comからポート:8080に転送するようにTraefikに指示する2つのDockerラベルを設定し、監視ダッシュボードを公開します。
コンテナのネットワークをproxyに設定し、コンテナにtraefikという名前を付けます。
最後に、このコンテナは小さいため、traefik:1.3.6-alpineイメージを使用します。
DockerイメージのENTRYPOINTは、イメージからコンテナーが作成されるときに常に実行されるコマンドです。 この場合、コマンドはコンテナ内のtraefikバイナリです。 コンテナを起動するときに、そのコマンドに追加の引数を渡すことができます。 この場合、引数--dockerをENTRYPOINTに渡します。これにより、dockerプロバイダーがデフォルト設定で登録されます。 dockerプロバイダーにより、TraefikはDockerコンテナーの前でプロキシとして機能できます。 Dockerプロバイダーのデフォルト構成は適切に機能するため、traefik.tomlで構成する必要はありません。
コンテナが起動すると、コンテナの状態を確認するためにアクセスできるダッシュボードができました。 このダッシュボードを使用して、Traefikが登録したフロントエンドとバックエンドを視覚化することもできます。 ブラウザでhttps://monitor.example.comを指定して、監視ダッシュボードにアクセスします。 ユーザー名とパスワードの入力を求められます。これらはadminであり、手順1で構成したパスワードです。
ログインすると、。 次のようなインターフェースが表示されます。
まだ見るものはあまりありませんが、このウィンドウを開いたままにしておくと、Traefikが使用するコンテナを追加すると、内容が変化するのがわかります。
これで、Traefikプロキシが実行され、Dockerと連携するように構成され、他のDockerコンテナーを監視する準備が整いました。 Traefikがプロキシとして機能するためのいくつかのコンテナを開始しましょう。
ステップ3—コンテナをTraefikに登録する
Traefikコンテナを実行すると、その背後でアプリケーションを実行する準備が整います。 Traefikの背後にある次のコンテナを起動しましょう。
- 公式Wordpress画像を使用したブログ。
- 公式管理者イメージを使用するデータベース管理サーバー。
docker-compose.ymlファイルを使用して、DockerComposeでこれらのアプリケーションの両方を管理します。
nano docker-compose.yml
次の行をファイルに追加して、使用するバージョンとネットワークを指定します。
docker-compose.yml
version: "3"
networks:
proxy:
external: true
internal:
external: false
DockerComposeバージョン3は、Composeファイル形式の最新のメジャーバージョンであるため、使用しています。
Traefikがアプリケーションを認識するためには、それらが同じネットワークの一部である必要があります。ネットワークは手動で作成したため、proxyのネットワーク名を指定し、externalを[ X208X]。 次に、公開されたコンテナを、Traefikを介して公開しないデータベースコンテナに接続できるように、別のネットワークを定義します。 このネットワークをinternalと呼びます。
次に、'各servicesを一度に1つずつ定義します。 blogコンテナーから始めましょう。これは、公式のWordPressイメージに基づいています。 この構成をファイルに追加します。
docker-compose.yml
version: "3"
...
services:
blog:
image: wordpress:4.7.5-apache
environment:
WORDPRESS_DB_PASSWORD:
labels:
- traefik.backend=blog
- traefik.frontend.rule=Host:blog.example.com
- traefik.docker.network=proxy
- traefik.port=80
networks:
- internal
- proxy
depends_on:
- mysql
environmentキーを使用すると、コンテナー内に設定される環境変数を指定できます。 WORDPRESS_DB_PASSWORDの値を設定しないことで、Docker Composeにシェルから値を取得し、コンテナーを作成するときにそれを渡すように指示しています。 コンテナを起動する前に、シェルでこの環境変数を定義します。 このようにして、パスワードを構成ファイルにハードコーディングしません。
labelsセクションでは、Traefikの構成値を指定します。 Dockerラベルはそれ自体では何もしませんが、Traefikはこれらを読み取るため、コンテナーの処理方法を認識しています。 これらの各ラベルの機能は次のとおりです。
traefik.backendは、Traefikのバックエンドサービスの名前を指定します(実際のblogコンテナーを指します)。traefik.frontend.rule=Host:blog.example.comは、要求されたホストを調べるようにTraefikに指示し、blog.example.comのパターンと一致する場合は、トラフィックをblogコンテナにルーティングする必要があります。traefik.docker.network=proxyは、このコンテナーの内部IPを見つけるためにTraefikを探すネットワークを指定します。 TraefikコンテナはすべてのDocker情報にアクセスできるため、これを指定しなかった場合、internalネットワークのIPを取得する可能性があります。traefik.portは、トラフィックをこのコンテナにルーティングするためにTraefikが使用する必要がある公開ポートを指定します。
この構成では、Dockerホストのポート80に送信されるすべてのトラフィックは、blogコンテナーにルーティングされます。
このコンテナを2つの異なるネットワークに割り当てて、Traefikがproxyネットワーク経由でコンテナを見つけ、internalネットワーク経由でデータベースコンテナと通信できるようにします。
最後に、depends_onキーは、依存関係が実行された後にこのコンテナーを開始する必要があることをDockerComposeに通知します。 WordPressを実行するにはデータベースが必要なため、blogコンテナーを開始する前に、mysqlコンテナーを実行する必要があります。
次に、次の構成をファイルに追加して、MySQLサービスを構成します。
docker-compose.yml
services:
...
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD:
networks:
- internal
labels:
- traefik.enable=false
このコンテナには、公式のMySQL5.7イメージを使用しています。 値のないenvironmentアイテムを再び使用していることに気付くでしょう。 MYSQL_ROOT_PASSWORD変数とWORDPRESS_DB_PASSWORD変数は、WordPressコンテナがMySQLと通信できるようにするために、同じ値に設定する必要があります。 mysqlコンテナをTraefikまたは外部に公開したくないので、このコンテナをinternalネットワークに割り当てるだけです。 TraefikはDockerソケットにアクセスできるため、プロセスはデフォルトでmysqlコンテナーのフロントエンドを公開します。そのため、ラベルtraefik.enable=falseを追加して、Traefikがこのコンテナーを公開しないように指定します。
最後に、次の構成を追加して、Adminerコンテナーを定義します。
docker-compose.yml
services:
...
adminer:
image: adminer:4.3.1-standalone
labels:
- traefik.backend=adminer
- traefik.frontend.rule=Host:db-admin.example.com
- traefik.docker.network=proxy
- traefik.port=8080
networks:
- internal
- proxy
depends_on:
- mysql
このコンテナは、公式のAdminerイメージに基づいています。 このコンテナーのnetworkおよびdepends_on構成は、blogコンテナーに使用しているものと完全に一致します。
ただし、すべてのトラフィックをDockerホストのポート80に直接blogコンテナーに転送しているため、トラフィックがadminerコンテナ。 行traefik.frontend.rule=Host:db-admin.example.comは、要求されたホストを調べるようにTraefikに指示します。 db-admin.example.comのパターンと一致する場合、Traefikはトラフィックをadminerコンテナにルーティングします。
ファイルを保存して、テキストエディタを終了します。
次に、コンテナを起動する前に、シェルでWORDPRESS_DB_PASSWORD変数とMYSQL_ROOT_PASSWORD変数の値を設定します。
export WORDPRESS_DB_PASSWORD=secure_database_password export MYSQL_ROOT_PASSWORD=secure_database_password
secure_database_passwordを目的のデータベースパスワードに置き換えます。
これらの変数を設定した状態で、docker-composeを使用してコンテナーを実行します。
docker-compose up -d
次に、Traefik管理ダッシュボードをもう一度見てください。 2つの公開されたサーバーにbackendとfrontendがあることがわかります。
blog.example.comに移動し、example.comをドメインに置き換えます。 TLS接続にリダイレクトされ、Wordpressのセットアップを完了することができます。
次に、ブラウザでdb-admin.example.comにアクセスし、ドメインをexample.comに置き換えて、Adminerにアクセスします。 mysqlコンテナは外界に公開されていませんが、adminerコンテナは、mysqlを使用して共有するinternalDockerネットワークを介してアクセスできます。 ]ホスト名としてのコンテナ名。
管理者ログイン画面で、ユーザー名 root を使用し、サーバーにmysqlを使用し、パスワードにMYSQL_ROOT_PASSWORDに設定した値を使用します。 ログインすると、Adminerユーザーインターフェイスが表示されます。
現在、両方のサイトが機能しており、monitor.example.comのダッシュボードを使用してアプリケーションを監視できます。
結論
このチュートリアルでは、Dockerコンテナー内の他のアプリケーションにリクエストをプロキシするようにTraefikを構成しました。
アプリケーションコンテナレベルでのTraefikの宣言型構成により、より多くのサービスを簡単に構成できます。TraefikはDockerソケットファイルを介して変更にすぐに気付くため、プロキシトラフィックに新しいアプリケーションを追加するときにtraefikコンテナを再起動する必要はありません。監視しています。
Traefikで何ができるかについて詳しくは、Traefikの公式ドキュメントをご覧ください。