Services de Kubernetes para Tráfico de Salida
Los services ExternalName de Kubernetes y los services de Kubernetes con
Endpoints
le permiten crear un alias DNS local para un service externo.
Este alias DNS tiene la misma forma que las entradas DNS para services locales, a saber,
<nombre del service>.<nombre del namespace>.svc.cluster.local. Los alias DNS proporcionan transparencia de ubicación para sus workloads:
los workloads pueden llamar a services locales y externos de la misma manera. Si en algún momento decide desplegar el
service externo dentro de su cluster, puede simplemente actualizar su service de Kubernetes para que haga referencia a la versión local. Los workloads seguirán funcionando sin ningún cambio.
Esta tarea muestra que estos mecanismos de Kubernetes para acceder a services externos siguen funcionando con Istio. El único paso de configuración que debe realizar es usar un modo TLS diferente al mTLS de Istio. Los services externos no forman parte de una service mesh de Istio, por lo que no pueden realizar el mTLS de Istio. Debe configurar el modo TLS de acuerdo con los requisitos TLS del service externo y de acuerdo con la forma en que su workload accede al service externo. Si su workload emite solicitudes HTTP planas y el service externo requiere TLS, es posible que desee realizar la TLS origination por Istio. Si su workload ya utiliza TLS, el tráfico ya está cifrado y simplemente puede deshabilitar el mTLS de Istio.
Aunque los ejemplos de esta tarea utilizan protocolos HTTP, los Services de Kubernetes para tráfico de salida también funcionan con otros protocolos.
Antes de empezar
Configura Istio siguiendo las instrucciones de la Guía de instalación.
Despliega la aplicación de ejemplo curl para usarla como fuente de prueba para enviar solicitudes. Si tienes habilitada la inyección automática de sidecar , ejecuta el siguiente comando para desplegar la aplicación de ejemplo:
$ kubectl apply -f @samples/curl/curl.yaml@De lo contrario, inyecta manualmente el sidecar antes de desplegar la aplicación
curlcon el siguiente comando:$ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@)Establece la variable de entorno
SOURCE_PODcon el nombre de tu pod de origen:$ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath={.items..metadata.name})
Cree un namespace para un pod de origen sin control de Istio:
$ kubectl create namespace without-istioInicie la muestra curl en el namespace
without-istio.$ kubectl apply -f @samples/curl/curl.yaml@ -n without-istioPara enviar solicitudes, cree la variable de entorno
SOURCE_POD_WITHOUT_ISTIOpara almacenar el nombre del pod de origen:$ export SOURCE_POD_WITHOUT_ISTIO="$(kubectl get pod -n without-istio -l app=curl -o jsonpath={.items..metadata.name})"Verifique que el sidecar de Istio no fue inyectado, es decir, que el pod tiene un solo contenedor:
$ kubectl get pod "$SOURCE_POD_WITHOUT_ISTIO" -n without-istio NAME READY STATUS RESTARTS AGE curl-66c8d79ff5-8tqrl 1/1 Running 0 32s
Service ExternalName de Kubernetes para acceder a un service externo
Cree un service ExternalName de Kubernetes para
httpbin.orgen el namespace predeterminado:$ kubectl apply -f - <<EOF kind: Service apiVersion: v1 metadata: name: my-httpbin spec: type: ExternalName externalName: httpbin.org ports: - name: http protocol: TCP port: 80 EOFObserve su service. Tenga en cuenta que no tiene una IP de cluster.
$ kubectl get svc my-httpbin NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-httpbin ExternalName <none> httpbin.org 80/TCP 4sAcceda a
httpbin.orga través del hostname del service de Kubernetes desde el pod de origen sin sidecar de Istio. Tenga en cuenta que el comando curl a continuación utiliza el formato DNS de Kubernetes para services:<nombre del service>.<namespace>.svc.cluster.local.$ kubectl exec "$SOURCE_POD_WITHOUT_ISTIO" -n without-istio -c curl -- curl -sS my-httpbin.default.svc.cluster.local/headers { "headers": { "Accept": "*/*", "Host": "my-httpbin.default.svc.cluster.local", "User-Agent": "curl/7.55.0" } }En este ejemplo, se envían solicitudes HTTP sin cifrar a
httpbin.org. Solo para el ejemplo, deshabilita el modo TLS y permite el tráfico sin cifrar al service externo. En escenarios reales, recomendamos realizar la TLS origination de salida por Istio.$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: DestinationRule metadata: name: my-httpbin spec: host: my-httpbin.default.svc.cluster.local trafficPolicy: tls: mode: DISABLE EOFAcceda a
httpbin.orga través del hostname del service de Kubernetes desde el pod de origen con sidecar de Istio. Observe las cabeceras agregadas por el sidecar de Istio, por ejemploX-Envoy-Peer-Metadata. También tenga en cuenta que la cabeceraHostes igual al hostname de su service.$ kubectl exec "$SOURCE_POD" -c curl -- curl -sS my-httpbin.default.svc.cluster.local/headers { "headers": { "Accept": "*/*", "Content-Length": "0", "Host": "my-httpbin.default.svc.cluster.local", "User-Agent": "curl/7.64.0", "X-B3-Sampled": "0", "X-B3-Spanid": "5795fab599dca0b8", "X-B3-Traceid": "5079ad3a4af418915795fab599dca0b8", "X-Envoy-Peer-Metadata": "...", "X-Envoy-Peer-Metadata-Id": "sidecar~10.28.1.74~curl-6bdb595bcb-drr45.default~default.svc.cluster.local" } }
Limpieza del service ExternalName de Kubernetes
$ kubectl delete destinationrule my-httpbin
$ kubectl delete service my-httpbinUsar un service de Kubernetes con endpoints para acceder a un service externo
Cree un service de Kubernetes sin selector para Wikipedia:
$ kubectl apply -f - <<EOF kind: Service apiVersion: v1 metadata: name: my-wikipedia spec: ports: - protocol: TCP port: 443 name: tls EOFCree endpoints para su service. Elija un par de IPs de la lista de rangos de Wikipedia.
$ kubectl apply -f - <<EOF kind: Endpoints apiVersion: v1 metadata: name: my-wikipedia subsets: - addresses: - ip: 198.35.26.96 - ip: 208.80.153.224 ports: - port: 443 name: tls EOFObserve su service. Tenga en cuenta que tiene una IP de cluster que puede usar para acceder a
wikipedia.org.$ kubectl get svc my-wikipedia NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-wikipedia ClusterIP 172.21.156.230 <none> 443/TCP 21hEnvíe solicitudes HTTPS a
wikipedia.orgpor la IP del cluster de su service de Kubernetes desde el pod de origen sin sidecar de Istio. Use la opción--resolvedecurlpara acceder awikipedia.orgpor la IP del cluster:$ kubectl exec "$SOURCE_POD_WITHOUT_ISTIO" -n without-istio -c curl -- curl -sS --resolve en.wikipedia.org:443:"$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}')" https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>" <title>Wikipedia, la enciclopedia libre</title>En este caso, el workload envía solicitudes HTTPS (abre conexión TLS) a
wikipedia.org. El tráfico ya está cifrado por el workload, por lo que puede deshabilitar de forma segura el mTLS de Istio:$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: DestinationRule metadata: name: my-wikipedia spec: host: my-wikipedia.default.svc.cluster.local trafficPolicy: tls: mode: DISABLE EOFAcceda a
wikipedia.orgpor la IP del cluster de su service de Kubernetes desde el pod de origen con sidecar de Istio:$ kubectl exec "$SOURCE_POD" -c curl -- curl -sS --resolve en.wikipedia.org:443:"$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}')" https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>" <title>Wikipedia, la enciclopedia libre</title>Verifique que el acceso se realiza realmente por la IP del cluster. Observe la frase
Connected to en.wikipedia.org (172.21.156.230)en la salida decurl -v, menciona la IP que se imprimió en la salida de su service como la IP del cluster.$ kubectl exec "$SOURCE_POD" -c curl -- curl -sS -v --resolve en.wikipedia.org:443:"$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}')" https://en.wikipedia.org/wiki/Main_Page -o /dev/null * Added en.wikipedia.org:443:172.21.156.230 to DNS cache * Hostname en.wikipedia.org was found in DNS cache * Trying 172.21.156.230... * TCP_NODELAY set * Connected to en.wikipedia.org (172.21.156.230) port 443 (#0) ...
Limpieza del service de Kubernetes con endpoints
$ kubectl delete destinationrule my-wikipedia
$ kubectl delete endpoints my-wikipedia
$ kubectl delete service my-wikipediaLimpieza
Apague el service curl:
$ kubectl delete -f @samples/curl/curl.yaml@Apague el service curl en el namespace
without-istio:$ kubectl delete -f @samples/curl/curl.yaml@ -n without-istioElimine el namespace
without-istio:$ kubectl delete namespace without-istioDesestablezca las variables de entorno:
$ unset SOURCE_POD SOURCE_POD_WITHOUT_ISTIO