← Cloudflare One / cloudflare-one / networks / connectors / cloudflare-mesh
Запуск 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 и скопируйте его токен.
-
В панели управления Cloudflare перейдите в Сеть > Mesh.
Перейдите в Mesh ↗ -
Выберите Добавьте узел.
-
Введите имя узла (например,
k8s-gatewayилиdocker-agent). -
Выберите Создать узел.
-
Скопируйте токен, отображённый в панели управления. Вы передадите его в контейнер как
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: 1Gi3. Проверьте узел
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: http3. Проверьте 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-маршрутами:
- Используйте один и тот же токен узла Mesh для нескольких реплик.
- Выделите каждому 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-meshKubernetes Service не удается разрешить
Убедитесь, что маршрут по имени хоста соответствует фактическому DNS-суффиксу кластера. Значение по умолчанию обычно cluster.local, в результате получаются имена Service, такие как service.namespace.svc.cluster.local.
Запрос имени хоста приходит, но ответ не возвращается
Сначала проверьте source NAT и обратную маршрутизацию. Убедитесь, что SRCNAT_ENABLED имеет значение true или в том, что в вашей сети есть обратные маршруты к диапазону IP-адресов Mesh.
Проверить состояние узла
docker exec -it cloudflare-mesh warp-cli statuskubectl exec cloudflare-mesh-0 -- warp-cli statusСледующие шаги
- Добавление маршрутов : Сделайте подсети за контейнеризированным узлом доступными с любого устройства в вашей Mesh.
- Включить высокую доступность : Запустите несколько реплик для повышения отказоустойчивости рабочей среды.
- Подключитесь из Workers : Используйте привязки VPC Network для доступа к приватным сервисам из Cloudflare Workers.
- Советы и лучшие практики : Настройка облачного VPC, настройка MTU и работа совместно с Cloudflare Tunnel.