Acceso a Services Externos
Debido a que todo el tráfico saliente de un pod habilitado para Istio se redirige a su proxy sidecar por defecto, la accesibilidad de las URLs fuera del cluster depende de la configuración del proxy. Por defecto, Istio configura el proxy Envoy para pasar las solicitudes a services desconocidos. Aunque esto proporciona una forma conveniente de empezar a usar Istio, configurar un control más estricto suele ser preferible.
Esta tarea le muestra cómo acceder a services externos de tres maneras diferentes:
- Permitir que el proxy Envoy pase las solicitudes a services que no están configurados dentro de la malla.
- Configurar entradas de service para proporcionar acceso controlado a services externos.
- Omitir completamente el proxy Envoy para un rango específico de IPs.
Antes de empezar
Configure Istio siguiendo las instrucciones de la guía de instalación. Utilice el perfil de configuración
demo
o, de lo contrario, habilite el registro de acceso de Envoy.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}')
Passthrough de Envoy a services externos
Istio tiene una opción de instalación,
meshConfig.outboundTrafficPolicy.mode
, que configura el manejo del sidecar
de services externos, es decir, aquellos services que no están definidos en el service registry interno de Istio.
Si esta opción se establece en ALLOW_ANY
, el proxy de Istio permite que las llamadas a services desconocidos pasen.
Si la opción se establece en REGISTRY_ONLY
, el proxy de Istio bloquea cualquier host sin un service HTTP o
una entrada de service definida dentro de la malla.
ALLOW_ANY
es el valor predeterminado, lo que le permite comenzar a evaluar Istio rápidamente,
sin controlar el acceso a services externos.
Luego puede decidir configurar el acceso a services externos más tarde.
Para ver este enfoque en acción, debe asegurarse de que su instalación de Istio esté configurada con la opción
meshConfig.outboundTrafficPolicy.mode
establecida enALLOW_ANY
. A menos que la haya establecido explícitamente en modoREGISTRY_ONLY
cuando instaló Istio, probablemente esté habilitada por defecto.Si no está seguro, puede ejecutar el siguiente comando para mostrar la configuración de su malla:
$ kubectl get configmap istio -n istio-system -o yaml
A menos que vea una configuración explícita de
meshConfig.outboundTrafficPolicy.mode
con el valorREGISTRY_ONLY
, puede estar seguro de que la opción está establecida enALLOW_ANY
, que es el único otro valor posible y el predeterminado.Realice un par de solicitudes a services HTTPS externos desde el
SOURCE_POD
para confirmar respuestas200
exitosas:$ kubectl exec "$SOURCE_POD" -c curl -- curl -sSI https://www.google.com | grep "HTTP/"; kubectl exec "$SOURCE_POD" -c curl -- curl -sI https://edition.cnn.com | grep "HTTP/" HTTP/2 200 HTTP/2 200
¡Felicidades! Ha enviado tráfico de salida desde su malla con éxito.
Este enfoque simple para acceder a services externos tiene el inconveniente de que se pierde el monitoreo y control de Istio para el tráfico a services externos. La siguiente sección le muestra cómo monitorear y controlar el acceso de su malla a services externos.
Acceso controlado a services externos
Utilizando las configuraciones de ServiceEntry
de Istio, puede acceder a cualquier service accesible públicamente
desde dentro de su cluster de Istio. Esta sección le muestra cómo configurar el acceso a un service HTTP externo,
httpbin.org, así como a un service HTTPS externo,
www.google.com sin perder las features de monitoreo y control de tráfico de Istio.
Cambiar a la política de bloqueo por defecto
Para demostrar la forma controlada de habilitar el acceso a services externos, debe cambiar la opción
meshConfig.outboundTrafficPolicy.mode
del modo ALLOW_ANY
al modo REGISTRY_ONLY
.
Cambie la opción
meshConfig.outboundTrafficPolicy.mode
aREGISTRY_ONLY
.Si utilizó una configuración de
IstioOperator
para instalar Istio, agregue el siguiente campo a su configuración:spec: meshConfig: outboundTrafficPolicy: mode: REGISTRY_ONLY
De lo contrario, agregue la configuración equivalente a su comando
istioctl install
original, por ejemplo:$ istioctl install <flags-you-used-to-install-Istio> \ --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
Realice un par de solicitudes a services HTTPS externos desde
SOURCE_POD
para verificar que ahora están bloqueados:$ kubectl exec "$SOURCE_POD" -c curl -- curl -sI https://www.google.com | grep "HTTP/"; kubectl exec "$SOURCE_POD" -c curl -- curl -sI https://edition.cnn.com | grep "HTTP/" command terminated with exit code 35 command terminated with exit code 35
Acceder a un service HTTP externo
Cree una
ServiceEntry
para permitir el acceso a un service HTTP externo.$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: httpbin-ext spec: hosts: - httpbin.org ports: - number: 80 name: http protocol: HTTP resolution: DNS location: MESH_EXTERNAL EOF
Realice una solicitud al service HTTP externo desde
SOURCE_POD
:$ kubectl exec "$SOURCE_POD" -c curl -- curl -sS http://httpbin.org/headers { "headers": { "Accept": "*/*", "Host": "httpbin.org", ... "X-Envoy-Decorator-Operation": "httpbin.org:80/*", ... } }
Observe las cabeceras agregadas por el proxy sidecar de Istio:
X-Envoy-Decorator-Operation
.Verifique el registro del proxy sidecar de
SOURCE_POD
:$ kubectl logs "$SOURCE_POD" -c istio-proxy | tail [2019-01-24T12:17:11.640Z] "GET /headers HTTP/1.1" 200 - 0 599 214 214 "-" "curl/7.60.0" "17fde8f7-fa62-9b39-8999-302324e6def2" "httpbin.org" "35.173.6.94:80" outbound|80||httpbin.org - 35.173.6.94:80 172.30.109.82:55314 -
Observe la entrada relacionada con su solicitud HTTP a
httpbin.org/headers
.
Acceder a un service HTTPS externo
Cree una
ServiceEntry
para permitir el acceso a un service HTTPS externo.$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: google spec: hosts: - www.google.com ports: - number: 443 name: https protocol: HTTPS resolution: DNS location: MESH_EXTERNAL EOF
Realice una solicitud al service HTTPS externo desde
SOURCE_POD
:$ kubectl exec "$SOURCE_POD" -c curl -- curl -sSI https://www.google.com | grep "HTTP/" HTTP/2 200
Verifique el registro del proxy sidecar de
SOURCE_POD
:$ kubectl logs "$SOURCE_POD" -c istio-proxy | tail [2019-01-24T12:48:54.977Z] "- - -" 0 - 601 17766 1289 - "-" "-" "-" "-" "172.217.161.36:443" outbound|443||www.google.com 172.30.109.82:59480 172.217.161.36:443 172.30.109.82:59478 www.google.com
Observe la entrada relacionada con su solicitud HTTPS a
www.google.com
.
Gestionar el tráfico a services externos
De forma similar a las solicitudes entre clusters, las reglas de enrutamiento
también se pueden configurar para services externos a los que se accede mediante configuraciones de ServiceEntry
.
En este ejemplo, se establece una regla de tiempo de espera en las llamadas al service httpbin.org
.
Desde dentro del pod que se utiliza como fuente de prueba, realice una solicitud curl al endpoint
/delay
del service externo httpbin.org:$ kubectl exec "$SOURCE_POD" -c curl -- time curl -o /dev/null -sS -w "%{\http_code}\n" http://httpbin.org/delay/5 200 real 0m5.024s user 0m0.003s sys 0m0.003s
La solicitud debería devolver 200 (OK) en aproximadamente 5 segundos.
Use
kubectl
para establecer un tiempo de espera de 3s en las llamadas al service externohttpbin.org
:
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
http:
- timeout: 3s
route:
- destination:
host: httpbin.org
weight: 100
EOF
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-ext
spec:
parentRefs:
- kind: ServiceEntry
group: networking.istio.io
name: httpbin-ext
hostnames:
- httpbin.org
rules:
- timeouts:
request: 3s
backendRefs:
- kind: Hostname
group: networking.istio.io
name: httpbin.org
port: 80
EOF
Espere unos segundos, luego realice la solicitud curl nuevamente:
$ kubectl exec "$SOURCE_POD" -c curl -- time curl -o /dev/null -sS -w "%{\http_code}\n" http://httpbin.org/delay/5 504 real 0m3.149s user 0m0.004s sys 0m0.004s
Esta vez aparece un 504 (Gateway Timeout) después de 3 segundos. Aunque httpbin.org estaba esperando 5 segundos, Istio cortó la solicitud a los 3 segundos.
Limpieza del acceso controlado a services externos
$ kubectl delete serviceentry httpbin-ext google
$ kubectl delete virtualservice httpbin-ext --ignore-not-found=true
$ kubectl delete serviceentry httpbin-ext
$ kubectl delete httproute httpbin-ext --ignore-not-found=true
Acceso directo a services externos
Si desea omitir completamente Istio para un rango de IP específico,
puede configurar los sidecars de Envoy para evitar que
intercepten
las solicitudes externas. Para configurar la omisión, cambie global.proxy.includeIPRanges
o global.proxy.excludeIPRanges
opción de configuración y
actualice el mapa de configuración istio-sidecar-injector
usando el comando kubectl apply
. Esto también
se puede configurar en un pod estableciendo las anotaciones correspondientes, como
traffic.sidecar.istio.io/includeOutboundIPRanges
.
Después de actualizar la configuración de istio-sidecar-injector
, afecta a todos
los futuros despliegues de pods de aplicación.
Una forma sencilla de excluir todas las IPs externas de ser redirigidas al proxy sidecar es
establecer la opción de configuración global.proxy.includeIPRanges
en el rango o rangos de IP
utilizados para los services internos del cluster.
Estos valores de rango de IP dependen de la plataforma donde se ejecuta su cluster.
Determinar los rangos de IP internos para su plataforma
Establezca el valor de values.global.proxy.includeIPRanges
de acuerdo con su proveedor de cluster.
IBM Cloud Private
Obtenga su
service_cluster_ip_range
del fichero de configuración de IBM Cloud Private encluster/config.yaml
:$ grep service_cluster_ip_range cluster/config.yaml
La siguiente es una salida de ejemplo:
service_cluster_ip_range: 10.0.0.1/24
Use `–set values.global.proxy.includeIPRanges=“10.0.0.1/24”
IBM Cloud Kubernetes Service
Para ver qué CIDR se utiliza en el cluster, use ibmcloud ks cluster get -c <CLUSTER-NAME>
y busque el Service Subnet
:
$ ibmcloud ks cluster get -c my-cluster | grep "Service Subnet"
Service Subnet: 172.21.0.0/16
Luego use `–set values.global.proxy.includeIPRanges=“172.21.0.0/16”
Google Kubernetes Engine (GKE)
Los rangos no son fijos, por lo que deberá ejecutar el comando gcloud container clusters describe
para determinar los
rangos a usar. Por ejemplo:
$ gcloud container clusters describe XXXXXXX --zone=XXXXXX | grep -e clusterIpv4Cidr -e servicesIpv4Cidr
clusterIpv4Cidr: 10.4.0.0/14
servicesIpv4Cidr: 10.7.240.0/20
Use `–set values.global.proxy.includeIPRanges=“10.4.0.0/14,10.7.240.0/20”
Azure Kubernetes Service (AKS)
Kubenet
Para ver qué CIDR de service y CIDR de pod se utilizan en el cluster, use az aks show
y busque el serviceCidr
:
$ az aks show --resource-group "${RESOURCE_GROUP}" --name "${CLUSTER}" | grep Cidr
"podCidr": "10.244.0.0/16",
"podCidrs": [
"serviceCidr": "10.0.0.0/16",
"serviceCidrs": [
Luego use `–set values.global.proxy.includeIPRanges=“10.244.0.0/16,10.0.0.0/16”
Azure CNI
Siga estos pasos si está utilizando Azure CNI con un modo de red sin superposición. Si utiliza Azure CNI con red de superposición, siga las instrucciones de Kubenet. Para obtener más información, consulte la documentación de Azure CNI Overlay.
Para ver qué CIDR de service se utiliza en el cluster, use az aks show
y busque el serviceCidr
:
$ az aks show --resource-group "${RESOURCE_GROUP}" --name "${CLUSTER}" | grep serviceCidr
"serviceCidr": "10.0.0.0/16",
"serviceCidrs": [
Para ver qué CIDR de pod se utiliza en el cluster, use la CLI de az
para inspeccionar la vnet
:
$ az aks show --resource-group "${RESOURCE_GROUP}" --name "${CLUSTER}" | grep nodeResourceGroup
"nodeResourceGroup": "MC_user-rg_user-cluster_region",
"nodeResourceGroupProfile": null,
$ az network vnet list -g MC_user-rg_user-cluster_region | grep name
"name": "aks-vnet-74242220",
"name": "aks-subnet",
$ az network vnet show -g MC_user-rg_user-cluster_region -n aks-vnet-74242220 | grep addressPrefix
"addressPrefixes": [
"addressPrefix": "10.224.0.0/16",
Luego use `–set values.global.proxy.includeIPRanges=“10.244.0.0/16,10.0.0.0/16”
Minikube, Docker For Desktop, Bare Metal
El valor predeterminado es 10.96.0.0/12
, pero no es fijo. Use el siguiente comando para determinar su valor real:
$ kubectl describe pod kube-apiserver -n kube-system | grep 'service-cluster-ip-range'
--service-cluster-ip-range=10.96.0.0/12
Use `–set values.global.proxy.includeIPRanges=“10.96.0.0/12”
Configuración de la omisión del proxy
Actualice su mapa de configuración istio-sidecar-injector
utilizando los rangos de IP específicos de su plataforma.
Por ejemplo, si el rango es 10.0.0.1/24, use el siguiente comando:
$ istioctl install <flags-you-used-to-install-Istio> --set values.global.proxy.includeIPRanges="10.0.0.1/24"
Use el mismo comando que usó para instalar Istio y agregue `–set values.global.proxy.includeIPRanges=“10.0.0.1/24”
Acceder a los services externos
Debido a que la configuración de omisión solo afecta a los nuevos despliegues, debe terminar y luego volver a desplegar la aplicación curl
como se describe en la sección Antes de empezar.
Después de actualizar el configmap istio-sidecar-injector
y volver a desplegar la aplicación curl
,
el sidecar de Istio solo interceptará y gestionará las solicitudes internas
dentro del cluster. Cualquier solicitud externa omite el sidecar y va directamente a su destino previsto.
Por ejemplo:
$ kubectl exec "$SOURCE_POD" -c curl -- curl -sS http://httpbin.org/headers
{
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
...
}
}
Unlike accessing external services through HTTP or HTTPS, you don’t see any headers related to the Istio sidecar and the requests sent to external services do not appear in the log of the sidecar. Bypassing the Istio sidecars means you can no longer monitor the access to external services.
Limpieza del acceso directo a services externos
Actualice la configuración para dejar de omitir los proxies sidecar para un rango de IPs:
$ istioctl install <flags-you-used-to-install-Istio>
Comprender lo que sucedió
En esta tarea, examinó tres formas de llamar a services externos desde una malla de Istio:
Configurar Envoy para permitir el acceso a cualquier service externo.
Usar una entrada de service para registrar un service externo accesible dentro de la malla. Este es el enfoque recomendado.
Configurar el sidecar de Istio para excluir IPs externas de su tabla de IPs remapeadas.
El primer enfoque dirige el tráfico a través del proxy sidecar de Istio, incluidas las llamadas a services desconocidos dentro de la malla. Al usar este enfoque, no puede monitorear el acceso a services externos ni aprovechar las features de control de tráfico de Istio para ellos. Para cambiar fácilmente al segundo enfoque para services específicos, simplemente cree entradas de service para esos services externos. Este proceso le permite acceder inicialmente a cualquier service externo y luego decidir si desea o no controlar el acceso, habilitar el monitoreo de tráfico y usar las features de control de tráfico según sea necesario.
El segundo enfoque le permite usar todas las mismas features de service mesh de Istio para llamadas a services dentro o fuera del cluster. En esta tarea, aprendió cómo monitorear el acceso a services externos y establecer una regla de tiempo de espera para las llamadas a un service externo.
El tercer enfoque omite el proxy sidecar de Istio, dando a sus services acceso directo a cualquier servidor externo. Sin embargo, configurar el proxy de esta manera requiere conocimientos y configuración específicos del proveedor del cluster. De manera similar al primer enfoque, también pierde el monitoreo del acceso a services externos y no puede aplicar las features de Istio al tráfico a services externos.
Nota de seguridad
Para implementar el control de tráfico de salida de una manera más segura, debe dirigir el tráfico de salida a través de un egress gateway y revisar las preocupaciones de seguridad descritas en la sección consideraciones de seguridad adicionales.
Limpieza
Apague el service curl:
$ kubectl delete -f @samples/curl/curl.yaml@