Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Docker / Kubernetes で Mesh を実行する

最終更新 Markdown で表示Agent セットアップ

cloudflare/mesh Docker イメージは、Linux コンテナ向けの Cloudflare Mesh ノードをパッケージします。Cloudflare One Client の warp-svc デーモンを、最小の Wolfi ベースランタイムでヘッドレス実行します。

コンテナイメージを使い、ホストにパッケージをインストールせずに、Docker Compose スタック、Kubernetes クラスター、CI/CD パイプラインへ Mesh ノードを追加します。

サポートされるアーキテクチャ

latest タグはマルチプラットフォームマニフェストです。Docker はホストアーキテクチャに応じたイメージを自動選択します。

アーキテクチャ タグ
マルチアーキテクチャ latest
x86-64 latest-amd64
ARM64 latest-arm64

前提条件

コンテナを開始する前に、Mesh ノードを作成し、そのトークンをコピーします。

  1. Cloudflare dashboard で Networking > Mesh を開きます。

    Mesh を開く ↗
  2. Add a node を選択します。

  3. ノード名を入力します(k8s-gatewaydocker-agent など)。

  4. Create node を選択します。

  5. dashboard に表示されたトークンをコピーします。コンテナへ MESH_NODE_TOKEN として渡します。

Cloudflare One Connectors Write または Cloudflare One Connector: WARP Write 権限を持つ API トークンで、ノードを作成し、コネクタートークンを取得します。

set -euo pipefail

NODE_RESPONSE=$(
	curl --fail-with-body --silent --show-error \
		"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/warp_connector" \
		--request POST \
		--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
		--header "Content-Type: application/json" \
		--data '{"name":"k8s-gateway"}'
)

jq -e '.success == true and (.result.id | type == "string")' \
	<<< "$NODE_RESPONSE" > /dev/null
NODE_ID=$(jq -r '.result.id' <<< "$NODE_RESPONSE")

TOKEN_RESPONSE=$(
	curl --fail-with-body --silent --show-error \
		"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/warp_connector/$NODE_ID/token" \
		--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
)

MESH_NODE_TOKEN=$(jq -er \
	'select(.success == true) | .result | select(type == "string" and length > 0)' \
	<<< "$TOKEN_RESPONSE")

jq をインストールし、コマンドを実行する前に ACCOUNT_IDCLOUDFLARE_API_TOKEN を設定します。コマンドは HTTP または API エラーで停止します。終了コードが 0 で、NODE_IDMESH_NODE_TOKEN が設定されるまで先に進まないでください。ノード作成後にトークン取得が失敗した場合は、既存の NODE_ID でトークンリクエストだけを再試行します。ノード作成リクエストは再実行しないでください。MESH_NODE_TOKEN をコンテナへ渡します。

これが最初の Mesh ノードなら、必要なアカウント設定 を構成します。dashboard ウィザード、API、Terraform のいずれかを使えます。

Docker Compose でデプロイする

Docker Compose は、アプリケーションサービスと並べて Mesh ノードを動かす推奨方法です。compose.yamlcloudflare-mesh サービスを追加します。

services:
  cloudflare-mesh:
    image: cloudflare/mesh:latest
    container_name: cloudflare-mesh
    cap_add:
      - NET_ADMIN
      - NET_RAW
    devices:
      - /dev/net/tun:/dev/net/tun
    environment:
      MESH_NODE_TOKEN: ${MESH_NODE_TOKEN}
      SRCNAT_ENABLED: "true"
    sysctls:
      net.ipv4.ip_forward: "1"
      net.ipv6.conf.all.forwarding: "1"
      net.ipv6.conf.default.forwarding: "1"
    volumes:
      - mesh_data:/var/lib/cloudflare-warp
    restart: unless-stopped

volumes:
  mesh_data:

スタックを起動します。

MESH_NODE_TOKEN="<YOUR-TOKEN>" docker compose up -d

ノードが接続されていることを確認します。

docker exec cloudflare-mesh warp-cli status

Docker CLI でデプロイする

Compose なしのスタンドアロンコンテナの場合:

docker run -d \
  --name cloudflare-mesh \
  --cap-add NET_ADMIN \
  --cap-add NET_RAW \
  --device /dev/net/tun \
  --sysctl net.ipv4.ip_forward=1 \
  --sysctl net.ipv6.conf.all.forwarding=1 \
  --sysctl net.ipv6.conf.default.forwarding=1 \
  -e MESH_NODE_TOKEN="$MESH_NODE_TOKEN" \
  -e SRCNAT_ENABLED=true \
  -v mesh_data:/var/lib/cloudflare-warp \
  --restart unless-stopped \
  cloudflare/mesh:latest

Kubernetes でデプロイする

この例は、永続的な登録状態を持つ 1 レプリカの StatefulSet を作成します。NET_ADMINNET_RAW/dev/net/tun ホストアクセスを許可する Kubernetes クラスター(GKE Standard など)が必要です。

1. トークン Secret を作成する

kubectl create secret generic cloudflare-mesh \
  --from-literal=MESH_NODE_TOKEN="$MESH_NODE_TOKEN"

2. マニフェストを適用する

次を cloudflare-mesh.yaml として保存します。

apiVersion: v1
kind: Service
metadata:
  name: cloudflare-mesh
spec:
  clusterIP: None
  selector:
    app: cloudflare-mesh
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cloudflare-mesh
spec:
  serviceName: cloudflare-mesh
  replicas: 1
  selector:
    matchLabels:
      app: cloudflare-mesh
  template:
    metadata:
      labels:
        app: cloudflare-mesh
    spec:
      containers:
        - name: mesh
          image: cloudflare/mesh:latest
          env:
            - name: MESH_NODE_TOKEN
              valueFrom:
                secretKeyRef:
                  name: cloudflare-mesh
                  key: MESH_NODE_TOKEN
            - name: SRCNAT_ENABLED
              value: "true"
          securityContext:
            capabilities:
              add:
                - NET_ADMIN
                - NET_RAW
          volumeMounts:
            - name: warp-data
              mountPath: /var/lib/cloudflare-warp
            - name: dev-net-tun
              mountPath: /dev/net/tun
      volumes:
        - name: dev-net-tun
          hostPath:
            path: /dev/net/tun
            type: CharDevice
  volumeClaimTemplates:
    - metadata:
        name: warp-data
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi

3. ノードを確認する

kubectl apply -f cloudflare-mesh.yaml
kubectl rollout status statefulset/cloudflare-mesh
kubectl exec cloudflare-mesh-0 -- warp-cli status

PersistentVolumeClaim は、Pod の再起動をまたいで Mesh 登録を保持します。

Kubernetes sidecar

アプリケーションコンテナを Mesh に接続するには、同じ Pod に Mesh イメージを sidecar として追加します。Pod 内のコンテナはネットワーク名前空間を共有するため、Mesh sidecar はアプリケーションの変更なしに Cloudflare へ接続します。

1. トークン Secret を作成する

sidecar 用に別の Mesh ノードと Kubernetes Secret を作成します。

kubectl create secret generic cloudflare-mesh-sidecar \
  --from-literal=MESH_NODE_TOKEN="$MESH_NODE_TOKEN"

2. マニフェストを適用する

次を cloudflare-mesh-sidecar.yaml として保存します。

apiVersion: v1
kind: Service
metadata:
  name: cloudflare-mesh-sidecar-headless
spec:
  clusterIP: None
  selector:
    app: cloudflare-mesh-sidecar
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cloudflare-mesh-sidecar
spec:
  serviceName: cloudflare-mesh-sidecar-headless
  replicas: 1
  selector:
    matchLabels:
      app: cloudflare-mesh-sidecar
  template:
    metadata:
      labels:
        app: cloudflare-mesh-sidecar
    spec:
      containers:
        - name: application
          image: busybox:1.37.0
          command:
            - sh
            - -c
            - |
              echo "Hello from the Kubernetes sidecar example" > /tmp/index.html
              httpd -f -p 8080 -h /tmp
          ports:
            - name: http
              containerPort: 8080
        - name: mesh
          image: cloudflare/mesh:latest
          env:
            - name: MESH_NODE_TOKEN
              valueFrom:
                secretKeyRef:
                  name: cloudflare-mesh-sidecar
                  key: MESH_NODE_TOKEN
            - name: SRCNAT_ENABLED
              value: "true"
          securityContext:
            capabilities:
              add:
                - NET_ADMIN
                - NET_RAW
          volumeMounts:
            - name: warp-data
              mountPath: /var/lib/cloudflare-warp
            - name: dev-net-tun
              mountPath: /dev/net/tun
      volumes:
        - name: dev-net-tun
          hostPath:
            path: /dev/net/tun
            type: CharDevice
  volumeClaimTemplates:
    - metadata:
        name: warp-data
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
  name: cloudflare-mesh-sidecar
spec:
  selector:
    app: cloudflare-mesh-sidecar
  ports:
    - name: http
      port: 8080
      targetPort: http

3. sidecar を確認する

kubectl apply -f cloudflare-mesh-sidecar.yaml
kubectl rollout status statefulset/cloudflare-mesh-sidecar
kubectl exec cloudflare-mesh-sidecar-0 -c mesh -- warp-cli status

ランタイム設定

パラメーター 説明
MESH_NODE_TOKEN 初回登録に 必須 です。トークンは Cloudflare dashboardNetworking > Mesh、または API で作成します。
SRCNAT_ENABLED ソース NAT を制御します。デフォルトは true です。truefalse10 を受け付けます。
/var/lib/cloudflare-warp 登録状態を保存します。コンテナ再作成をまたいで安定した Mesh 識別子を保つには、このパスをボリュームで永続化します。

必要な capability とデバイス

Capability / デバイス 必要な理由
NET_ADMIN トンネルインターフェース、ルーティング、nftables ルールを作成・設定します。
NET_RAW ICMP などの raw ソケット操作を有効にします。Docker は通常これをデフォルトで付与しますが、ここでは明示的に宣言します。
/dev/net/tun WARP TUN インターフェースを作成します。
IP 転送 sysctl ノードがルーティング済みサブネット向けにトラフィックを転送するときに必要です。

ソース NAT

ソース NAT(マスカレード)はデフォルトで有効です(SRCNAT_ENABLED=true)。Mesh ノードが Cloudflare エッジからトラフィックを受け取り、ローカルネットワーク上の宛先へ転送するとき、送信元 IP を Mesh CGNAT アドレス(100.96.x.x)からノード自身のローカルインターフェース IP へ変換します。これにより、VPC やオンプレミスネットワークに静的ルートがなくても、戻りトラフィックが正しくルーティングされます。

SRCNAT_ENABLED=false にするのは、接続先ネットワークがすでに Mesh IP 範囲(100.96.0.0/12)への戻りルートを持っている場合だけです。戻りトラフィックのルーティングの詳細は Routes を参照してください。

Kubernetes での高可用性

CIDR ルートで 高可用性 を使うには:

  1. 複数レプリカで同じ Mesh ノードトークンを使います。
  2. 各 Pod に独自の PersistentVolumeClaim を与えます。

Cloudflare はレプリカをアクティブ / パッシブで運用します。アクティブなレプリカがオフラインになると、トラフィックはスタンバイへ自動フェイルオーバーします。1 レプリカでは冗長性がありません。

ホスト名ルート

コンテナは ホスト名ルーティング をサポートします。ホスト名ルート経由で Kubernetes Service を解決するには、ホスト名がクラスターの実際の DNS サフィックスと一致することを確認します。デフォルトは cluster.local で、Service 名は service.namespace.svc.cluster.local のようになります。

サイト間ネットワーキング

各サイトに別の Mesh ノードコンテナをデプロイし、ノード識別子ごとに別のノードトークンを使います。各ノードは、ローカルで到達可能なサブネットを CIDR ルート として通知します。各サイトのルーターまたはワークロードを、リモートサブネット向けトラフィックがローカル Mesh ノード経由になるよう設定します。

SRCNAT_ENABLED=true の場合、宛先は Mesh ノードのローカルアドレスを見ます。ソース NAT を無効にした場合、接続先ネットワークは Mesh ノード経由の戻りルートが必要です。

トラブルシューティング

ノードが通常の Cloudflare One Client デバイスとして登録される

MESH_NODE_TOKEN に正しい Mesh ノードトークンが設定されていることを確認します。永続ボリューム内の既存の登録状態が優先されます。その登録を破棄して新しい識別子を作成したいときだけ、ボリュームを削除してください。

warp-cli status が Connecting のまま

トークン、デバイスプロファイル、Gateway プロキシ、Split Tunnel 構成、アウトバウンドファイアウォール接続、コンテナログを確認します。

docker logs cloudflare-mesh

Kubernetes Service を解決できない

ホスト名ルート がクラスターの実際の DNS サフィックスと一致することを確認します。通常のデフォルトは cluster.local で、Service 名は service.namespace.svc.cluster.local のようになります。

ホスト名リクエストは届くが応答が返らない

まずソース NAT と戻りルーティングを確認します。SRCNAT_ENABLEDtrue か、ネットワークに Mesh IP 範囲への戻りルートがあることを確認します。

ノードの状態を確認する

docker exec -it cloudflare-mesh warp-cli status
kubectl exec cloudflare-mesh-0 -- warp-cli status

次のステップ

  • ルートを追加する — コンテナ化されたノードの背後にあるサブネットを、Mesh 上の任意のデバイスから到達可能にします。
  • 高可用性を有効にする — 本番の耐障害性のために複数レプリカを実行します。
  • Workers から接続する — VPC Network バインディングで、Cloudflare Workers からプライベートサービスへ到達します。
  • ヒントと推奨事項 — クラウド VPC の設定、MTU 調整、Cloudflare Tunnel との併用。

役に立ちましたか?