Ubuntu20.04でDockerコンテナのリバースプロキシとしてTraefikv2を使用する方法
著者は、 Write for DOnations プログラムの一環として、 Girls WhoCodeを選択して寄付を受け取りました。
序章
Docker は、本番環境でWebアプリケーションを実行するための効率的な方法ですが、同じDockerホストで複数のアプリケーションを実行したい場合があります。 この状況では、リバースプロキシを設定する必要があります。 これは、ポート80
と443
のみを他の世界に公開したいためです。
Traefik は、監視ダッシュボードを含むDocker対応のリバースプロキシです。 Traefik v1はしばらくの間広く使用されており、この以前のチュートリアルに従ってTraefik v1 をインストールできます)。 ただし、このチュートリアルでは、Traefik v2をインストールして構成します。これには、かなりの違いが含まれています。
Traefik v1とv2の最大の違いは、フロントエンドとバックエンドが削除され、それらを組み合わせた機能がルーター、ミドルウェア、およびサービス。 以前は、バックエンドがリクエストに変更を加え、そのリクエストを処理することになっているものにそのリクエストを取得するという仕事をしていました。 Traefik v2は、サービスに送信する前に要求を変更できるミドルウェアを導入することにより、関心の分離を強化します。 ミドルウェアを使用すると、さまざまなルートで使用される可能性のある単一の変更ステップを簡単に指定して、それらを再利用できるようになります(HTTP基本認証など。これについては後で説明します)。 ルーターは、さまざまなミドルウェアを使用することもできます。
このチュートリアルでは、リクエストを2つの異なるWebアプリケーションコンテナ(WordPressコンテナとAdminerコンテナ)にルーティングするようにTraefik v2を構成し、それぞれがMySQLと通信します。データベース。 Let’s Encrypt を使用して、HTTPS経由ですべてを提供するようにTraefikを構成します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- sudo非rootユーザーとファイアウォールを備えた1台のUbuntu20.04サーバー。 これは、Ubuntu20.04初期サーバーセットアップガイドに従ってセットアップできます。
- サーバーにDockerがインストールされています。これは、 Ubuntu20.04にDockerをインストールして使用する方法のステップ1および2に従って実行できます。
- DockerComposeはUbuntu20.04にDockerComposeをインストールする方法のステップ1の手順を使用してインストールされます。
- ドメインと3つのAレコード、
db-admin.your_domain
、blog.your_domain
、およびmonitor.your_domain
。 それぞれがサーバーのIPアドレスを指している必要があります。 DigitalOceanのドメインとDNSドキュメントを読むことで、ドメインをDigitalOceanドロップレットにポイントする方法を学ぶことができます。 このチュートリアル全体を通して、構成ファイルと例でyour_domain
をドメインに置き換えてください。
ステップ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/
この出力をTraefik構成ファイルで使用して、Traefikヘルスチェックおよび監視ダッシュボードのHTTP基本認証を設定します。 後で貼り付けることができるように、出力行全体をコピーします。
Traefikサーバーを構成するには、TOML形式を使用してtraefik.toml
およびtraefik_dynamic.toml
という2つの新しい構成ファイルを作成します。 TOML は、INIファイルに似た構成言語ですが、標準化されています。 これらのファイルを使用すると、Traefikサーバーと、使用するさまざまな統合またはproviders
を構成できます。 このチュートリアルでは、Traefikで利用可能な3つのプロバイダー、api
、docker
、およびacme
を使用します。 これらの最後のacme
は、Let’sEncryptを使用したTLS証明書をサポートしています。
nano
またはお好みのテキストエディタを使用して、traefik.toml
を作成して開きます。
- nano traefik.toml
まず、構成ファイルのentryPoints
セクションを使用して、Traefikがリッスンするポートを指定します。 ポート80
と443
でリッスンするため、2つ必要です。 これらをweb
(ポート80
)およびwebsecure
(ポート443
)と呼びましょう。
次の構成を追加します。
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web.http.redirections.entryPoint]
to = "websecure"
scheme = "https"
[entryPoints.websecure]
address = ":443"
また、TLSを介して処理されるトラフィックを自動的にリダイレクトしていることに注意してください。
次に、Traefik api
を構成します。これにより、APIとダッシュボードインターフェイスの両方にアクセスできるようになります。 ダッシュボードはデフォルトで有効になっているため、[api]
の見出しだけで十分ですが、当面は明示的になります。
次のコードを追加します。
...
[api]
dashboard = true
Webリクエストの保護を完了するには、Let’sEncryptを使用して有効なTLS証明書を生成します。 Traefik v2は、Let’s Encryptをすぐにサポートしており、タイプacme
の証明書リゾルバーを作成することで構成できます。
lets-encrypt
という名前を使用して、証明書リゾルバーを構成しましょう。
...
[certificatesResolvers.lets-encrypt.acme]
email = "your_email@your_domain"
storage = "acme.json"
[certificatesResolvers.lets-encrypt.acme.tlsChallenge]
ACME は、Let’s Encryptと通信して証明書を管理するために使用されるプロトコルの名前であるため、このセクションはacme
と呼ばれます。 Let’s Encryptサービスでは、有効な電子メールアドレスで登録する必要があるため、Traefikにホストの証明書を生成させるには、email
キーを電子メールアドレスに設定します。 次に、Let’sEncryptから受け取る情報をacme.json
というJSONファイルに保存するように指定します。
acme.tlsChallenge
セクションでは、Let’sEncryptが証明書を検証する方法を指定できます。 ポート443
を介したチャレンジの一部としてファイルを提供するように構成しています。
最後に、Dockerと連携するようにTraefikを構成する必要があります。
次の構成を追加します。
...
[providers.docker]
watch = true
network = "web"
docker
プロバイダーにより、TraefikはDockerコンテナーの前でプロキシとして機能できます。 web
ネットワーク上の新しいコンテナー用にプロバイダーをwatch
に構成しました。これは、まもなく作成されます。
最終的な構成では、file
プロバイダーを使用します。 Traefik v2では、静的構成と動的構成を混在させて一致させることはできません。 これを回避するには、traefik.toml
を使用して静的構成を定義し、動的構成をtraefik_dynamic.toml
と呼ばれる別のファイルに保持します。 ここでは、file
プロバイダーを使用して、別のファイルから動的構成で読み取る必要があることをTraefikに通知しています。
次のfile
プロバイダーを追加します。
- [providers.file]
- filename = "traefik_dynamic.toml"
完成したtraefik.toml
は次のようになります。
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web.http.redirections.entryPoint]
to = "websecure"
scheme = "https"
[entryPoints.websecure]
address = ":443"
[api]
dashboard = true
[certificatesResolvers.lets-encrypt.acme]
email = "your_email@your_domain"
storage = "acme.json"
[certificatesResolvers.lets-encrypt.acme.tlsChallenge]
[providers.docker]
watch = true
network = "web"
[providers.file]
filename = "traefik_dynamic.toml"
ファイルを保存して閉じます。
それでは、traefik_dynamic.toml
を作成しましょう。
独自のファイルに保持する必要のある動的構成値は、ミドルウェアとルーターです。 ダッシュボードをパスワードの背後に配置するには、APIのルーターをカスタマイズし、HTTP基本認証を処理するようにミドルウェアを構成する必要があります。 ミドルウェアを設定することから始めましょう。
ミドルウェアはプロトコルごとに構成され、HTTPを使用しているため、http.middlewares
からチェーンされたセクションとしてミドルウェアを指定します。 次に、後で参照できるようにミドルウェアの名前を示し、次にミドルウェアのタイプ(この場合はbasicAuth
)を示します。 ミドルウェアをsimpleAuth
と呼びましょう。
traefik_dynamic.toml
という名前の新しいファイルを作成して開きます。
- nano traefik_dynamic.toml
次のコードを追加します。 ここに、htpasswd
コマンドからの出力を貼り付けます。
[http.middlewares.simpleAuth.basicAuth]
users = [
"admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/"
]
APIのルーターを構成するには、プロトコル名を再度チェーンオフしますが、http.middlewares
を使用する代わりに、http.routers
の後にルーターの名前を使用します。 この場合、api
は、[http.routers.api]
セクションを使用して構成できる独自の名前付きルーターを提供します。 ホストマッチを使用してrule
キーを設定し、websecure
を使用するエントリポイント、および
次の構成を追加します。
...
[http.routers.api]
rule = "Host(`monitor.your_domain`)"
entrypoints = ["websecure"]
middlewares = ["simpleAuth"]
service = "api@internal"
[http.routers.api.tls]
certResolver = "lets-encrypt"
web
エントリポイントはポート80
を処理し、websecure
エントリポイントはTLS/SSLにポート443
を使用します。 ポート80
のすべてのトラフィックをwebsecure
エントリポイントに自動的にリダイレクトして、すべての要求に対して安全な接続を強制します。
ここの最後の3行は、 service を構成し、tlsを有効にして、certResolver
を"lets-encrypt"
に構成していることに注意してください。 サービスは、リクエストが最終的に処理される場所を決定するための最終ステップです。 api@internal
サービスは、公開するAPIの背後にある組み込みサービスです。 ルーターやミドルウェアと同様に、このファイルでサービスを構成できますが、目的の結果を得るために構成する必要はありません。
完成したtraefik_dynamic.toml
ファイルは次のようになります。
[http.middlewares.simpleAuth.basicAuth]
users = [
"admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/"
]
[http.routers.api]
rule = "Host(`monitor.your_domain`)"
entrypoints = ["websecure"]
middlewares = ["simpleAuth"]
service = "api@internal"
[http.routers.api.tls]
certResolver = "lets-encrypt"
ファイルを保存して、エディターを終了します。
これらの構成が整ったら、Traefikを起動します。
ステップ2–Traefikコンテナを実行する
このステップでは、プロキシがコンテナと共有するためのDockerネットワークを作成します。 次に、Traefikダッシュボードにアクセスします。 Dockerネットワークは、DockerComposeを使用して実行されるアプリケーションで使用できるようにするために必要です。
web
という名前の新しいDockerネットワークを作成します。
- docker network create web
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/traefik_dynamic.toml:/traefik_dynamic.toml \
- -v $PWD/acme.json:/acme.json \
- -p 80:80 \
- -p 443:443 \
- --network web \
- --name traefik \
- traefik:v2.2
このコマンドは少し長いです。 分解してみましょう。
-d
フラグを使用して、コンテナーをデーモンとしてバックグラウンドで実行します。 次に、docker.sock
ファイルをコンテナーに共有して、Traefikプロセスがコンテナーへの変更をリッスンできるようにします。 また、traefik.toml
とtraefik_dynamic.toml
の構成ファイル、およびacme.json
をコンテナーで共有します。
次に、Dockerホストのポート:80
と:443
をTraefikコンテナー内の同じポートにマップして、TraefikがサーバーへのすべてのHTTPおよびHTTPSトラフィックを受信するようにします。
コンテナのネットワークをweb
に設定し、コンテナにtraefik
という名前を付けます。
最後に、このコンテナにtraefik:v2.2
イメージを使用して、このチュートリアルが記述されているものとは完全に異なるバージョンを実行していないことを保証できます。
DockerイメージのENTRYPOINTは、イメージからコンテナーが作成されるときに常に実行されるコマンドです。 この場合、コマンドはコンテナ内のtraefik
バイナリです。 コンテナを起動するときにそのコマンドに追加の引数を渡すことができますが、traefik.toml
ファイルですべての設定を構成しました。
コンテナを起動すると、コンテナの状態を確認するためにアクセスできるダッシュボードができました。 このダッシュボードを使用して、Traefikが登録したルーター、サービス、およびミドルウェアを視覚化することもできます。 ブラウザでhttps://monitor.your_domain/dashboard/
を指定すると、監視ダッシュボードにアクセスできます(末尾の/
が必要です)。
ユーザー名とパスワードの入力を求められます。これらはadminであり、手順1で構成したパスワードです。
ログインすると、Traefikインターフェースが表示されます。
すでにいくつかのルーターとサービスが登録されていることに気付くでしょうが、それらはTraefikとAPI用に作成したルーター構成に付属しているものです。
これでTraefikプロキシが実行され、Dockerと連携して他のコンテナーを監視するように構成されました。 次のステップでは、Traefikがプロキシするためのいくつかのコンテナーを開始します。
ステップ3—コンテナをTraefikに登録する
Traefikコンテナを実行すると、その背後でアプリケーションを実行する準備が整います。 Traefikの背後にある次のコンテナを起動しましょう。
- 公式WordPress画像を使用したブログ。
- 公式管理者イメージを使用するデータベース管理サーバー。
docker-compose.yml
ファイルを使用して、DockerComposeでこれらのアプリケーションの両方を管理します。
docker-compose.yml
ファイルを作成してエディターで開きます。
- nano docker-compose.yml
次の行をファイルに追加して、使用するバージョンとネットワークを指定します。
version: "3"
networks:
web:
external: true
internal:
external: false
DockerComposeバージョン3
は、Composeファイル形式の最新のメジャーバージョンであるため、使用します。
Traefikがアプリケーションを認識するためには、それらが同じネットワークの一部である必要があります。ネットワークを手動で作成したため、web
のネットワーク名を指定し、external
を[ X211X]