Service Mesh на базе Kong: mTLS, traffic splitting, policy enforcement
Service Mesh решает проблему безопасной и наблюдаемой коммуникации между микросервисами в распределённых системах.
Проблема: В микросервисной архитектуре сервисы должны общаться друг с другом. Это создаёт проблемы:
Решение: Service Mesh — инфраструктурный слой для управления service-to-service коммуникацией.
┌─────────────────────────────────────────────────────────────┐
│ Service Mesh Architecture │
└─────────────────────────────────────────────────────────────┘
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Service │ │ Service │ │ Service │
│ A │ │ B │ │ C │
│ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │
│ │ App │ │ │ │ App │ │ │ │ App │ │
│ └───┬────┘ │ │ └───┬────┘ │ │ └───┬────┘ │
│ ┌───┴────┐ │ │ ┌───┴────┐ │ │ ┌───┴────┐ │
│ │ Sidecar│ │ │ │ Sidecar│ │ │ │ Sidecar│ │
│ │ (Envoy)│ │ │ │ (Envoy)│ │ │ │ (Envoy)│ │
│ └────────┘ │ │ └────────┘ │ │ └────────┘ │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└───────────────────┼───────────────────┘
│
┌────────▼────────┐
│ Control Plane │
│ (Kong Mesh) │
└─────────────────┘
Компоненты Service Mesh:
Проблема: Нужно понимать разницу между API Gateway и Service Mesh.
Решение: Они решают разные задачи и дополняют друг друга.
| Характеристика | Kong Gateway | Kong Mesh |
|---|---|---|
| Тип трафика | North-South (клиент → сервис) | East-West (сервис → сервис) |
| Развёртывание | Центральный шлюз | Sidecar в каждом pod |
| Прокси | nginx | Envoy |
| Безопасность | TLS termination | mTLS между сервисами |
| Маршрутизация | По path/host к сервисам | Traffic splitting между версиями |
| Use case | Внешний API, аутентификация | Внутренняя коммуникация, шифрование |
┌──────────────────────────────────────────────────────────────┐
│ Полный стек │
└──────────────────────────────────────────────────────────────┘
Интернет
│
▼
┌──────────────┐
│ Kong Gateway │ ← North-South (API Gateway)
└──────┬───────┘
│
▼
┌─────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────┐ │
│ │ Service │◄──►│ Service │◄──►│Svc │ │
│ │ +Sidecar│ │ +Sidecar│ │+SC │ │
│ └─────────┘ └─────────┘ └─────┘ │
│ ▲ │
│ └──────────────────────────────────┘ │
│ Kong Mesh │
│ (East-West) │
└─────────────────────────────────────────┘
Проблема: Нужно развернуть Kong Mesh в Kubernetes.
Решение: Helm chart для Kong Mesh.
# Добавляем репозиторий
helm repo add kong https://charts.konghq.com
helm repo update
# Создаём namespace
kubectl create namespace kong-mesh
# Установка Global Control Plane
helm install kong-mesh-global kong/kong-mesh-global \
--namespace kong-mesh \
--set controlPlane.environment=universal# Получение токена для зоны
kubectl get -n kong-mesh secret kong-mesh-global-zone-token -o jsonpath='{.data.token}' | base64 -d > zone-token
# Установка Zone Control Plane
helm install kong-mesh-zone kong/kong-mesh-zone \
--namespace kong-mesh \
--set controlPlane.environment=kubernetes \
--set controlPlane.zoneToken=$(cat zone-token) \
--set controlPlane.globalAddress=grpc://kong-mesh-global.kong-mesh:5685# Добавление аннотации для автоматического injection sidecar
kubectl label namespace default kong-mesh-injection=enabled# app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: users-service
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: users-service
template:
metadata:
labels:
app: users-service
spec:
containers:
- name: users-service
image: users-service:latest
ports:
- containerPort: 8080kubectl apply -f app.yamlПроверка sidecar:
kubectl get pods
# NAME READY STATUS
# users-service-xxxxxxxxx-xxxxx 2/2 Running ← app + sidecarПроблема: Нужно шифровать трафик между сервисами и аутентифицировать их.
Решение: Kong Mesh автоматически выдаёт сертификаты каждому сервису.
# meshtrafficpermission.yaml
apiVersion: kuma.io/v1alpha1
kind: MeshTrafficPermission
metadata:
name: default-mtls
namespace: kong-mesh
spec:
targetRef:
kind: Mesh
from:
- targetRef:
kind: Mesh
default:
action: Allowkubectl apply -f meshtrafficpermission.yaml┌─────────────────────────────────────────────────────────────┐
│ mTLS Handshake │
└─────────────────────────────────────────────────────────────┘
Service A (sidecar) Service B (sidecar)
│ │
│ 1. ClientHello + cert A │
├────────────────────────────────►│
│ │
│ 2. ServerHello + cert B │
│ + CertificateRequest │
◄─────────────────────────────────┤
│ │
│ 3. Client cert A │
├────────────────────────────────►│
│ │
│ 4. Verify cert A │
│ Verify cert B │
│ │
│ 5. Зашифрованное соединение │
◄────────────────────────────────►│
Процесс:
# Проверка статуса mTLS для сервиса
kubectl get meshtrafficpermission default-mtls -o yaml
# Проверка сертификатов sidecar
kubectl exec -it users-service-xxxxx -c kuma-sidecar -- \
cat /var/run/secrets/kuma.io/tls/cert.pemПроблема: Нужно развернуть новую версию сервиса с постепенным накатом.
Решение: TrafficPermission и TrafficRoute политики Kong Mesh.
# trafficroute.yaml
apiVersion: kuma.io/v1alpha1
kind: TrafficRoute
metadata:
name: canary-route
namespace: kong-mesh
spec:
sources:
- match:
kuma.io/service: '*'
destinations:
- match:
kuma.io/service: users-service
conf:
loadBalancer:
roundRobin: {}
split:
- weight: 90
destination:
kuma.io/service: users-service
version: v1
- weight: 10
destination:
kuma.io/service: users-service
version: v2kubectl apply -f trafficroute.yamlРезультат:
# trafficroute-header.yaml
apiVersion: kuma.io/v1alpha1
kind: TrafficRoute
metadata:
name: ab-test-route
spec:
sources:
- match:
kuma.io/service: '*'
destinations:
- match:
kuma.io/service: users-service
conf:
split:
- weight: 100
destination:
kuma.io/service: users-service
version: v2
match:
headers:
x-ab-test: "enabled"
- weight: 100
destination:
kuma.io/service: users-service
version: v1Использование:
# Запрос с заголовком попадает на v2
curl -H "x-ab-test: enabled" http://users-service:8080/api/users
# Обычный запрос попадает на v1
curl http://users-service:8080/api/usersПроблема: Нужно ограничить доступ между сервисами (например, только payments → orders).
Решение: MeshTrafficPermission политики.
# restrict-access.yaml
apiVersion: kuma.io/v1alpha1
kind: MeshTrafficPermission
metadata:
name: restrict-orders
spec:
targetRef:
kind: MeshService
name: orders-service
from:
- targetRef:
kind: MeshService
name: payments-service
default:
action: Allow
- targetRef:
kind: Mesh
default:
action: Denykubectl apply -f restrict-access.yamlРезультат:
Mesh (глобально)
↓
Namespace
↓
Service
↓
Route (наиболее специфичный)
Более специфичная политика переопределяет общую.
Проблема: Нужно видеть метрики и trace для сервисов в mesh.
Решение: Встроенные метрики Envoy и интеграция с Prometheus/Jaeger.
# meshmetrics.yaml
apiVersion: kuma.io/v1alpha1
kind: MeshMetrics
metadata:
name: default
spec:
targetRef:
kind: Mesh
prometheus:
- path: /metrics
port: 8080kubectl apply -f meshmetrics.yaml# prometheus service monitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: kong-mesh
spec:
selector:
matchLabels:
app: kuma-sidecar
endpoints:
- port: metrics
path: /metrics
interval: 15s# meshtrace.yaml
apiVersion: kuma.io/v1alpha1
kind: MeshTrace
metadata:
name: default
spec:
targetRef:
kind: Mesh
default:
backend:
zipkin:
url: http://jaeger:9411/api/v2/spans
sampling: 10.0kubectl apply -f meshtrace.yamlПроблема: Сервисы работают в разных кластерах/регионах, нужна единая mesh сеть.
Решение: Kong Mesh Multi-Zone архитектура.
┌─────────────────────────────────────────────────────────────┐
│ Multi-Zone Architecture │
└─────────────────────────────────────────────────────────────┘
┌──────────────────┐
│ Global CP │
│ (единый) │
└────────┬─────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌──────▼──────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ Zone CP │ │ Zone CP │ │ Zone CP │
│ (US-East) │ │ (EU-West) │ │ (AP-South)│
└──────┬──────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
┌──────┴──────┐ ┌─────┴─────┐ ┌────┴─────┐
│ Services │ │ Services │ │ Services │
└─────────────┘ └───────────┘ └──────────┘
# Global Control Plane должен быть доступен из всех зон
helm install kong-mesh-global kong/kong-mesh-global \
--namespace kong-mesh \
--set controlPlane.environment=universal \
--set controlPlane.globalAddress=grpc://global-cp.example.com:5685# Каждая зона подключается к Global CP
helm install kong-mesh-zone kong/kong-mesh-zone \
--namespace kong-mesh \
--set controlPlane.zone=us-east \
--set controlPlane.globalAddress=grpc://global-cp.example.com:5685# Проверка статуса sidecar
kubectl get pods -o custom-columns=NAME:.metadata.name,SIDECAR:.status.containerStatuses[*].ready
# Логи sidecar
kubectl logs users-service-xxxxx -c kuma-sidecar
# Проверка политик
kubectl get meshtrafficpermission
kubectl get meshroute
# Inspect сервис
kubectl inspect mesh service/users-serviceВопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.