Salida usando Wildcard Hosts
La tarea Acceso a Services Externos y
el ejemplo Configurar un Egress Gateway
describen cómo configurar el tráfico de salida para hostnames específicos, como edition.cnn.com
.
Este ejemplo muestra cómo habilitar el tráfico de salida para un conjunto de hosts en un dominio común, por
ejemplo *.wikipedia.org
, en lugar de configurar cada host por separado.
Antecedentes
Suponga que desea habilitar el tráfico de salida en Istio para los sitios wikipedia.org
en todos los idiomas.
Cada versión de wikipedia.org
en un idioma particular tiene su propio hostname, por ejemplo, en.wikipedia.org
y
de.wikipedia.org
en inglés y alemán, respectivamente.
Desea habilitar el tráfico de salida mediante elementos de configuración comunes para todos los sitios de Wikipedia,
sin necesidad de especificar cada sitio de idioma por separado.
Antes de empezar
- Instale Istio con el registro de acceso habilitado y con la política de tráfico de salida de bloqueo por defecto:
$ istioctl install --set profile=demo --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
$ istioctl install --set profile=minimal -y \
--set values.pilot.env.PILOT_ENABLE_ALPHA_GATEWAY_API=true \
--set meshConfig.accessLogFile=/dev/stdout \
--set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
Despliegue la aplicación de ejemplo curl para usarla como fuente de prueba para enviar solicitudes. Si tiene la inyección automática de sidecar habilitada, ejecute el siguiente comando para desplegar la aplicación de ejemplo:
$ kubectl apply -f @samples/curl/curl.yaml@
De lo contrario, inyecte manualmente el sidecar antes de desplegar la aplicación
curl
con el siguiente comando:$ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@)
Establezca la variable de entorno
SOURCE_POD
con el nombre de su pod de origen:$ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath={.items..metadata.name})
Configurar el tráfico directo a un host wildcard
La primera y más sencilla forma de acceder a un conjunto de hosts dentro de un dominio común es configurando
una ServiceEntry
simple con un host wildcard y llamando a los services directamente desde el sidecar.
Al llamar a los services directamente (es decir, no a través de un egress gateway), la configuración para
un host wildcard no es diferente a la de cualquier otro host (por ejemplo, completamente calificado),
solo mucho más conveniente cuando hay muchos hosts dentro del dominio común.
Defina una
ServiceEntry
para*.wikipedia.org
:$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: wikipedia spec: hosts: - "*.wikipedia.org" ports: - number: 443 name: https protocol: HTTPS EOF
Envíe solicitudes HTTPS a https://en.wikipedia.org y https://de.wikipedia.org:
$ kubectl exec "$SOURCE_POD" -c curl -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://de.wikipedia.org/wiki/Wikipedia:Hauptseite | grep -o "<title>.*</title>"' <title>Wikipedia, la enciclopedia libre</title> <title>Wikipedia – Die freie Enzyklopädie</title>
Limpieza del tráfico directo a un host wildcard
$ kubectl delete serviceentry wikipedia
Configurar el tráfico del egress gateway a un host wildcard
Cuando todos los hosts wildcard son atendidos por un solo servidor, la configuración para el acceso basado en egress gateway a un host wildcard es muy similar a la de cualquier host, con una excepción: el destino de ruta configurado no será el mismo que el host configurado, es decir, el wildcard. En su lugar, se configurará con el host del único servidor para el conjunto de dominios.
- Cree un
Gateway
de salida para *.wikipedia.org y reglas de ruta para dirigir el tráfico a través del egress gateway y desde el egress gateway al service externo:
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: istio-egressgateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*.wikipedia.org"
tls:
mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: egressgateway-for-wikipedia
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: wikipedia
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: direct-wikipedia-through-egress-gateway
spec:
hosts:
- "*.wikipedia.org"
gateways:
- mesh
- istio-egressgateway
tls:
- match:
- gateways:
- mesh
port: 443
sniHosts:
- "*.wikipedia.org"
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
subset: wikipedia
port:
number: 443
weight: 100
- match:
- gateways:
- istio-egressgateway
port: 443
route:
- destination:
host: www.wikipedia.org
port:
number: 443
weight: 100
EOF
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: wikipedia-egress-gateway
annotations:
networking.istio.io/service-type: ClusterIP
spec:
gatewayClassName: istio
listeners:
- name: tls
hostname: "*.wikipedia.org"
port: 443
protocol: TLS
tls:
mode: Passthrough
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: direct-wikipedia-to-egress-gateway
spec:
parentRefs:
- kind: ServiceEntry
group: networking.istio.io
name: wikipedia
rules:
- backendRefs:
- name: wikipedia-egress-gateway-istio
port: 443
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: forward-wikipedia-from-egress-gateway
spec:
parentRefs:
- name: wikipedia-egress-gateway
hostnames:
- "*.wikipedia.org"
rules:
- backendRefs:
- kind: Hostname
group: networking.istio.io
name: www.wikipedia.org
port: 443
---
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: wikipedia
spec:
hosts:
- "*.wikipedia.org"
ports:
- number: 443
name: https
protocol: HTTPS
EOF
Cree una
ServiceEntry
para el servidor de destino, www.wikipedia.org:$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: www-wikipedia spec: hosts: - www.wikipedia.org ports: - number: 443 name: https protocol: HTTPS resolution: DNS EOF
Envíe solicitudes HTTPS a https://en.wikipedia.org y https://de.wikipedia.org:
$ kubectl exec "$SOURCE_POD" -c curl -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://de.wikipedia.org/wiki/Wikipedia:Hauptseite | grep -o "<title>.*</title>"' <title>Wikipedia, la enciclopedia libre</title> <title>Wikipedia – Die freie Enzyklopädie</title>
Verifique las estadísticas del proxy del egress gateway para el contador que corresponde a sus solicitudes a *.wikipedia.org:
$ kubectl exec "$(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}')" -c istio-proxy -n istio-system -- pilot-agent request GET clusters | grep '^outbound|443||www.wikipedia.org.*cx_total:'
outbound|443||www.wikipedia.org::208.80.154.224:443::cx_total::2
$ kubectl exec "$(kubectl get pod -l gateway.networking.k8s.io/gateway-name=wikipedia-egress-gateway -o jsonpath='{.items[0].metadata.name}')" -c istio-proxy -- pilot-agent request GET clusters | grep '^outbound|443||www.wikipedia.org.*cx_total:'
outbound|443||www.wikipedia.org::208.80.154.224:443::cx_total::2
Limpieza del tráfico del egress gateway a un host wildcard
$ kubectl delete serviceentry www-wikipedia
$ kubectl delete gateway istio-egressgateway
$ kubectl delete virtualservice direct-wikipedia-through-egress-gateway
$ kubectl delete destinationrule egressgateway-for-wikipedia
$ kubectl delete se wikipedia
$ kubectl delete se www-wikipedia
$ kubectl delete gtw wikipedia-egress-gateway
$ kubectl delete tlsroute direct-wikipedia-to-egress-gateway
$ kubectl delete tlsroute forward-wikipedia-from-egress-gateway
Configuración de comodines para dominios arbitrarios
La configuración de la sección anterior funcionó porque todos los sitios *.wikipedia.org
pueden ser servidos por cualquiera
de los servidores wikipedia.wikipedia.org
. Sin embargo, este no siempre es el caso. Por ejemplo, es posible que desee configurar el control de salida
para el acceso a dominios wildcard más generales como *.com
o *.org
. La configuración del tráfico a dominios wildcard arbitrarios
introduce un desafío para los gateways de Istio; un gateway de Istio solo se puede configurar para enrutar el tráfico
a hosts predefinidos, direcciones IP predefinidas o a la dirección IP de destino original de la solicitud.
En la sección anterior, configuró el virtual service para dirigir el tráfico al host predefinido www.wikipedia.org
.
En el caso general, sin embargo, no conoce el host o la dirección IP que puede servir a un host arbitrario recibido en una
solicitud, lo que deja la dirección de destino original de la solicitud como el único valor con el que enrutar la solicitud.
Desafortunadamente, al usar un egress gateway, la dirección de destino original de la solicitud se pierde ya que la solicitud original
se redirige al gateway, lo que hace que la dirección IP de destino se convierta en la dirección IP del gateway.
Aunque no es tan fácil y algo frágil, ya que se basa en los detalles de implementación de Istio, puede usar filtros de Envoy para configurar un gateway para admitir dominios arbitrarios utilizando el valor SNI en una solicitud HTTPS, o cualquier TLS, para identificar el destino original al que enrutar la solicitud. Un ejemplo de este enfoque de configuración se puede encontrar en enrutamiento del tráfico de salida a destinos wildcard.
Limpieza
Apague el service curl:
$ kubectl delete -f @samples/curl/curl.yaml@
Desinstale Istio de su cluster:
$ istioctl uninstall --purge -y