Visibilidad de ServiceEntry
Un ServiceEntry agrega un servicio al registro interno de servicios de Istio. De forma predeterminada, un ServiceEntry es visible para todos los workloads de la mesh: cualquiera que pueda crear un ServiceEntry en cualquier namespace puede definir cualquier nombre de host —por ejemplo example.com— e impactar en cómo toda la mesh lo resuelve y enruta.
El campo exportTo no protege contra esto, porque lo declara el propio autor del ServiceEntry: permite que el propietario de un servicio delimite lo que publica, pero no impone ninguna restricción firme. Históricamente, un administrador de la mesh necesitaría restringir la creación de ServiceEntry con un control de admisión externo, como un ValidatingAdmissionPolicy o un webhook de Kubernetes.
A partir de Istio 1.31, la configuración de mesh serviceEntryVisibility le da al administrador de la mesh ese control desde un único lugar. El data plane ambient (ztunnel y waypoints) respeta la visibilidad siempre que esté configurada; los sidecars y gateways pueden habilitarla de forma explícita. La característica es inerte a menos que se configure: si serviceEntryVisibility no está establecido, nada cambia.
El diseño refleja deliberadamente un patrón familiar de Kubernetes: un RoleBinding solo tiene efecto dentro de su propio namespace, mientras que crear un efecto a nivel de clúster con un ClusterRoleBinding está reservado para los administradores del clúster. serviceEntryVisibility le permite al administrador de la mesh aplicar el mismo modelo a ServiceEntry: al establecer defaultVisibility: NAMESPACE, un administrador hace que cada ServiceEntry se comporte como cualquier otro recurso delimitado por namespace, y la visibilidad más allá del propio namespace de un ServiceEntry se convierte en una capacidad que el administrador otorga explícitamente.
Cómo se resuelve la visibilidad
Cuando serviceEntryVisibility está configurado, istiod resuelve una visibilidad para cada ServiceEntry:
- La lista
policiesse evalúa en orden. La primera política cuyasmatchingRulescoincidan todas (semántica AND) determina la visibilidad. - Si ninguna política coincide, se aplica
defaultVisibility.
Hoy, la única regla de coincidencia es namespaceSelector: un selector de etiquetas estándar de Kubernetes evaluado contra las etiquetas del namespace en el que está definido el ServiceEntry.
Un ServiceEntry se resuelve en una de tres visibilidades:
| Visibilidad | Significado |
|---|---|
PUBLIC | Visible para todos los workloads conectados a este control plane. Este es el comportamiento existente, y el predeterminado cuando defaultVisibility no está establecido. |
NAMESPACE | Visible únicamente dentro del namespace en el que está definido el ServiceEntry. |
NONE | No es visible para nadie: el ServiceEntry se puede escribir, pero Istio no configura ningún data plane para él. Útil para prohibir expresamente una clase de ServiceEntry. |
Consulta la referencia de configuración de mesh para la documentación completa de los campos.
Configurar la visibilidad
La siguiente configuración mantiene cada ServiceEntry privado dentro de su propio namespace, mientras permite que los recursos ServiceEntry en istio-system —un namespace en el que solo puede escribir el administrador de la mesh— se publiquen a toda la mesh:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
serviceEntryVisibility:
# ServiceEntries matching no policy below stay in their own namespace.
defaultVisibility: NAMESPACE
policies:
# ServiceEntries in istio-system are visible mesh-wide.
- visibility: PUBLIC
matchingRules:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: istio-systemLas políticas también pueden otorgar visibilidad a grupos de namespaces. Por ejemplo, una política que coincida con una etiqueta de namespace trusted: "true" te permite delegar la capacidad de publicar recursos ServiceEntry de toda la mesh etiquetando namespaces.
Visibilidad en modo ambient
Cuando serviceEntryVisibility está configurado, el data plane ambient siempre lo respeta. Istiod resuelve la visibilidad de cada ServiceEntry y la distribuye junto con la definición del servicio; ztunnel luego la aplica del lado del cliente, en función del namespace del workload que realiza la solicitud:
- Un servicio
PUBLICse comporta exactamente como antes. - Un servicio
NAMESPACEpuede ser descubierto y resuelto por workloads en su propio namespace. Para workloads en cualquier otro namespace, es como si elServiceEntryno existiera. - Un servicio
NONEnunca se entrega a ningún data plane en absoluto.
Oculto significa ausente, no bloqueado
Esto es deliberado: si ztunnel en su lugar fallara las consultas DNS para los nombres de host ocultos, un ServiceEntry que reclamara example.com en un namespace rompería example.com para toda la mesh, exactamente el problema que esta característica existe para controlar. En concreto, para un cliente fuera del namespace del ServiceEntry:
- DNS: una consulta para el nombre de host oculto se reenvía al resolvedor upstream, devolviendo la respuesta real (o un
NXDOMAINreal si el nombre no existe públicamente). - Direcciones: el tráfico hacia una dirección IP que solo reclama un
ServiceEntryoculto se trata como tráfico desconocido y se pasa a su destino original. - Nombres de host compartidos: si un
ServiceEntryoculto y unoPUBLICdefinen el mismo nombre de host, los clientes fuera del namespace de la entrada oculta siempre son atendidos por la definiciónPUBLIC.
Waypoints
Adjuntar un waypoint de otro namespace a un ServiceEntry con visibilidad NAMESPACE permitiría que el tráfico y la configuración escaparan del límite del namespace, por lo que el control plane rechaza los enlaces de waypoint entre namespaces para ellos. El rechazo se reporta en el estado del ServiceEntry con la condición istio.io/WaypointBound: False y el motivo CrossNamespaceWaypointForbidden.
Enlazar un waypoint en el mismo namespace funciona normalmente, y los recursos ServiceEntry PUBLIC no se ven afectados.
Extender la visibilidad a sidecars y gateways
En modo sidecar, los propietarios de servicios ya delimitan sus recursos ServiceEntry con exportTo, por lo que respetar la visibilidad es opcional para los sidecars, lo que permite una adopción incremental durante una migración a ambient sin cambiar un despliegue sidecar que ya funciona:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
serviceEntryVisibility:
defaultVisibility: NAMESPACE
applyToSidecars: trueCon applyToSidecars habilitado, la visibilidad resuelta actúa como un límite máximo sobre el exportTo del ServiceEntry: el alcance efectivo es la intersección del exportTo declarado y la visibilidad resuelta. A pesar del nombre del campo, esto se aplica a todos los proxies basados en Envoy, incluidos los gateways de ingress y egress.
La visibilidad puede reducir lo que declara exportTo, pero nunca lo amplía. En modo sidecar, exportTo es un mecanismo de delimitación de configuración que controla cuánta configuración envía istiod a cada proxy. Ampliarlo para que coincida con una visibilidad más amplia empujaría la configuración de un ServiceEntry de vuelta a proxies de los que su propietario lo había excluido deliberadamente. Por lo tanto, la visibilidad siempre es solo un límite máximo: un ServiceEntry con un exportTo más estrecho que su visibilidad mantiene su alcance más estrecho.
Verificar la visibilidad
Cuando serviceEntryVisibility está configurado, istiod reporta la visibilidad que recibió el data plane como una condición de estado del ServiceEntry de tipo istio.io/VisibilityApplied, con el motivo indicando la visibilidad aplicada:
$ kubectl get serviceentry my-service -n team-a -o jsonpath='{.status.conditions[?(@.type=="istio.io/VisibilityApplied")].reason}'
NamespaceEl estado de la condición siempre es True; el campo reason lleva la visibilidad resuelta (Public o Namespace). Cuando serviceEntryVisibility no está configurado, la condición no se escribe.
También puedes inspeccionar la visibilidad que ztunnel está aplicando para cada servicio que conoce. Las salidas en JSON y YAML de istioctl ztunnel-config service incluyen un campo visibility:
$ istioctl ztunnel-config service --service-namespace team-a -o yamlLos Service de Kubernetes siempre reportan Public; los servicios respaldados por ServiceEntry reportan su visibilidad resuelta. Además, ztunnel registra a nivel debug cada vez que oculta un servicio a un cliente durante la resolución.
Qué no hace la visibilidad
- La visibilidad no es autorización. La visibilidad controla si un cliente puede descubrir y resolver un servicio; no decide si se permite una solicitud entrante. Usa
AuthorizationPolicypara controlar qué clientes pueden acceder a un workload; consulta Política de seguridad de capa 4. - La visibilidad no es secreto. Reducir la visibilidad de un
ServiceEntryrige lo que resuelven los workloads cliente; no oculta la existencia del servicio. El recurso permanece legible a través de la API de Kubernetes según el RBAC, y el servicio sigue apareciendo en los volcados de configuración del data plane, comoistioctl ztunnel-config service. - Solo se aplica a
ServiceEntry. LosServicede Kubernetes siempre son visibles en toda la mesh en modo ambient. - No hay un modo de auditoría o de solo advertencia. Cuando está configurada, la visibilidad siempre tiene efecto.
Ver también
- Referencia de configuración de mesh
ServiceEntryVisibility - Delimitación de configuración —
exportToySidecarpara el modo sidecar, además dediscoverySelectors, que se aplican en todos los modos de data plane - Proxying de DNS
- Configurar proxies waypoint