Debian 9でDockerコンテナのリバースプロキシとしてTraefikを使用する方法

作成者はhttps://www.brightfunds.org/organizations/girls-who-code[Girls Who Code]を選択して、https://do.co/w4do-cta [Donationsのための書き込み]プログラムの一環として寄付を受け取りました.

前書き

https://www.docker.com [Docker]は、実稼働環境でWebアプリケーションを実行する効率的な方法ですが、同じDockerホストで複数のアプリケーションを実行することもできます。 この状況では、ポート `+ 80 `および ` 443 +`のみを世界に公開するため、リバースプロキシを設定する必要があります。

https://traefik.io [Traefik]は、独自の監視ダッシュボードを含むDocker対応のリバースプロキシです。 このチュートリアルでは、Traefikを使用して、2つの異なるWebアプリケーションコンテナーにリクエストをルーティングします。http://wordpress.org [Wordpress]コンテナーとhttps://www.adminer.org/[Adminer]コンテナーで、それぞれが通信しますhttps://www.mysql.com/[MySQL]データベースへ。 Let’s Encryptを使用して、HTTPS経由ですべてを提供するようにTraefikを設定します。

前提条件

このチュートリアルを進めるには、次のものが必要です。

  • Debian 9での初期サーバー設定に従ってセットアップされた1台のDebian 9サーバー(sudo非rootユーザーとファイアウォール。

  • サーバーにインストールされているDocker。https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-debian-9 [Dockerをインストールして使用する方法Debian 9]。

  • Debian 9にDocker Composeをインストールする方法の指示に従ってインストールされたDocker Compose。

  • ドメインと3つのAレコード、「+ db-admin」、「+ blogs」、および「+ monitor of」は、それぞれサーバーのIPアドレスを指します。 DigitalOceanのhttps://www.digitalocean.com/docs/networking/dns/[Domains and DNS documentation]を読むと、ドメインをDigitalOcean Dropletsにポイントする方法を学習できます。 このチュートリアル全体を通して、構成ファイルと例でドメインを「++」に置き換えます。

手順1-Traefikの構成と実行

Traefikプロジェクトにはhttps://hub.docker.com/_/traefik [公式Dockerイメージ]があるため、これを使用してDockerコンテナでTraefikを実行します。

ただし、Traefikコンテナを起動して実行する前に、監視ダッシュボードにアクセスできるように、構成ファイルを作成し、暗号化されたパスワードを設定する必要があります。

この暗号化されたパスワードを作成するには、 `+ htpasswd `ユーティリティを使用します。 最初に、 ` apache2-utils +`パッケージに含まれているユーティリティをインストールします。

sudo apt install apache2-utils

次に、「+ htpasswd 」でパスワードを生成します。 Traefik管理ユーザーに使用するパスワードで「+」を置き換えます。

htpasswd -nb admin

プログラムからの出力は次のようになります。

Outputadmin:

Traefik構成ファイルでこの出力を使用して、Traefikヘルスチェックおよび監視ダッシュボードのHTTP基本認証を設定します。 後で貼り付けることができるように、出力行全体をコピーします。

Traefikサーバーを設定するには、TOML形式を使用して、「+ traefik.toml 」という新しい設定ファイルを作成します。 https://github.com/toml-lang/toml[TOML]は、INIファイルに似ていますが、標準化された構成言語です。 このファイルにより、使用したいTraefikサーバーとさまざまな統合、または_providers_を構成できます。 このチュートリアルでは、Traefikで利用可能な3つのプロバイダーを使用します。` api _`、 + docker _、および` + acme _`は、Let’s Encryptを使用してTLSをサポートするために使用されます。

新しいファイルを `+ nano +`またはお気に入りのテキストエディターで開きます。

nano traefik.toml

最初に、すべてのバックエンドがデフォルトでアクセスできる2つの名前付きエントリポイント、「+ http 」と「 https +」を追加します。

traefik.toml

defaultEntryPoints = ["http", "https"]

このファイルの後半で、 `+ http `および ` https +`エントリポイントを設定します。

次に、ダッシュボードインターフェイスへのアクセスを提供する `+ api`プロバイダーを設定します。 これは、 `+ htpasswd +`コマンドからの出力を貼り付ける場所です。

traefik.toml

...
[entryPoints]
 [entryPoints.dashboard]
   address = ":8080"
   [entryPoints.dashboard.auth]
     [entryPoints.dashboard.auth.basic]
       users = [""]

[api]
entrypoint="dashboard"

ダッシュボードは、Traefikコンテナ内で実行される別個のWebアプリケーションです。 ポート「8080」で実行するようにダッシュボードを設定します。

`+ entrypoints.dashboard `セクションは ` api `プロバイダーとの接続方法を設定し、 ` entrypoints.dashboard.auth.basic `セクションはダッシュボードのHTTP基本認証を設定します。 ` users `エントリの値に対して実行したばかりの ` htpasswd +`コマンドの出力を使用します。 カンマで区切って追加のログインを指定できます。

最初の `+ entryPoint `を定義しましたが、 ` api `プロバイダーに向けられていない標準のHTTPおよびHTTPS通信用に他のものを定義する必要があります。 ` entryPoints `セクションは、Traefikとプロキシされたコンテナがリッスンできるアドレスを設定します。 これらの行をファイルの「 entryPoints +」見出しの下に追加します。

traefik.toml

...
 [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の証明書の暗号化サポートを設定します。

traefik.toml

...
[acme]
email = ""
storage = "acme.json"
entryPoint = "https"
onHostRule = true
 [acme.httpChallenge]
 entryPoint = "http"

ACMEはLet’s Encryptと通信して証明書を管理するために使用されるプロトコルの名前であるため、このセクションは「+ acme 」と呼ばれます。 Let's Encryptサービスでは、有効なメールアドレスでの登録が必要です。そのため、Trafikがホストの証明書を生成するには、 ` email `キーをメールアドレスに設定してください。 次に、Let’s Encryptから受信する情報を ` acme.json `というJSONファイルに保存することを指定します。 ` entryPoint `キーは、ポート ` 443 `を処理するエントリポイントをポイントする必要があります。この場合、このエントリポイントは ` https +`エントリポイントです。

キー `+ onHostRule `は、Traefikが証明書を生成する方法を指示します。 指定されたホスト名を持つコンテナが作成されたらすぐに証明書を取得したいのですが、それが ` onHostRule +`設定の動作です。

`+ acme.httpChallenge `セクションでは、Let's Encryptが証明書の生成を確認できる方法を指定できます。 ` http +`エントリポイントを介したチャレンジの一部としてファイルを提供するように設定しています。

最後に、これらの行をファイルに追加して、 `+ docker +`プロバイダーを設定しましょう:

traefik.toml

...
[docker]
domain = ""
watch = true
network = "web"

`+ docker `プロバイダーにより、TraefikはDockerコンテナの前でプロキシとして機能できます。 「 web」ネットワーク上の新しいコンテナ(間もなく作成します)の「+ watch」にプロバイダーを設定し、「++」のサブドメインとして公開します。

この時点で、 `+ traefik.toml +`には次の内容が含まれているはずです。

traefik.toml

defaultEntryPoints = ["http", "https"]

[entryPoints]
 [entryPoints.dashboard]
   address = ":8080"
   [entryPoints.dashboard.auth]
     [entryPoints.dashboard.auth.basic]
       users = [""]
 [entryPoints.http]
   address = ":80"
     [entryPoints.http.redirect]
       entryPoint = "https"
 [entryPoints.https]
   address = ":443"
     [entryPoints.https.tls]

[api]
entrypoint="dashboard"

[acme]
email = ""
storage = "acme.json"
entryPoint = "https"
onHostRule = true
 [acme.httpChallenge]
 entryPoint = "http"

[docker]
domain = ""
watch = true
network = "web"

ファイルを保存し、エディターを終了します。 このすべての構成が整ったら、Traefikを起動できます。

ステップ2 – Traefikコンテナの実行

次に、プロキシがコンテナと共有するためのDockerネットワークを作成します。 Dockerネットワークは、Docker Composeを使用して実行されるアプリケーションで使用できるようにするために必要です。 このネットワークを「+ web」と呼びましょう。

docker network create

Traefikコンテナが起動したら、このネットワークに追加します。 その後、Traefikがプロキシするために、このネットワークに後でコンテナを追加できます。

次に、Let’s Encrypt情報を保持する空のファイルを作成します。 これをコンテナに共有して、Traefikが使用できるようにします。

touch

Traefikは、コンテナ内のルートユーザーに一意の読み取りおよび書き込みアクセス権がある場合にのみ、このファイルを使用できます。 これを行うには、ファイルの所有者のみが読み取りおよび書き込み権限を持つように、 `+ acme.json +`の権限をロックダウンします。

chmod 600

ファイルが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. \
 -l traefik.port=8080 \
 --network web \
 --name traefik \
 traefik:1.7.6-alpine

コマンドは少し長いので、分解しましょう。

`+ -d `フラグを使用して、デーモンとしてコンテナをバックグラウンドで実行します。 次に、 ` docker.sock `ファイルをコンテナに共有し、Traefikプロセスがコンテナの変更をリッスンできるようにします。 また、コンテナに作成した ` traefik.toml `設定ファイルと ` acme.json +`ファイルも共有します。

次に、Dockerホストのポート「80」と「443」をTraefikコンテナの同じポートにマッピングし、TraefikがサーバーへのすべてのHTTPおよびHTTPSトラフィックを受信するようにします。

次に、トラフィックをホスト名「+ monitor。」に転送してTraefikコンテナ内のポート「+8080」に転送するようにTraefikに指示する2つのDockerラベルを設定し、監視ダッシュボードを公開します。

コンテナのネットワークを「+ web 」に設定し、コンテナに「 traefik +」という名前を付けます。

最後に、このコンテナには小さいため、「+ traefik:1.7.6-alpine +」画像を使用します。

Dockerイメージの `+ ENTRYPOINT`は、コンテナーがイメージから作成されたときに常に実行されるコマンドです。 この場合、コマンドはコンテナ内の `+ traefik `バイナリです。 コンテナを起動するときに、そのコマンドに追加の引数を渡すことができますが、すべての設定を ` traefik.toml +`ファイルで構成しました。

コンテナが起動すると、ダッシュボードにアクセスして、コンテナの状態を確認できます。 このダッシュボードを使用して、Traefikが登録したフロントエンドとバックエンドを視覚化することもできます。 ブラウザで「+ https://monitor.+」を指定して、監視ダッシュボードにアクセスします。 ユーザー名とパスワードの入力を求められます。これらは、* admin *とステップ1で設定したパスワードです。

ログインすると、次のようなインターフェースが表示されます。

画像:https://assets.digitalocean.com/articles/64873_Traefik/Empty_Traefik_Dashboard.png [空のTraefikダッシュボード]

まだあまり見ることはありませんが、このウィンドウを開いたままにしておくと、Traefikが操作するコンテナを追加すると内容が変更されます。

これで、Trafikプロキシが実行され、Dockerと連携するように構成され、他のDockerコンテナーを監視する準備が整いました。 Traefikのプロキシとして機能するコンテナをいくつか始めましょう。

ステップ3-コンテナをTraefikに登録する

Traefikコンテナを実行すると、その背後でアプリケーションを実行する準備が整います。 Traefikの背後にある次のコンテナを起動しましょう。

  1. https://hub.docker.com/_/wordpress/ [公式Wordpress画像]を使用したブログ。

  2. https://hub.docker.com/_/adminer/ [公式管理者イメージ]を使用するデータベース管理サーバー。

`+ docker-compose.yml `ファイルを使用して、これら両方のアプリケーションをDocker Composeで管理します。 エディターで ` docker-compose.yml +`ファイルを開きます:

nano docker-compose.yml

ファイルに次の行を追加して、使用するバージョンとネットワークを指定します。

docker-compose.yml

version: "3"

networks:
 web:
   external: true
 internal:
   external: false

Composeファイル形式の最新のメジャーバージョンであるため、Docker Composeバージョン `+ 3 +`を使用します。

Traefikがアプリケーションを認識するには、それらが同じネットワークの一部である必要があります。ネットワークを手動で作成したので、ネットワーク名を「+ web 」に指定し、「 external 」を「 true 」に設定してプルします。 次に、公開されたコンテナをTraefikを介して公開しないデータベースコンテナに接続できるように、別のネットワークを定義します。 このネットワークを「 internal +」と呼びます。

次に、各「+ services 」を1つずつ定義します。 「 blog +」コンテナから始めましょう。これは、公式のWordPressイメージに基づいています。 この構成をファイルに追加します。

docker-compose.yml

version: "3"
...

services:
 blog:
   image: wordpress:4.9.8-apache
   environment:
     WORDPRESS_DB_PASSWORD:
   labels:
     - traefik.backend=blog
     - traefik.frontend.rule=Host:blog.
     - traefik.docker.network=web
     - traefik.port=80
   networks:
     - internal
     - web
   depends_on:
     - mysql

`+ environment `キーを使用すると、コンテナ内に設定される環境変数を指定できます。 ` WORDPRESS_DB_PASSWORD +`の値を設定しないことにより、Docker Composeにシェルから値を取得し、コンテナーの作成時にパススルーするように指示しています。 コンテナを起動する前に、シェルでこの環境変数を定義します。 この方法では、パスワードを構成ファイルにハードコーディングしません。

`+ labels +`セクションでは、Traefikの設定値を指定します。 Dockerラベルはそれ自体では何もしませんが、Traefikはこれらを読み取って、コンテナの処理方法を認識します。 これらの各ラベルの機能は次のとおりです。

  • `+ traefik.backend `はTraefikのバックエンドサービスの名前を指定します(実際の ` blog +`コンテナを指します)。

  • `+ traefik.frontend.rule = Host:blog。`は、要求されたホストを検査するようTraefikに指示し、 ` blog。`のパターンに一致する場合、トラフィックを ` blog +`コンテナにルーティングする必要があります。

  • `+ traefik.docker.network = web `は、このコンテナの内部IPを見つけるためにTraefikを探すネットワークを指定します。 TraefikコンテナはすべてのDocker情報にアクセスできるため、これを指定しないと、「 internal +」ネットワークのIPを取得する可能性があります。

  • `+ traefik.port +`は、トラフィックをこのコンテナにルーティングするためにTraefikが使用する公開ポートを指定します。

この設定では、Dockerホストのポート「80」に送信されるすべてのトラフィックは「+ blog +」コンテナにルーティングされます。

このコンテナを2つの異なるネットワークに割り当て、Traefikが `+ web `ネットワークを介してそれを見つけ、 ` internal +`ネットワークを介してデータベースコンテナと通信できるようにします。

最後に、 `+ depends_on `キーはDocker Composeに、このコンテナが依存関係の実行後に起動する必要があることを伝えます。 WordPressを実行するにはデータベースが必要なので、 ` blog `コンテナを起動する前に ` mysql +`コンテナを実行する必要があります。

次に、この構成をファイルに追加して、MySQLサービスを構成します。

docker-compose.yml

services:
...
 mysql:
   image: mysql:5.7
   environment:
     MYSQL_ROOT_PASSWORD:
   networks:
     - internal
   labels:
     - traefik.enable=false

このコンテナには、公式のMySQL 5.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.6.3-standalone
   labels:
     - traefik.backend=adminer
     - traefik.frontend.rule=Host:db-admin.
     - traefik.docker.network=web
     - traefik.port=8080
   networks:
     - internal
     - web
   depends_on:
     - mysql

このコンテナは、公式の管理者イメージに基づいています。 このコンテナの「+ network 」および「 depends_on 」設定は、「 blog +」コンテナに使用しているものと完全に一致します。

ただし、Dockerホストのポート「80」にすべてのトラフィックを直接「+ blog 」コンテナに向けるので、トラフィックが「 adminer + `コンテナ。 行 `+ traefik.frontend.rule = Host:db-admin。`は、要求されたホストを調べるようにTraefikに指示します。 ` db-admin。`のパターンに一致する場合、Traefikはトラフィックを ` adminer +`コンテナにルーティングします。

この時点で、 `+ docker-compose.yml +`には次の内容が含まれているはずです。

docker-compose.yml

version: "3"

networks:
 web:
   external: true
 internal:
   external: false

services:
 blog:
   image: wordpress:4.9.8-apache
   environment:
     WORDPRESS_DB_PASSWORD:
   labels:
     - traefik.backend=blog
     - traefik.frontend.rule=Host:blog.
     - traefik.docker.network=web
     - traefik.port=80
   networks:
     - internal
     - web
   depends_on:
     - mysql
 mysql:
   image: mysql:5.7
   environment:
     MYSQL_ROOT_PASSWORD:
   networks:
     - internal
   labels:
     - traefik.enable=false
 adminer:
   image: adminer:4.6.3-standalone
   labels:
     - traefik.backend=adminer
     - traefik.frontend.rule=Host:db-admin.
     - traefik.docker.network=web
     - traefik.port=8080
   networks:
     - internal
     - web
   depends_on:
     - mysql

ファイルを保存し、テキストエディターを終了します。

次に、コンテナを起動する前に、 `+ WORDPRESS_DB_PASSWORD `および ` MYSQL_ROOT_PASSWORD +`変数の値をシェルに設定します。

export WORDPRESS_DB_PASSWORD=
export MYSQL_ROOT_PASSWORD=

希望するデータベースパスワードで「+」を置き換えます。 ` WORDPRESS_DB_PASSWORD `と ` MYSQL_ROOT_PASSWORD +`の両方に同じパスワードを使用することを忘れないでください。

これらの変数を設定して、 `+ docker-compose +`を使用してコンテナーを実行します。

docker-compose up -d

Traefik管理ダッシュボードをもう一度見てみましょう。 これで、公開された2つのサーバーに「+ backend 」と「 frontend +」があることがわかります。

画像:https://assets.digitalocean.com/articles/64873_Traefik/Populated_Traefik_Dashboard.png [Populated Traefik dashboard]

`+ blog。`に移動し、 ` your_domain +`をドメインに置き換えます。 TLS接続にリダイレクトされ、Wordpressのセットアップを完了することができます。

image:https://assets.digitalocean.com/articles/64873_Traefik/WordPress_setup_screen.png [WordPressセットアップ画面]

ブラウザで + db-admin。+`にアクセスしてAdminerにアクセスし、再び `+ your_domain +`をドメインに置き換えます。 `+ mysql +`コンテナは外部に公開されませんが、 `+ adminer +`コンテナは、ホスト名として `+ mysql +`コンテナ名を使用して共有する `+ internal + Dockerネットワークを介してアクセスできます。

管理者ログイン画面で、ユーザー名* root を使用し、 server *にユーザー + mysql`を使用し、パスワードに + MYSQL_ROOT_PASSWORD`に設定した値を使用します。 ログインすると、管理者のユーザーインターフェースが表示されます。

image:https://assets.digitalocean.com/articles/64873_Traefik/Adminer_MySQL_database.png [MySQLデータベースに接続された管理者]

両方のサイトが機能するようになり、 `+ monitor。+`のダッシュボードを使用してアプリケーションを監視できます。

結論

このチュートリアルでは、Dockerコンテナ内の他のアプリケーションへのリクエストをプロキシするようにTraefikを設定しました。

アプリケーションコンテナレベルでのTraefikの宣言的な設定により、より多くのサービスを簡単に設定できます。また、Trafikが監視しているDockerソケットファイルを通じて変更をすぐに通知するため、プロキシトラフィックに新しいアプリケーションを追加するときに `+ traefik +`コンテナを再起動する必要はありません。

Traefikでできることの詳細については、公式のhttps://docs.traefik.io/basics/[Traefikドキュメント]をご覧ください。 Dockerコンテナをさらに詳しく知りたい場合は、https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-18-04をご覧ください。 [Ubuntu 18.04でプライベートDockerレジストリを設定する方法]またはhttps://www.digitalocean.com/community/tutorials/how-to-secure-a-containerized-node-js-application-with-nginx-let- s-encrypt-and-docker-compose [コンテナ化されたNode.jsアプリケーションをNginx、Let Encrypt、Docker Composeで保護する方法]。

Related