K3sのデフォルトTraefik IngressでEnd-to-End TLS通信を設定する方法
2025-08-17
Post Image

はじめに

K3sのデフォルトIngressコントローラであるTraefikを使って、クライアントからバックエンドサービスまで完全なTLS通信(End-to-End TLS)を実現する方法を解説します。この設定により、様々なサービスをセキュアに公開し、データ盗難や中間者攻撃を防ぐことができます。本記事では、TraefikのServersTransportリソースを使った設定手順を、実際のYAML例とともにステップごとに説明します。

ServersTransportリソースの作成

まず、バックエンドサービスへのTLS接続を定義するために、ServersTransportというカスタムリソースを作成します。これはTraefikのCRD(Custom Resource Definition)を使って実現されます。TraefikはデフォルトでバックエンドサービスにHTTPで接続しますが、ServersTransportリソースを使うことでバックエンドへの接続をHTTPS(TLS)に変更でき、End-to-Endの暗号化を実現できます。以下は、my-namespaceというネームスペースのサービスを例にしたYAML例です:

apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
  name: my-transport
  namespace: my-namespace
spec:
  serverName: "*.my-namespace.svc.cluster.local"
  rootCAsSecrets: 
    - my-ca-secret
  insecureSkipVerify: false
  • serverName:
    バックエンドサービスのSNI(Server Name Indication)を指定します。ここではワイルドカードを使ってmy-namespaceのサービスを対象にしています。
  • rootCAsSecrets: バックエンドサービスのルートCA秘密鍵を指定します。これは独自の証明書(例: 自前で生成したもの)を使う場合に必要です。ここでmy-ca-secretというSecretを参照しています。
  • insecureSkipVerify:false:
    に設定すると、証明書の検証が行われます。これがデフォルトのセキュアな設定です。

このリソースを作成したら、kubectl apply -f filename.yaml で適用します。

IngressやServiceへのAnnotation設定

次に、Ingressリソースや関連するServiceにTraefik固有のAnnotationを追加して、ServersTransportを適用します。Serviceに以下のAnnotationを追加します:

annotations:
  traefik.ingress.kubernetes.io/service.serversscheme: https
  traefik.ingress.kubernetes.io/service.serverstransport: my-namespace-my-transport@kubernetescrd
  • service.serversscheme:https:
    バックエンドへの通信をHTTPSに指定します。これでEnd-to-End TLSが有効になります。
  • traefik.ingress.kubernetes.io/service.serverstransport: my-namespace-my-transport@kubernetescrd:
    先ほど作成したServersTransportのリソース名を参照します。@kubernetescrdはTraefikがCRDを参照することを示します。my-namespaceがネームスペースで、my-transportがServersTransportのnameに相当します。

これにより、Traefikはバックエンドサービスに対してTLSで接続し、証明書の検証を行います。

独自証明書 vs Let's Encryptの場合の違い

バックエンドサービスの証明書によって、ServersTransportの設定が変わります。

独自証明書の場合

自前で生成した証明書(例: OpenSSLで作成したもの)を使う場合、Traefikがその証明書を信頼するためにルートCAを指定する必要があります。上記のYAML例のように、rootCAsSecretsにSecret名を追加します。このSecretには、ルートCAの証明書ファイル(例: ca.crt)が含まれているはずです。これを省略すると、証明書の検証に失敗し、接続エラーが発生します。

Let's Encryptの場合

Let's Encryptの証明書は信頼された公開CA(例: ISRG Root X1)によって発行されるため、Traefikがデフォルトでこれを信頼します。したがって、rootCAsSecretsの指定は不要です。以下は設定例です:

apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
  name: my-transport
  namespace: my-namespace
spec:
  serverName: "*.my-namespace.svc.cluster.local"
  insecureSkipVerify: false

これでTraefikが自動的に証明書を検証します。

insecureSkipVerifyをtrueに設定して簡略化

証明書の検証をスキップしたい場合(例: 開発環境や一時的なテスト時)、insecureSkipVerify: trueに設定します。これにより、serverNameの指定が不要になります。YAML例は以下のようになります:

apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
  name: my-transport
  namespace: my-namespace
spec:
  insecureSkipVerify: true

この設定は便利ですが、セキュリティリスクがあるため、本番環境では避けましょう。Man-in-the-Middle攻撃の可能性が増します。

注意点とトラブルシューティング

まとめ

K3sのTraefikでEnd-to-End TLSを設定するのは、ServersTransportとAnnotationの組み合わせで実現可能です。独自証明書ではrootCAsSecretsを追加、Let's Encryptでは不要、そしてinsecureSkipVerifyで簡略化できる点を覚えておきましょう。この設定で、MinIOや他のサービスを安全に露出できます。ご質問があればコメントください! KubernetesのTLS設定で困った経験があれば共有しましょう。

K3sのデフォルトTraefik IngressでEnd-to-End TLS通信を設定する方法
https://notes.midnightstops.com/posts/26/
作者
Author
公開日
2025-08-17