ARMボード色々でおうちDockerSwarmクラスタ traefik編


クラスタを作っている所(進行形)なのでそのメモを残していきます。
この記事ではおうちARMボードに、traefikを入れます。

注意: Traefik v2と Traefik v1の設定方法には互換性がありません。
この記事では Traefik v2.5を使った構成を示します。

おうちクラスタシリーズ

  • 第1弾: ハードウェア編
  • 第2弾: Portainer編
  • 第3弾: Ceph編(失敗)
  • 第4弾: SeaweedFS編
  • 第5弾: traefik編

Traefikについて

Go製のコンテナと相性がいい感じのリバースプロキシです。コンテナにラベルをつけると動的にルーティングしてくれたり、LetsEncryptの証明書の自動発行ができたり、いい感じのAPIがあるイケてるやつです。コンテナ間のネットワークをちゃんと設定すれば、物理ポートに割り当てせずに(どのポートを使用済みか考えずに!)サービスをデプロイできるようになります。

なんでnginxとかapacheを使わないの?

どちらもラズパイ1台でセットアップしたときには使用していました。そのままセットアップしても恐らくはうまく行くと思うのですが、せっかくDockerSwarmを導入したので、それに合うモダンなツールを試してみようと思います。

導入

ここまでで、PortainerとSeaweedFSをセットアップしたので、WebUIからサービスを追加できる、/mnt/seaweedfsに設定ファイルを保存できるという想定で進めます。

1 traefikで使うネットワークの作成

予めSwarm内で使うoverlayネットワークを作ります

2 必要ファイルを/mnt/seaweedfsに用意

traefikフォルダとファイルを用意
sudo mkdir /mnt/seaweedfs/traefik
sudo mkdir /mnt/seaweedfs/traefik/certs
sudo touch /mnt/seaweedfs/traefik/certs/certs.json
sudo nano /mnt/seaweedfs/traefik/traefik.yml
traefik.ymlに下記内容を貼り付け
providers:
  docker:
    exposedByDefault: false
    # テスト用(公開時は要変更)
    defaultRule: "Host(`{{ index .Labels \"traefik.host\" }}.192.168.0.11.nip.io`)"
    swarmMode: true
api:
  insecure: true

nip.io って何?

こちらの記事で紹介されていたのですが、サブドメインを付けたまま指定されたIPアドレスにルーティングを返してくれるDNSサービスらしいです。LAN内のアドレスにも使えるので、テスト用に利用させていただきます

3 composeファイルをデプロイ

stacksから下記composeファイルをデプロイします

docker-compose.yml
version: "3.4"

services:
  traefik:
    image: traefik:v2.5
    ports:
      - 80:80 # HTTP
      - 443:443 # HTTPS
      - 1204:8080 # API
    networks:
      - traefik-net
    volumes:
      - /mnt/seaweedfs/traefik/certs/certs.json:/certs.json:ro
      - /mnt/seaweedfs/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
      - /var/run/docker.sock:/var/run/docker.sock
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role==manager
      restart_policy:
        condition: on-failure

networks:
  traefik-net:
    external: true

4 Traefikを試してみる

別の定義ファイルでサービスを作り、labelsにtraefikを設定します。
whoamiは各種IPアドレスやホスト名等が確認できるコンテナです。

whoami-compose.yml
version: "3.4"

services:
  whoami:
    image: containous/whoami
    networks:
      - traefik-net
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
      labels:
        - "traefik.enable=true"
        # アクセスする際のホスト名 (テスト用の場合 ホスト名+アドレス+nip.ioになる)
        - "traefik.host=whoami"
        # Traefikの属するのと同じネットワークを指定
        - "traefik.docker.network=traefik-net"
        # Traefikで指定したアクセスする際のエントリーポイント(http/https等)
        - "traefik.http.routers.whoami.entrypoints=http"
        # コンテナ内で動作しているサービスのポート
        - "traefik.http.services.whoami.loadbalancer.server.port=80"
networks:
  # traefik作成時に作成したネットワーク名
  traefik-net:
    external: true

上記をデプロイして、アクセスしてみると下記画像のようになります。リロードすると一番上のhostnameが変わり、複数のホストから応答が返ってきていることが確認できます。

完走した感想

激寒ギャグ

設定ファイルが読み込めない問題

前回ほど困らなくてサクッと終わったのですが、なんか、設定ファイルを書き込む際に謎のNULLが挿入されて上手く動作しない謎現象に困りました。原因はSeaweedFSだったようで、使っているディレクトリはいくらサイズが小さくても即時に同期されるわけではないので、そのフォルダにアクセスしているサービスを完全に止めるか、ファイルを消してもう一度作り直さないとダメだったようです。Traefik自体はなんかすごく便利そうなので、今後末長く利用させていただきたいと思っています。

オンプレで設定してたサイト繋がらない問題

ユーザーさんから連絡あって気づいたんですが、Swarm内のノードで、既にポート80で動かしてたnginxのポートを横取りしてしまい、サイトに繋がらなくなっていました。既に動いてるプロセスがあるなら別ポートを使うなりして、サイトが止まらないように気をつけましょう(うっかり)

参考