Service Mesh: Istio, Linkerd
Service Mesh: Istio, Linkerd
1) Qué es Service Mesh y cuándo se necesita
Service Mesh es una capa de plano de datos/control de red que proporciona mTLS de extremo a extremo, enrutamiento, tolerancia a fallas y observabilidad entre servicios sin reescribir código.
Objetivos:- Seguridad predeterminada (confianza cero, identidad de servicios, política de acceso).
- Control de tráfico (Canary/Blue-Green, A/B, shadowing).
- Fiabilidad (retraídas, timeouts, circuit breaking).
- Observabilidad (métricas, registros, tracks).
- Estandarización operativa (políticas como código, GitOps).
- Muchos microservicios con la polilingüidad y el requisito del mTLS.
- Se necesitan escenarios avanzados de enrutamiento/experimentación sin cambiar la aplicación.
- Hay requisitos de auditoría/políticas a nivel de red.
2) Istio vs Linkerd - breve comparación
3) Arquitectura y modelos de implementación
3. 1 Sidecar mesh (clásico)
Cada Pod recibe un sidkar proxy.
Pros: madurez, control L7 completo.
Contras: sobrecarga de CPU/RAM, complicación de la depuración/depuración.
3. 2 Istio Ambient Mesh
ztunnel (L4) en el nodo + waypoint proxies (L7) según sea necesario.
Ventajas: menor coste y complejidad, incorporación gradual del L7.
Contras: más nuevo, no todos los casos L7 están disponibles sin waypoint.
4) Identidad y mTLS (confianza cero)
4. 1 SPIFFE/SPIRE y certificados
A cada worcload se le asigna un SPIFFE ID: 'spiffe ://cluster. local/ns/NS/sa/SA`.
Autenticación: TLS recíproco entre servicios.
Rotación de llaves - automáticamente (TTL corto).
4. 2 Istio (PeerAuthentication + DestinationRule)
yaml apiVersion: security. istio. io/v1 kind: PeerAuthentication metadata: { name: default, namespace: payments }
spec:
mtls: { mode: STRICT }
apiVersion: networking. istio. io/v1 kind: DestinationRule metadata: { name: payments-dr, namespace: payments }
spec:
host: payments. svc. cluster. local trafficPolicy:
tls: { mode: ISTIO_MUTUAL }
4. 3 Linkerd - mTLS predeterminado
Se activa después de 'linkerd install' +' linkerd inject '.
Los clústeres son su propio trust-anchor, la rotación es automática.
5) Gestión del tráfico
5. 1 Istio: Servicio Virtual (Rutas, Canarias)
yaml apiVersion: networking. istio. io/v1 kind: VirtualService metadata: { name: payments }
spec:
hosts: ["payments"]
http:
- route:
- destination: { host: payments, subset: v1 } # stable weight: 90
- destination: { host: payments, subset: v2 } # canary weight: 10 retries: { attempts: 2, perTryTimeout: 300ms }
timeout: 2s
DestinationRule (LB/CB):
yaml apiVersion: networking. istio. io/v1 kind: DestinationRule metadata: { name: payments }
spec:
host: payments subsets:
- name: v1 labels: { version: v1 }
- name: v2 labels: { version: v2 }
trafficPolicy:
loadBalancer: { simple: LEAST_CONN }
outlierDetection:
consecutive5xx: 5 interval: 5s baseEjectionTime: 30s maxEjectionPercent: 50
5. 2 Linkerd: ServiceProfile + TrafficSplit
yaml apiVersion: linkerd. io/v1alpha2 kind: ServiceProfile metadata:
name: payments. default. svc. cluster. local spec:
routes:
- name: POST /withdraw condition:
method: POST pathRegex: "/withdraw"
isRetryable: true timeout: 2s apiVersion: split. smi-spec. io/v1alpha2 kind: TrafficSplit metadata: { name: payments }
spec:
service: payments backends:
- service: payments-v1 weight: 90
- service: payments-v2 weight: 10
6) Ingress/Egress y pasarelas API
Istio Gateway (ingress/egress): controla el tráfico entrante/saliente, la terminación TLS, el passthrough mTLS.
Linkerd funciona con controladores de ingress existentes (NGINX/Contour/Traefik); egress - a través de NetworkPolicy/egress-gateway-patrones.
Políticas de egresos: listas blancas de dominios, política de SNI, prohibición de Internet directo.
7) Autorización y política
7. 1 Istio AuthorizationPolicy (RBAC/ABAC)
yaml apiVersion: security. istio. io/v1 kind: AuthorizationPolicy metadata: { name: allow-withdraw, namespace: payments }
spec:
selector: { matchLabels: { app: payments } }
action: ALLOW rules:
- from:
- source:
principals: ["spiffe://cluster. local/ns/api/sa/gateway"]
to:
- operation:
methods: ["POST"]
paths: ["/withdraw"]
when:
- key: request. auth. claims[role]
values: ["cashout"]
7. 2 Linkerd policy (server + serverauthorization)
yaml apiVersion: policy. linkerd. io/v1beta3 kind: Server metadata: { name: payments-server, namespace: payments }
spec:
podSelector: { matchLabels: { app: payments } }
port: 8080 apiVersion: policy. linkerd. io/v1beta3 kind: ServerAuthorization metadata: { name: allow-gateway, namespace: payments }
spec:
server: { name: payments-server }
client:
meshTLS:
identities: [".ns. api. serviceaccount. identity. linkerd. cluster. local"]
8) Observabilidad y telemetría
8. 1 Métricas
Istio Telemetry API → Prometheus: `istio_requests_total`, `istio_request_duration_milliseconds_bucket`, `istio_tcp_received_bytes_total`.
Linkerd viz: `request_total`, latency p50/p95/p99, `success_rate`.
8. 2 Tracks y logs
Coloque W3C Trace Context.
Istio/Envoy → OTLP в OpenTelemetry Collector; Linkerd - a través de los loggers sidecar/app-SDK.
8. 3 Instancias (Exemplars)
Agregue 'trace _ id' a los histogramas de duración para 'jump-to-trace'.
9) Rate limits, WAF, filtros personalizados
Istio: EnvoyFilter/WASM para rate limits locales, eksternal-rate-limit service (Redis), así como lógica WAF (Lua/WASM).
Linkerd: soporte nativo limitado; rate limit - en el nivel de entrada/puerta de enlace.
10) Multiplicidad
Istio: gateway east-west, PKI compartido o trust-bundle, servicio discovery a través de ServiceEntry, Federation.
Linkerd: `linkerd multicluster link`, gateway per cluster, service-mirror контроллер.
Use-cases: región activo-activo, localización de tráfico, zero-trust federado.
11) Rendimiento y costo
Mesh Sidecar: CPU/RAM sobrealimentado por cada Pod, latencia aumentada (generalmente + 1-3 ms por hop en steady-state).
Amb (Istio): menor consumo para L4, L7 se incluye puntualmente.
Linkerd: un proxy ligero tiende a ser menos overhead, pero menos capacidades extremas L7.
Práctica: mida el p95/CPU antes/después, mantenga las getas SLO en degradación.
12) Seguridad
mTLS en todas partes, TTL corto, rotación automática.
Policy as Code (OPA/Gatekeeper, Kyverno) para las prohibiciones 'authorizationPolicy: ALLOW all'.
Los secretos son a través de CSI/Vault, no en los manifiestos.
Control Egress: deny-by-default, hojas claras allow.
Dominios de confianza individuales para entornos (prod/stage).
13) Integración con lanzamientos y juegos SLO
Canary/Blue-Green son implementados por rutas mesh (ver ejemplos).
Análisis de métricas (Prometheus/SpanMetrics) en Argo Rollouts AnalysisTemplate - autoestop/retroceso en burn-rate/p95/5xx.
Anotaciones de lanzamientos en Grafana: comparación de 'version = stable' canary '.
14) Anti-patrones
Incluir mesh «en todas partes y a la vez» → choque de infraestructura.
Ignore la cardinalidad de las métricas/registros del proxy → la sobrecarga de TSDB/almacenamiento de información.
Dejar mTLS en el modo PERMISSIVE/opaque para siempre.
Intenta hacer una lógica WAF/business compleja dentro de EnvoyFilter en lugar de gateway/app.
No hay política de egresos - filtraciones en Internet/elusión de cumplimiento.
Proxy s ': 15000' debug abierto al exterior.
15) Lista de verificación de implementación (0-60 días)
0-15 días
Selección del modelo: Sidecar vs Amb (Istio )/Linkerd por perfil de carga.
Habilitar mTLS STRICT, las políticas básicas de autorización para 1-2 servicios críticos.
Rutas básicas (timeout/retries), dashboards RED/SLO.
16-30 días
Canary/TrafficSplit, outlier detection/circuit breaking on hot paths.
Integración OTEL: Tracks + Exemplars; alertas burn-rate.
Egress-gateways y listas blancas de dominios; deny-by-default.
31-60 días
Link multicapa (si es necesario), fideicomiso federativo.
Policy as Code на AuthorizationPolicy/ServerAuthorization.
Día de juego: simulación de incidentes y reversión de rutas/políticas.
16) Métricas de madurez
La cobertura de mTLS (STRICT/auto-rotate) ≥ el 95% de los servicios.
El porcentaje de tráfico a través de lanzamientos canarios/progresivos ≥ del 80%.
Media de sobremesa p95 <+ 5% de la línea base (después de la optimización).
0 egresos abiertos sin permiso, el 100% de los servicios con AuthZ básicos.
RCA «de horario en pista» ≤ 2 minutos (p50).
17) Ejemplos de «políticas como código»
Gatekeeper (prohibición de PERMISSIVE en la venta)
yaml apiVersion: constraints. gatekeeper. sh/v1beta1 kind: K8sIstiomTLSStrict metadata: { name: deny-permissive-prod }
spec:
match:
kinds: [{ apiGroups: ["security. istio. io"], kinds: ["PeerAuthentication"] }]
namespaces: ["prod-"]
parameters:
allowedModes: ["STRICT"]
Kyverno (labels obligatorios para VS/DR)
yaml apiVersion: kyverno. io/v1 kind: ClusterPolicy metadata: { name: require-mesh-labels }
spec:
rules:
- name: vs-dr-labels match:
any:
- resources:
kinds: ["VirtualService","DestinationRule"]
validate:
message: "owner and service labels required"
pattern:
metadata:
labels:
owner: "?"
service: "?"
18) Consejos de operación
Versionar políticas y rutas (semver), promoción a través de GitOps.
Observabilidad del proxy: dashboards individuales «proxy saturation» (CPU/heap, retries, 429/503).
Presupuesto de cardinalidad: las etiquetas 'route', 'code', 'destination' son sólo plantillas.
Límites de red/cuotas por nivel de namespace (NetworkPolicy/LimitRange).
Documentación de comandos: runbook «Cómo revertir rutas/políticas/claves mTLS».
19) Conclusión
Istio y Linkerd se enfrentan a un único desafío: estandarizar la seguridad, fiabilidad y visibilidad de las comunicaciones entre servicios, pero lo hacen con diferentes profundidades y costos de propiedad.
Se necesitan ricas capacidades de L7 y políticas flexibles: tome Istio (revise Amb para reducir las facturas).
Necesita simplicidad y un pequeño overhead - tome Linkerd.
Cualquiera que sea el mensaje que elija: active mTLS por defecto, administre el enrutamiento como código, vincule las métricas a las pistas, cierre el egreso, y agregue el juego de SLO a las versiones. Entonces la capa de red dejará de ser una «caja negra» y se convertirá en una herramienta predecible de estabilidad y velocidad de cambio.