En Cloud Service Mesh 1.5 y versiones posteriores, la autenticación TLS mutua automática (mTLS automática) está habilitada de forma predeterminada. Con mTLS automático, un proxy sidecar del cliente detecta automáticamente si el servidor tiene un sidecar. El sidecar del cliente envía mTLS a las cargas de trabajo con sidecars y texto sin formato a las cargas de trabajo sin sidecars. Sin embargo, los servicios aceptan tráfico tanto de texto sin formato como de mTLS. A medida que insertes proxies sidecar en tus pods, te recomendamos que también configures tus servicios para que solo acepten tráfico mTLS.
Con Cloud Service Mesh, puedes aplicar mTLS fuera del código de tu aplicación aplicando un solo archivo YAML. Cloud Service Mesh te ofrece la flexibilidad necesaria para aplicar una política de autenticación a toda la malla de servicios, a un espacio de nombres o a una carga de trabajo concreta.
Costes
En este documento, se utilizan los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costes basada en el uso previsto,
utiliza la calculadora de precios.
Cuando termines este tutorial, puedes evitar costes continuos eliminando los recursos que hayas creado. Para obtener más información, consulta la sección Limpiar.
Antes de empezar
Asegúrate de que la facturación esté habilitada en tu proyecto.
Aprovisiona Cloud Service Mesh en un clúster de GKE. Hay varios métodos de configuración admitidos:
Clona el repositorio:
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples cd anthos-service-mesh-samples
Desplegar una pasarela de entrada
Define el contexto actual de
kubectl
en el clúster:gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
Crea un espacio de nombres para tu pasarela de entrada:
kubectl create namespace asm-ingress
Habilita el espacio de nombres para la inyección. Los pasos dependen de la implementación del plano de control.
Gestionado (TD)
Aplica la etiqueta de inyección predeterminada al espacio de nombres:
kubectl label namespace asm-ingress \ istio.io/rev- istio-injection=enabled --overwrite
Gestionado (Istiod)
Recomendación: Ejecuta el siguiente comando para aplicar la etiqueta de inyección predeterminada al espacio de nombres:
kubectl label namespace asm-ingress \ istio.io/rev- istio-injection=enabled --overwrite
Si ya eres usuario del plano de control de Istiod gestionado: Te recomendamos que utilices la inyección predeterminada, pero también se admite la inyección basada en revisiones. Sigue estas instrucciones:
Ejecuta el siguiente comando para localizar los canales de lanzamiento disponibles:
kubectl -n istio-system get controlplanerevision
El resultado debería ser similar al siguiente:
NAME AGE asm-managed-rapid 6d7h
En el resultado, el valor de la columna
NAME
es la etiqueta de revisión que corresponde al canal de lanzamiento disponible para la versión de Cloud Service Mesh.Aplica la etiqueta de revisión al espacio de nombres:
kubectl label namespace asm-ingress \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite
Despliega la pasarela de ejemplo en el repositorio
anthos-service-mesh-samples
:kubectl apply -n asm-ingress \ -f docs/shared/asm-ingress-gateway
Resultado esperado:
serviceaccount/asm-ingressgateway configured service/asm-ingressgateway configured deployment.apps/asm-ingressgateway configured gateway.networking.istio.io/asm-ingressgateway configured
Implementar la aplicación de ejemplo Online Boutique
Si no lo ha hecho, defina el contexto actual de
kubectl
en el clúster:gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
Crea el espacio de nombres de la aplicación de ejemplo:
kubectl create namespace onlineboutique
Etiqueta el espacio de nombres
onlineboutique
para insertar automáticamente proxies de Envoy. Sigue los pasos para habilitar la inyección automática de sidecar.Implementa la aplicación de ejemplo, el
VirtualService
del frontend y las cuentas de servicio de las cargas de trabajo. En este tutorial, desplegarás Online Boutique, una aplicación de demostración de microservicios.kubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/virtual-service.yaml kubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/service-accounts
Ver tus servicios
Consulta los pods del espacio de nombres
onlineboutique
:kubectl get pods -n onlineboutique
Resultado esperado:
NAME READY STATUS RESTARTS AGE adservice-85598d856b-m84m6 2/2 Running 0 2m7s cartservice-c77f6b866-m67vd 2/2 Running 0 2m8s checkoutservice-654c47f4b6-hqtqr 2/2 Running 0 2m10s currencyservice-59bc889674-jhk8z 2/2 Running 0 2m8s emailservice-5b9fff7cb8-8nqwz 2/2 Running 0 2m10s frontend-77b88cc7cb-mr4rp 2/2 Running 0 2m9s loadgenerator-6958f5bc8b-55q7w 2/2 Running 0 2m8s paymentservice-68dd9755bb-2jmb7 2/2 Running 0 2m9s productcatalogservice-84f95c95ff-c5kl6 2/2 Running 0 114s recommendationservice-64dc9dfbc8-xfs2t 2/2 Running 0 2m9s redis-cart-5b569cd47-cc2qd 2/2 Running 0 2m7s shippingservice-5488d5b6cb-lfhtt 2/2 Running 0 2m7s
Todos los pods de tu aplicación deben estar operativos y tener un
2/2
en la columnaREADY
. Esto indica que los pods tienen un proxy sidecar de Envoy insertado correctamente. Si no aparece2/2
al cabo de un par de minutos, consulta la guía de solución de problemas.Obtén la IP externa y asígnala a una variable:
kubectl get services -n asm-ingress export FRONTEND_IP=$(kubectl --namespace asm-ingress \ get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \ )
Verá un resultado similar al siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE asm-ingressgateway LoadBalancer 10.19.247.233 35.239.7.64 80:31380/TCP,443:31390/TCP,31400:31400/TCP 27m
Visita la dirección
EXTERNAL-IP
en tu navegador web. Deberías ver la tienda Online Boutique en tu navegador.
Crear un pod TestCurl
Crea un pod TestCurl para enviar tráfico de texto sin formato con fines de prueba.
apiVersion: v1
kind: Pod
metadata:
name: testcurl
namespace: default
annotations:
sidecar.istio.io/inject: "false"
spec:
containers:
- name: curl
image: curlimages/curl
command: ["sleep", "600"]
Acceder a Online Boutique
Define el contexto actual de
kubectl
en el clúster en el que has desplegado Online Boutique:gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
Muestra los servicios del espacio de nombres
frontend
:kubectl get services -n frontend
Observa que
frontend-external
es unLoadBalancer
y tiene una dirección IP externa. La aplicación de ejemplo incluye un servicio que es un balanceador de carga para que se pueda implementar en GKE sin Cloud Service Mesh.Visita la aplicación en tu navegador con la dirección IP externa del servicio
frontend-external
:http://FRONTEND_EXTERNAL_IP/
Cloud Service Mesh te permite desplegar una pasarela de entrada. También puedes acceder a Online Boutique mediante la dirección IP externa de la pasarela de entrada. Obtén la IP externa de la pasarela. Sustituye los marcadores de posición por la siguiente información:
- GATEWAY_SERVICE_NAME : nombre del servicio de pasarela de entrada. Si has implementado la pasarela de ejemplo sin modificarla o si has implementado la pasarela de entrada predeterminada, el nombre es
istio-ingressgateway
. - GATEWAY_NAMESPACE: el espacio de nombres en el que has implementado la pasarela de entrada. Si has implementado la pasarela de entrada predeterminada, el espacio de nombres es
istio-system
.
kubectl get service GATEWAY_NAME -n GATEWAY_NAMESPACE
- GATEWAY_SERVICE_NAME : nombre del servicio de pasarela de entrada. Si has implementado la pasarela de ejemplo sin modificarla o si has implementado la pasarela de entrada predeterminada, el nombre es
Abre otra pestaña en el navegador y visita la aplicación con la dirección IP externa de la pasarela de entrada:
http://INGRESS_GATEWAY_EXTERNAL_IP/
Ejecuta el siguiente comando para
curl
el serviciofrontend
con HTTP sin cifrar desde otro pod. Como los servicios están en espacios de nombres diferentes, debes usar curl en el nombre DNS del serviciofrontend
.kubectl debug --image istio/base --target istio-proxy -it \ $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \ -n product-catalog -- \ curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
Tu solicitud se ha completado correctamente con el estado
200
porque, de forma predeterminada, se acepta tanto el tráfico TLS como el de texto sin cifrar.
Habilitar TLS mutuo por espacio de nombres
Para aplicar mTLS, debes aplicar una política PeerAuthentication
con kubectl
.
Guarda la siguiente política de autenticación como
mtls-namespace.yaml
.cat <<EOF > mtls-namespace.yaml apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "namespace-policy" spec: mtls: mode: STRICT EOF
La línea
mode: STRICT
del archivo YAML configura los servicios para que solo acepten mTLS. De forma predeterminada,mode
esPERMISSIVE
, lo que configura los servicios para que acepten tanto texto sin formato como mTLS.Aplica la política de autenticación para configurar todos los servicios de Online Boutique de forma que solo acepten mTLS:
for ns in ad cart checkout currency email frontend loadgenerator \ payment product-catalog recommendation shipping; do kubectl apply -n $ns -f mtls-namespace.yaml done
Resultado esperado:
peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created
Ve a la pestaña de tu navegador que accede a Online Boutique mediante la dirección IP externa del servicio
frontend-external
:http://FRONTEND_EXTERNAL_IP/
Actualiza la página. El navegador muestra el siguiente error:
Al actualizar la página, se envía texto sin formato al servicio
frontend
. Debido a laSTRICT
política de autenticación, el proxy sidecar bloquea la solicitud al servicio.Ve a la pestaña del navegador que accede a Online Boutique mediante la dirección IP externa de
istio-ingressgateway
y actualiza la página, que se mostrará correctamente. Cuando accedes a Online Boutique mediante la puerta de enlace de entrada, la solicitud sigue esta ruta:Flujo de autenticación mTLS:
- El navegador envía una solicitud HTTP en texto sin cifrar al servidor.
- El contenedor proxy de la puerta de enlace de entrada intercepta la solicitud.
- El proxy de la pasarela de entrada realiza un handshake TLS con el proxy del lado del servidor (el servicio frontend en este ejemplo). Este handshake incluye un intercambio de certificados. Cloud Service Mesh precarga estos certificados en los contenedores proxy.
- El proxy de la pasarela de entrada realiza una comprobación de nombres segura en el certificado del servidor para verificar que una identidad autorizada esté ejecutando el servidor.
- La pasarela de entrada y los proxies del servidor establecen una conexión TLS mutua, y el proxy del servidor reenvía la solicitud al contenedor de la aplicación del servidor (el servicio frontend).
Ejecuta el siguiente comando para
curl
el serviciofrontend
con HTTP sin cifrar desde otro pod.kubectl exec testcurl -n default -- curl \ http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
Tu solicitud falla porque estamos enviando tráfico de texto sin formato desde una carga de trabajo sin sidecar en la que se aplica la política STRICT
peerAuthentication
.
Buscar y eliminar políticas de autenticación
Para ver una lista de todas las políticas de
PeerAuthentication
en la malla de servicios, haz lo siguiente:kubectl get peerauthentication --all-namespaces
El resultado debería ser similar al siguiente:
NAMESPACE NAME MODE AGE ad namespace-policy STRICT 17m cart namespace-policy STRICT 17m checkout namespace-policy STRICT 17m currency namespace-policy STRICT 17m email namespace-policy STRICT 17m frontend namespace-policy STRICT 17m loadgenerator namespace-policy STRICT 17m payment namespace-policy STRICT 17m product-catalog namespace-policy STRICT 17m recommendation namespace-policy STRICT 17m shipping namespace-policy STRICT 17m
Elimina la política de autenticación de todos los espacios de nombres de Online Boutique:
for ns in ad cart checkout currency email frontend loadgenerator payment \ product-catalog recommendation shipping; do kubectl delete peerauthentication -n $ns namespace-policy done;
Resultado esperado:
peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted
Accede a Online Boutique con la dirección IP externa del servicio
frontend-external
y actualiza la página. La página se muestra como se esperaba.Ejecuta el siguiente comando para
curl
el serviciofrontend
con HTTP sin cifrar desde otro pod.kubectl debug --image istio/base --target istio-proxy -it \ $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \ -n product-catalog -- \ curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
Tu solicitud se ha completado correctamente con el estado
200
porque, de forma predeterminada, se acepta tanto el tráfico TLS como el de texto sin cifrar.
Si actualizas la página de la consola Google Cloud que muestra la lista Cargas de trabajo, ahora verás que el estado de mTLS es Permissive
.
Habilitar TLS mutuo por carga de trabajo
Para definir una política de PeerAuthentication
en una carga de trabajo específica, debe configurar la sección selector
y especificar las etiquetas que coincidan con la carga de trabajo deseada.
Sin embargo, Cloud Service Mesh no puede agregar políticas a nivel de carga de trabajo para el tráfico mTLS saliente a un servicio. Para gestionar este comportamiento, debe configurar una regla de destino.
Aplica una política de autenticación a una carga de trabajo específica. Fíjate en cómo la siguiente política usa etiquetas y selectores para segmentar una
frontend
implementación específica.cat <<EOF | kubectl apply -n frontend -f - apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "frontend" namespace: "frontend" spec: selector: matchLabels: app: frontend mtls: mode: STRICT EOF
Resultado esperado:
peerauthentication.security.istio.io/frontend created
Configura una regla de destino de coincidencia.
cat <<EOF | kubectl apply -n frontend -f - apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "frontend" spec: host: "frontend.demo.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL EOF
Resultado esperado:
destinationrule.networking.istio.io/frontend created
Accede a Online Boutique con la dirección IP externa del servicio
frontend-external
y actualiza la página. La página no se muestra porquefrontend service
está configurado comoSTRICT
mTLS y el proxy sidecar bloquea la solicitud.Ejecuta el siguiente comando para
curl
el serviciofrontend
con HTTP sin cifrar desde otro pod.kubectl exec testcurl -n default -- curl \ http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
Tu solicitud falla porque estamos enviando tráfico de texto sin formato desde una carga de trabajo sin sidecar en la que se aplica la política STRICT
peerAuthentication
.Elimina la política de autenticación:
kubectl delete peerauthentication -n frontend frontend
Resultado esperado:
peerauthentication.security.istio.io "frontend" deleted
Elimina la regla de destino:
kubectl delete destinationrule -n frontend frontend
Resultado esperado:
destinationrule.networking.istio.io "frontend" deleted
Implementar mTLS en toda la malla
Para evitar que todos los servicios de la malla acepten tráfico sin cifrar, define una PeerAuthentication
política en toda la malla con el modo mTLS definido como STRICT
.
La política PeerAuthentication
de toda la malla no debe tener un selector y debe aplicarse en el espacio de nombres raíz, istio-system
. Cuando implementas la política, el plano de control aprovisiona automáticamente certificados TLS para que las cargas de trabajo puedan autenticarse entre sí.
Implementa mTLS en toda la malla:
kubectl apply -f - <<EOF apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "mesh-wide" namespace: "istio-system" spec: mtls: mode: STRICT EOF
Resultado esperado:
peerauthentication.security.istio.io/mesh-wide created
Accede a Online Boutique con la dirección IP externa del servicio
frontend-external
y actualiza la página. La página no se muestra.Ejecuta el siguiente comando para
curl
el serviciofrontend
con HTTP sin cifrar desde otro pod.kubectl exec testcurl -n default -- curl \ http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
Tu solicitud falla porque estamos enviando tráfico de texto sin formato desde una carga de trabajo sin sidecar en la que se aplica la política STRICT
peerAuthentication
.Elimina la política
mesh-wide
:kubectl delete peerauthentication -n istio-system mesh-wide
Resultado esperado:
peerauthentication.security.istio.io "mesh-wide" deleted
Limpieza
Para evitar que los recursos utilizados en este tutorial se cobren en tu cuenta de Google Cloud, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.
Si quieres evitar cargos adicionales, elimina el clúster:
gcloud container clusters delete CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
Si quieres conservar tu clúster y eliminar la muestra de Online Boutique, sigue estos pasos:
- Elimina los espacios de nombres de la aplicación:
kubectl delete -f online-boutique/kubernetes-manifests/namespaces
Resultado esperado:
namespace "ad" deleted namespace "cart" deleted namespace "checkout" deleted namespace "currency" deleted namespace "email" deleted namespace "frontend" deleted namespace "loadgenerator" deleted namespace "payment" deleted namespace "product-catalog" deleted namespace "recommendation" deleted namespace "shipping" deleted
- Elimina las entradas de servicio:
kubectl delete -f online-boutique/istio-manifests/allow-egress-googleapis.yaml
Resultado esperado:
serviceentry.networking.istio.io "allow-egress-googleapis" deleted serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
Siguientes pasos
- Para obtener una guía general sobre cómo configurar las políticas de
PeerAuthentication
, consulta Configurar la seguridad del transporte.