INTEGRITY Документация

Запуск Mesh в Docker / Kubernetes

cloudflare/mesh Образ Docker включает узел Cloudflare Mesh для Linux-контейнеров. В нём выполняется исполняемый файл клиента Cloudflare One warp-svc демон в безголовом режиме в минимальном Wolfi-совместимая среда выполнения.

Используйте образ контейнера, чтобы добавлять узлы Mesh в стеки Docker Compose, кластеры Kubernetes и конвейеры CI/CD без установки пакетов на хост.

Поддерживаемые архитектуры

latest tag представляет собой мультиплатформенный манифест. Docker автоматически выбирает подходящий образ для архитектуры хоста.

Архитектура Тег
Multi-arch latest
x86-64 latest-amd64
ARM64 latest-arm64

Предварительные требования

Прежде чем запускать контейнер, создайте узел Mesh и скопируйте его токен.

  1. В панели управления Cloudflare перейдите в Сеть > Mesh.

    Перейдите в Mesh ↗
  2. Выберите Добавьте узел.

  3. Введите имя узла (например, k8s-gateway или docker-agent).

  4. Выберите Создать узел.

  5. Скопируйте токен, отображённый в панели управления. Вы передадите его в контейнер как MESH_NODE_TOKEN.

Создайте узел через Cloudflare API:

curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/warp_connector" \
  -H "Authorization: Bearer {api_token}" \
  -H "Content-Type: application/json" \
  -d '{"name": "k8s-gateway"}'

Затем получите токен:

curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/warp_connector/{node_id}/token" \
  -H "Authorization: Bearer {api_token}"

Ответ содержит строку токена. Передайте её в контейнер как MESH_NODE_TOKEN.

Если это ваш первый узел Mesh, панель управления запускает setup wizard которая настраивает ваш аккаунт для сети Mesh.

Разверните с помощью Docker Compose

Docker Compose представляет собой рекомендуемый способ запуска узла Mesh вместе со службами вашего приложения. Добавьте cloudflare-mesh службу к вашему compose.yaml:

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

В этом примере создаётся с одной репликой StatefulSet с сохраняемым состоянием регистрации. Для этого требуется кластер Kubernetes, который разрешает NET_ADMIN, NET_RAW, а также /dev/net/tun доступ к хосту (например, 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 сохраняет регистрацию Mesh при перезапуске Pod.

Kubernetes sidecar

Чтобы подключить контейнер приложения к Mesh, добавьте образ Mesh в качестве sidecar в тот же Pod. Контейнеры в Pod используют общее пространство имён сети, поэтому sidecar Mesh подключает приложение к Cloudflare без каких-либо изменений в самом приложении.

1. Создайте Secret токена

Создайте отдельный узел Mesh и Kubernetes Secret для sidecar:

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 Обязательный для первоначальной регистрации. Создайте токен в разделе Сеть > Mesh в Панель управления Cloudflare, либо через API.
SRCNAT_ENABLED Управляет source NAT. По умолчанию используется true. Принимает true, false, 1, или 0.
/var/lib/cloudflare-warp Хранит состояние регистрации. Сохраняйте этот путь с помощью тома, чтобы поддерживать стабильную идентификацию Mesh при пересоздании контейнера.

Необходимые возможности и устройства

Возможность / устройство Зачем это нужно
NET_ADMIN Создаёт и настраивает интерфейс туннеля, маршрутизацию и правила nftables.
NET_RAW Разрешает операции с raw-сокетами, такие как ICMP. Docker обычно предоставляет эту возможность по умолчанию, но здесь она указана явно.
/dev/net/tun Создаёт интерфейс WARP TUN.
Параметры sysctl для IP-forwarding Требуется, если узел перенаправляет трафик для маршрутизируемых подсетей.

NAT источника

NAT источника (маскарадинг) включен по умолчанию (SRCNAT_ENABLED=true). Когда узел Mesh получает трафик от периферии Cloudflare и пересылает его на узел назначения в локальной сети, он транслирует исходный IP-адрес из адреса Mesh CGNAT (100.96.x.x) на собственный локальный IP-адрес интерфейса узла. Это обеспечивает правильную маршрутизацию обратного трафика без необходимости настраивать статические маршруты в вашей VPC или локальной сети.

Задайте SRCNAT_ENABLED=false только если у подключённых сетей уже есть обратные маршруты к диапазону IP-адресов Mesh (100.96.0.0/12). Подробнее о маршрутизации обратного трафика см. в Маршруты.

Высокая доступность в Kubernetes

Для высокая доступность с CIDR-маршрутами:

  1. Используйте один и тот же токен узла Mesh для нескольких реплик.
  2. Выделите каждому Pod собственный PersistentVolumeClaim.

Cloudflare использует реплики в режиме active-passive. Если активная реплика выходит из строя, трафик автоматически переключается на резервную. Единственная реплика не обеспечивает избыточности.

Маршруты хоста

Контейнеры поддерживают маршрутизация по имени хоста. Чтобы разрешать Kubernetes Services через маршрут по имени хоста, убедитесь, что имя хоста соответствует фактическому суффиксу DNS кластера. По умолчанию используется cluster.local, в результате получаются имена Service вида service.namespace.svc.cluster.local.

Сетевое взаимодействие между сайтами

Разверните отдельный контейнер узла Mesh на каждой площадке с отдельным токеном узла для каждого идентификатора узла. Каждый узел должен анонсировать свою локально доступную подсеть как Маршрут CIDR. Настройте маршрутизатор или рабочие нагрузки каждого сайта так, чтобы трафик для удалённой подсети направлялся через локальный узел Mesh.

С SRCNAT_ENABLED=true, получатели видят локальный адрес узла Mesh. Если source NAT отключён, подключённым сетям требуются обратные маршруты через их узлы Mesh.

Устранение неполадок

Узел регистрируется как обычное устройство Cloudflare One Client

Убедитесь, что правильный токен узла Mesh задан в MESH_NODE_TOKEN. Существующее состояние регистрации в постоянном томе имеет приоритет: удаляйте том только тогда, когда вы намеренно хотите отменить эту регистрацию и создать новую идентификацию.

warp-cli status остается в статусе Connecting

Проверьте токен, профиль устройства, Gateway proxy, конфигурацию Split Tunnel, исходящее подключение через межсетевой экран и журналы контейнеров:

docker logs cloudflare-mesh

Kubernetes Service не удается разрешить

Убедитесь, что маршрут по имени хоста соответствует фактическому DNS-суффиксу кластера. Значение по умолчанию обычно cluster.local, в результате получаются имена Service, такие как service.namespace.svc.cluster.local.

Запрос имени хоста приходит, но ответ не возвращается

Сначала проверьте source NAT и обратную маршрутизацию. Убедитесь, что SRCNAT_ENABLED имеет значение true или в том, что в вашей сети есть обратные маршруты к диапазону IP-адресов Mesh.

Проверить состояние узла

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

Следующие шаги