はじめに
Traefik を Kubernetes クラスタに導入して、Ingress の管理、ロードバランシング、Let's Encrypt による TLS 自動化を行う手順をまとめます。
Traefik は動的ルーティングやミドルウェア(リダイレクト、認証、CORS など)を容易に設定できるため、開発環境から本番運用まで幅広く利用できます。この記事では Helm を使ったインストール例、IngressRoute を用いた公開、ACME(Let's Encrypt)による証明書取得までを扱います。
対象環境:
- Kubernetes クラスタ(kubectl が利用可能なこと)
- Helm 3
- 公開ドメイン(Let's Encrypt を利用する場合)
注意点:
- ダッシュボードや管理用エンドポイントを公開する場合は必ず認証やアクセス制限を行ってください。
1. 準備
まず Helm リポジトリを追加します。
helm repo add traefik https://traefik.github.io/charts
helm repo update
本稿は Traefik v2 系の公式 Helm Chart を前提としています。
2. 名前空間作成と CRD の適用
Chart によっては CRD が必要になるため、--create-namespace と crds=true を利用するか、Chart に含まれる CRD を事前に適用してください。
kubectl create ns traefik
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik-helm-chart/master/traefik/crds/crd_traefikio_ingressroutes.yaml
# 必要に応じて他の CRD も適用してください
Chart のバージョンやリポジトリ構成により CRD の配置が変わるため、公式リポジトリを確認してください。
3. Helm でインストール(シンプル)
まずは最低限の設定で動作させてみます。ここでは外部公開に LoadBalancer 型の Service を使用する想定です。
helm install traefik traefik/traefik \
--namespace traefik \
--set service.type=LoadBalancer \
--set ingressClass.enabled=true \
--set dashboard.enabled=true
主なオプション:
-
service.type:LoadBalancer/NodePort/ClusterIP -
ingressClass.enabled: Traefik の IngressClass を有効化 -
dashboard.enabled: ダッシュボードを有効化(本番環境では認証必須)
インストール後は外部 IP を確認します。
kubectl -n traefik get svc
4. values.yaml の例(Let's Encrypt + Dashboard 保護)
本番では values.yaml を用意して Helm に渡す方法が管理しやすいです。以下は HTTP-01 による ACME(Let's Encrypt)自動取得の一例です。
# values.yaml
service:
type: LoadBalancer
ingressClass:
enabled: true
dashboard:
enabled: true
# ダッシュボードを公開する場合は BasicAuth 等で保護してください
certificatesResolvers:
letsencrypt:
acme:
email: your@example.com
storage: /data/acme.json
httpChallenge:
entryPoint: web
ports:
web:
port: 80
exposedPort: 80
websecure:
port: 443
exposedPort: 443
resources: {}
# 必要に応じてログレベルやプロバイダ設定を追加してください
この values.yaml を指定してインストールまたはアップグレードします。
helm upgrade --install traefik traefik/traefik -n traefik -f values.yaml
5. サンプルアプリを用意して IngressRoute で公開
ここでは確認用に簡単な Deployment と Service を用意します。
# app-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: containous/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
selector:
app: whoami
ports:
- protocol: TCP
port: 80
targetPort: 80
次に Traefik の CRD である IngressRoute を使って公開する例です(ドメインは適宜置き換えてください)。
# ingressroute.yaml
apiVersion: traefik.containo.us/v1beta1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`example.com`)
kind: Rule
services:
- name: whoami
port: 80
tls:
certResolver: letsencrypt
上記を適用し、DNS が example.com を指していれば TLS で公開されます。
kubectl apply -f app-deploy.yaml
kubectl apply -f ingressroute.yaml
6. Middleware の例(BasicAuth で Dashboard を保護)
ダッシュボードは公開したままにするとリスクが高いため、BasicAuth などで保護してください。htpasswd で認証情報を作成し、Secret として登録する流れの例を示します。
# htpasswd でユーザー作成(htpasswd コマンドが必要)
htpasswd -nb admin password | sed -e s/\$/\$\$/g
# 出力をコピーして Secret の値に使います
# traefik-dashboard-auth.yaml
apiVersion: v1
kind: Secret
metadata:
name: traefik-dashboard-auth
namespace: traefik
type: Opaque
data:
# 事前に base64 エンコードした htpasswd の値を入れてください
users: BASE64_ENCODED_HTPASSWD
---
apiVersion: traefik.containo.us/v1beta1
kind: Middleware
metadata:
name: dashboard-auth
namespace: traefik
spec:
basicAuth:
secret: traefik-dashboard-auth
removeHeader: true
---
# ダッシュボード用 IngressRoute(例)
apiVersion: traefik.containo.us/v1beta1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: traefik
spec:
entryPoints:
- websecure
routes:
- match: Host(`traefik.example.com`)
kind: Rule
services:
- name: api@internal
kind: TraefikService
middlewares:
- name: dashboard-auth
tls:
certResolver: letsencrypt
補足: api@internal は Traefik の内部サービスを指す特殊な指定です。ダッシュボード公開時は必ず認証を挟んでください。
7. Let's Encrypt (ACME) のポイント
- HTTP-01 チャレンジを利用する場合はポート 80 が外部から到達可能であること
- DNS-01 を利用する場合は使用する DNS プロバイダの API トークン等が必要
- ACME のストレージ(例:
/data/acme.json)は永続化しておくこと
環境に応じて HTTP-01 / DNS-01 を使い分けてください。
8. 検証とトラブルシュート
トラブルシュート例:
- Traefik Pod のログ確認
kubectl -n traefik logs -l app.kubernetes.io/name=traefik
- 証明書の状態確認(ACME エラーの確認)
kubectl -n traefik exec deploy/traefik -- cat /data/acme.json
- IngressRoute の登録状況確認
kubectl get ingressroutes --all-namespaces
- Helm の設定を反映する場合は
helm upgrade --installを実行してください。
よくある問題:
- DNS が正しく設定されていない → ACME チャレンジに失敗する
- ポート 80/443 が閉じている → HTTP-01 が失敗する
- CRD が適用されていない → IngressRoute が反映されない
まとめ
Traefik は middleware が使えたりとても拡張性が高いです。
ぜひ使ってみてください!
また、当サークルでは ProxmoxVE や Kubernetes を運用しています。
もし興味がありましたら、下記 URL へ飛んでいただければと思います!
⭐︎ 公式 HP ↓
⭐︎ Discord ↓
参考文献