Capítulo 4. Añadir servicios a la malla

Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com

En el capítulo anterior aprendiste a implementar Consul en Kubernetes o en máquinas virtuales. El siguiente paso para utilizar Consul es añadir tus servicios a la malla. A partir de ahí, podrás utilizar Consul para aumentar la seguridad, la observabilidad y la fiabilidad.

Un servicio se "añade a la malla" registrándolo en Consul, desplegando su proxy sidecar y asegurándose de que toda la comunicación se enruta a través de ese proxy. En Kubernetes, esto se hace mediante una simple anotación pod . En las máquinas virtuales, tienes que trabajar un poco más: tienes que registrar tu servicio en Consul, desplegar su proxy sidecar y configurar el enrutamiento.

Este capítulo y los siguientes utilizan una aplicación de ejemplo que construí para el libro para ilustrar la funcionalidad de Consul. Después de seguir los ejercicios con la aplicación de ejemplo, estarás bien equipado para añadir tus propios servicios a la malla.

Servicio de ejemplo para observadores de aves

Para probar la malla de servicios, primero necesitas algunos servicios. Vas a desplegar una aplicación básica llamada Birdwatcher. Birdwatcher consta de dos microservicios: frontend y backend.

El servicio frontend alberga una interfaz de usuario como la que se muestra en la Figura 4-1. Cada vez que haces clic en Barajar, se muestra un nuevo pájaro.

Screenshot of the UI.
Figura 4-1. El servicio frontend aloja la interfaz de usuario del servicio Birdwatcher

El servicio frontend utiliza la API del servicio backend para recuperar nuevas aves. Cada vez que frontend realiza una llamada al punto final de backend's /bird, obtiene una respuesta JSON con los datos de las aves:

{
  "metadata": {
    "hostname": "...",
    "version": "v1"
  },
  "response": {
    "name": "Crimson fruitcrow",
    "imageURL": "...",
    "extract": "The crimson fruitcrow..."
  }
}

La aplicación funciona del siguiente modo (ver Figura 4-2):

  1. Cuando cargas el servicio frontend en tu navegador en la ruta /, se carga la IU. A continuación, cuando pulsas el botón Aleatorio, la interfaz de usuario realiza una petición al servicio frontend en /shuffle.

  2. A continuación, el servicio frontend realiza su propia petición a backend para recuperar datos sobre un nuevo pájaro en /bird.

  3. El servicio backend responde con un documento JSON que describe un ave.

  4. El servicio frontend reenvía la respuesta a la IU, y la IU muestra el nuevo pájaro.

Diagram showing frontend calling backend.
Figura 4-2. Secuencia de peticiones para cargar un pájaro en la aplicación Birdwatcher
Nota

frontend y backend resultan ser escritos en Go, pero a Consul no le importa en qué lenguaje estén escritos tus servicios. Mientras utilicen un protocolo de red como TCP, HTTP o gRPC, pueden utilizarse en la malla de servicios.

Esta aplicación de ejemplo pretende ilustrar una arquitectura de microservicios sencilla con un servicio de interfaz de usuario y un servicio de API. Ahora que entiendes la arquitectura de la aplicación Birdwatcher, es hora de desplegarla. Primero desplegarás Birdwatcher sin la malla de servicios y , y luego aprenderás a añadirla a la malla.

Primero cubro Kubernetes y luego paso a las máquinas virtuales ("Implementación de servicios en máquinas virtuales").

Implementación de servicios en Kubernetes

La implementación de los servicios frontend y backend en Kubernetes requiere la creación de recursos de Implementación y Servicio. Como se describe en el Capítulo 2, una Implementación es un tipo de recurso de Kubernetes utilizado para desplegar múltiples réplicas de un servicio y gestionar su ciclo de vida. Los Servicios en Kubernetes se utilizan para configurar el enrutamiento. En concreto, al crear un recurso Servicio, creas una entrada DNS que dirige a tu implementación. Por ejemplo, cuando creas un recurso de Servicio para el servicio backend, el servicio frontend puede ahora llamar a backend utilizando la URL http://backend.1

Para crear recursos en Kubernetes, necesitas utilizar archivos YAML. En el mismo directorio donde creaste el archivo values.yaml para tu instalación, crea un nuevo directorio llamado manifests y cd en él:

$ mkdir manifests
$ cd manifests

Dentro del directorio manifests, crea cuatro archivos YAML, frontend-deployment.yaml(Ejemplo 4-1), frontend-service.yaml(Ejemplo 4-2), backend-deployment.yaml(Ejemplo 4-3) y backend-service.yaml(Ejemplo 4-4).

Ejemplo 4-1. frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  labels:
    app: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
      annotations:
    spec:
      containers:
        - name: frontend
          image: ghcr.io/consul-up/birdwatcher-frontend:1.0.0
          env:
            - name: BIND_ADDR
              value: "0.0.0.0:6060"
            - name: BACKEND_URL
              value: "http://backend"
          ports:
            - containerPort: 6060
Ejemplo 4-2. frontend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: frontend
spec:
  type: LoadBalancer
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 6060
      targetPort: 6060
Advertencia

Si no utilizas minikube en macOS, cambia el tipo de LoadBalancer a ClusterIP para no crear un equilibrador de carga público.

Ejemplo 4-3. backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  labels:
    app: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
      annotations:
    spec:
      containers:
        - name: backend
          image: ghcr.io/consul-up/birdwatcher-backend:1.0.0
          env:
            - name: BIND_ADDR
              value: "0.0.0.0:7000"
          ports:
            - containerPort: 7000
Ejemplo 4-4. backend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend
  labels:
    app: backend
spec:
  selector:
    app: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 7000

Utiliza kubectl apply para aplicar estos recursos a Kubernetes:

$ kubectl apply -f ./

deployment.apps/backend created
service/backend created
deployment.apps/frontend created
service/frontend created

Utiliza el comando kubectl get con la bandera --selector para ver la implementación y el servicio del servicio frontend:

$ kubectl get deployment,service --selector app=frontend

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/frontend   1/1     1            1           1s

NAME               TYPE           CLUSTER-IP      EXTERNAL-IP ...
service/frontend   LoadBalancer   10.98.221.236   127.0.0.1   ...

deployment.apps/frontend debería mostrar 1/1 READY y 1 AVAILABLE , lo que significa que hay un pod ejecutándose y que el único contenedor de ese pod está listo.

Utiliza el mismo comando con un selector diferente para ver la implementación y el servicio del servicio backend:

$ kubectl get deployment,service --selector app=backend

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/backend   1/1     1            1           1s

NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/backend   ClusterIP   10.96.38.122   <none>        80/TCP    1s

Ahora que tus servicios están implementados, deberías poder acceder a la interfaz de usuario de Birdwatcher. Primero, asegúrate de que estás ejecutando minikube tunnel para que los puertos se reenvíen correctamente,2 y luego navega con tu navegador hasta http://localhost:6060. Deberías ver la IU de Birdwatcher como se muestra anteriormente en la Figura 4-1.

Has desplegado con éxito los servicios frontend y backend en Kubernetes y has verificado que se comunican como se esperaba. La arquitectura actual se muestra en la Figura 4-3. Estás accediendo a http://localhost:6060, que es reenviado por minikube tunnel al pod frontend a través de su recurso Servicio. A continuación, el pod frontend está llamando a backend a través de su nombre de host DNS http://backend, que se enruta al pod backend a través de su recurso Servicio.

Frontend calling backend without a mesh.
Figura 4-3. La ruta de petición actual de la aplicación Birdwatcher

Ahora tienes un conjunto típico de servicios Kubernetes en ejecución, pero estos servicios aún no forman parte de la malla. No están registrados en con Consul, y no se comunican a través de proxies sidecar. El siguiente paso es añadir los servicios a la malla.

Añadir servicios Kubernetes a la malla

Para añadir un servicio Kubernetes a la malla, todo lo que tienes que hacer es añadir la anotación consul.hashicorp.com/connect-inject: "true" a los pods. Esta anotación indica a Consul que registre el servicio e inyecte un proxy sidecar (la barra lateral "Under the Hood" explica cómo funciona esto).

Tienes que editar ambas Implementaciones para añadir la anotación. Primero, edita frontend-deployment.yaml y añade la anotación en spec.template.metadata:

# frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
# ...
spec:
  # ...
  template:
    metadata:
      labels:
        app: frontend
      annotations:
        consul.hashicorp.com/connect-inject: "true" 1
    spec:
      containers:
        # ...
1

Asegúrate de entrecomillar true; de lo contrario obtendrás un error.

Nota

Debes añadir la anotación a la clave spec.template.metadata y no a la clave de nivel superior metadata. La clave de nivel superior metadata establece los metadatos de la implementación, y la clave spec.template.metadata establece los metadatos de los pods que componen la implementación. Consul sólo tiene en cuenta los pods (ver "Bajo el capó"), no las implementaciones, por lo que si la anotación no está en el pod, Consul no inyectará ese pod.

Ahora que has modificado tu YAML, estás listo para volver a desplegar el servicio frontend. Para ello, utiliza kubectl apply en el directorio de manifiestos:

$ kubectl apply -f frontend-deployment.yaml

deployment.apps/frontend configured

Kubernetes se encargará de iniciar un nuevo pod y de desactivar el pod antiguo. Puedes utilizar el comando kubectl rollout para esperar a que se complete la redistribución. Puede tardar uno o dos minutos porque Kubernetes necesita descargar imágenes Docker adicionales:

$ kubectl rollout status --watch deploy/frontend

Waiting for deployment "frontend" rollout to finish...
deployment "frontend" successfully rolled out

Ahora que el pod se ha redistribuido, cuando abras la interfaz de usuario de Consul en http://localhost:8500, deberías ver el servicio frontend en la lista, como se muestra en la Figura 4-4 (asegúrate de que tienes minikube tunnel o kubectl port-forward en ejecución). Esto significa que el servicio frontend ¡forma parte ahora de la malla de servicios!

Image of the Consul UI with the frontend service listed
Figura 4-4. El servicio frontend aparece ahora en la interfaz de usuario de Consul

Ahora añade el servicio backend a la malla añadiendo la misma anotación (y una anotación adicional para establecer algunos metadatos) a backend-deployment.yaml:

# backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
# ...
spec:
  # ...
  template:
    metadata:
      labels:
        app: backend
      annotations:
        consul.hashicorp.com/connect-inject: "true"
        consul.hashicorp.com/service-meta-version: "v1" 1
    spec:
      containers:
        # ...
1

Esta anotación establece una clave de metadatos de Consul. Por ahora no se utiliza , pero en el Capítulo 9, cuando aprendas sobre estrategias de implementación, desplegarás una versión v2 del servicio backend.

Vuelve a desplegarlo con kubectl apply:

$ kubectl apply -f backend-deployment.yaml

deployment.apps/backend configured

Espera a que se complete el despliegue:

$ kubectl rollout status --watch deploy/backend

Waiting for deployment "backend" rollout to finish:
  1 old replicas are pending termination...
deployment "backend" successfully rolled out

Ahora, cuando veas la IU, deberías ver los servicios frontend y backend listados como en la Figura 4-5.

Image of the Consul UI with the frontend and backend services listed
Figura 4-5. Los servicios frontend y backend aparecen ahora también en lainterfaz de usuario de Consul.

Ahora que los servicios frontend y backend forman parte de la malla de servicios, si estás utilizando minikube tunnel, intenta cargar de nuevo la interfaz de usuario de Birdwatcher en http://localhost:6060. Deberías ver un error similar al de la Figura 4-6.

Estás recibiendo este error porque ahora que el servicio frontend forma parte de la malla, su proxy sidecar está interceptando todo el tráfico entrante. Consul es seguro por defecto y requiere que todo el tráfico a través de la malla de servicios esté autenticado y autorizado. Cuando haces una petición al servicio frontend a través de tu navegador, tu petición no está autenticada ni autorizada, por lo que Consul la rechaza. Esto se muestra en la Figura 4-7.

Screenshot of the error.
Figura 4-6. Ahora, cuando cargues la IU de Birdwatcher, aparecerá un error
Diagram of the new architecture.
Figura 4-7. El pod frontend tiene ahora un proxy sidecar que intercepta todo el tráfico. Este sidecar rechaza el tráfico entrante que no esté autorizado.

Si utilizas kubectl port-forward, no verás ningún error. Esto se debe a que kubectl port-forward en realidad evita el proxy sidecar. Sin embargo, puedes reproducir el mismo error utilizando kubectl exec para realizar una llamada normal al servicio frontend:

$ kubectl exec consul-server-0 -n consul -- \
    curl -sS http://frontend.default:6060

curl: (52) Empty reply from server
command terminated with exit code 52
Consejo

En Windows, si utilizas PowerShell, sustituye \ por `.

En el próximo capítulo, desplegarás una pasarela de entrada que te permita llamar al servicio frontend con la autorización adecuada. Por ahora, sin embargo, quieres verificar que el tráfico entre los servicios frontend y backend funciona como es debido. Para ello, puedes eludir el proxy de frontendutilizando kubectl exec para ejecutar un comando desde el interior del contenedor frontend y llamar directamente a backend:

$ kubectl exec deploy/frontend -c frontend -- \
    curl -si http://backend/bird


HTTP/1.1 200 OK
...

Si todo funciona como esperabas, deberías recibir una respuesta HTTP 200 OK del servicio backend. Esta petición está atravesando ahora la malla del servicio, como se muestra en la Figura 4-8.

Diagram of kubectl exec.
Figura 4-8 .kubectl exec elude el proxy de frontendporque se ejecuta dentro del contenedor frontend. La petición a backend pasa entonces a través de la malla de servicios como se esperaba.

Para comprobar que las peticiones pasan por la malla de servicios, puedes utilizar la vista de topología de la interfaz de usuario de Consul, que muestra las métricas emitidas desde los proxies sidecar.

Ejecuta el comando anterior kubectl exec un par de veces más para generar más métricas y, a continuación, navega hasta la página de topología del servicio backend haciendo clic en el servicio backend desde la vista Todos los servicios o navegando hasta http://localhost:8500/ui/dc1/services/backend/topology. Deberías ver algo similar a la Figura 4-9 (las métricas pueden tardar un minuto en aparecer).

Image of the Consul UI's view for the backend service.
Figura 4-9. La vista de topología del servicio backend debería mostrar las métricas de las peticiones entrantes
Nota

Las advertencias que ves en la vista de topología se deben a que las ACL no están activadas y a que no has creado ninguna intención. Las ACL se tratan en el Capítulo 10 y crearás intenciones en el Capítulo 6. También observarás que la topología muestra backend llamando a frontend, lo cual es incorrecto. Esto se debe a que Consul está mostrando todas las conexiones permitidas entre servicios. Cuando más adelante crees intenciones para permitir sólo determinadas conexiones, la vista de la topología cambiará.

Si ves métricas en la vista de topología, ¡has añadido con éxito tus servicios a la malla! Las métricas demuestran que los proxies sidecar están captando tráfico.

Nota

Si haces clic en el servicio frontend, no verás ninguna métrica. Esto se debe a que el gráfico sólo muestra las peticiones entrantes, y actualmente no estás realizando ninguna petición al servicio frontend. En el próximo capítulo, desplegarás una pasarela de entrada que te permita hacer peticiones al servicio frontend, y entonces también verás sus métricas.

En la siguiente sección, aprenderás a añadir a la malla servicios que se ejecutan en máquinas virtuales. Si sólo te interesa Kubernetes, sáltate y avanza hasta el resumen del capítulo.

Implementación de servicios en máquinas virtuales

En esta sección, cubro cómo implementar y ejecutar la aplicación Birdwatcher en máquinas virtuales sin la malla. Una vez que Birdwatcher esté funcionando, aprenderás a añadirlo a la malla. El proceso para añadir Birdwatcher a la malla será similar al que seguirás para tus propios servicios.

Por simplicidad, vas a ejecutar frontend y backend en la misma máquina virtual. El primer paso es introducir los binarios frontend y backend en la máquina virtual. Si utilizas la máquina virtual preempaquetada a través de Vagrant, los binarios ya estarán allí. Si utilizas tu propia máquina virtual, puedes encontrar los binarios en el repositorio GitHub del libro.

Con los binarios en su sitio, tienes que iniciarlos utilizando systemd, igual que hiciste con Consul. En primer lugar, crea dos archivos de unidad systemd, frontend.service y backend.service, en /etc/systemd/system/ (asegúrate de haber ejecutado antes vagrant ssh ).

$ sudo touch /etc/systemd/system/frontend.service
$ sudo touch /etc/systemd/system/backend.service

Edita /etc/systemd/system/frontend.service y añade el contenido del Ejemplo 4-5.

Consejo

Tendrás que utilizar sudo para editar archivos en /etc/systemd/system;por ejemplo, sudo vim /etc/systemd/system/frontend.service.

Ejemplo 4-5. /etc/systemd/sistema/frontend.service
[Unit]
Description="Frontend service"

# The service requires the VM's network
# to be configured, e.g., an IP address has been assigned.
Requires=network-online.target
After=network-online.target

[Service]
# ExecStart is the command to run.
ExecStart=/usr/local/bin/frontend

# Restart configures the restart policy. In this case, we
# want to restart the service if it fails.
Restart=on-failure

# Environment sets environment variables.
# We will set the frontend service to listen
# on port 6060.
Environment=BIND_ADDR=0.0.0.0:6060

# We set BACKEND_URL to http://localhost:7000 because
# that's the port we'll run our backend service on.
Environment=BACKEND_URL=http://localhost:7000

# The Install section configures this service to start
# automatically if the VM reboots.
[Install]
WantedBy=multi-user.target

A continuación, edita /etc/systemd/system/backend. service para que coincida con el Ejemplo 4-6.

Ejemplo 4-6. /etc/systemd/sistema/backend.service
[Unit]
Description="Backend service"
Requires=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/backend
Restart=on-failure

# We will set the backend service to listen
# on port 7000.
Environment=BIND_ADDR=0.0.0.0:7000

[Install]
WantedBy=multi-user.target

Con los archivos de unidad en su sitio, estás listo para activar5 e iniciar tus servicios:

$ sudo systemctl enable frontend backend

Created symlink ...
Created symlink ...

Ahora inicia los servicios:

$ sudo systemctl start frontend backend
Nota

Para este ejercicio estás ejecutando todos estos pasos manualmente, pero para una implementación en producción deberías utilizar una herramienta de aprovisionamiento como Ansible o Terraform y Packer.

Puedes comprobar sus estados con systemctl status:

$ sudo systemctl status frontend backend

  frontend.service - "Frontend service"
     Loaded: loaded...
     Active: active (running)...
...
  backend.service - "Backend service"
     Loaded: loaded...
     Active: active (running)...

Ahora que frontend y backend se están ejecutando, deberías poder acceder a la aplicación Birdwatcher navegando por tu navegador hasta http://localhost:6060. Deberías ver la interfaz de usuario como se muestra en la Figura 4-1.

La arquitectura actual se muestra en la Figura 4-10.

Frontend calling backend without a mesh.
Figura 4-10 .frontend escucha en el puerto 6060, y backend escucha en el puerto 7000

Tus servicios ya están en marcha, pero aún no están registrados en la malla y su tráfico no fluye a través de los proxies sidecar. En las siguientes secciones, registrarás los servicios en Consul e iniciarás los proxies sidecar. Estos son los mismos pasos que tendrás que seguir para tus propios servicios.

Registrar servicios VM con Consul

Debes registrar los servicios con Consul para que sepa qué se está ejecutando y en qué IPs y puertos. Los servicios pueden registrarse mediante archivos de configuración o utilizando la API de Consul. En los sistemas dinámicos, como los orquestadores de contenedores, tiene sentido utilizar la API, pero en las máquinas virtuales suele ser más sencillo utilizar los archivos de configuración, porque normalmente sabes en el momento del aprovisionamiento qué servicios se ejecutarán en una máquina virtual concreta.

Crea los archivos de configuración del servicio en el directorio de configuración de Consul /etc/consul.d:6

$ sudo touch /etc/consul.d/frontend.hcl
$ sudo touch /etc/consul.d/backend.hcl

Añade el contenido del Ejemplo 4-7 a /etc/consul.d/frontend.hcl.

Ejemplo 4-7. /etc/consul.d/frontend.hcl
service {
  name = "frontend"

  # frontend runs on port 6060.
  port = 6060

  # The "connect" stanza configures service mesh
  # features.
  connect {
    sidecar_service {
      # frontend's proxy will listen on port 21000.
      port = 21000

      proxy {
        # The "upstreams" stanza configures
        # which ports the sidecar proxy will expose
        # and what services they'll route to.
        upstreams = [
          {
            # Here you're configuring the sidecar proxy to
            # proxy port 6001 to the backend service.
            destination_name = "backend"
            local_bind_port  = 6001
          }
        ]
      }
    }
  }
}
Nota

Normalmente no establecerás el puerto del proxy, sino que dejarás que Consul lo asigne dinámicamente. En este ejercicio, codificarás el puerto del proxy frontend en 21000 para que quede claro qué proxies están en qué puertos a lo largo del libro.

Para /etc/consul.d/backend.hcl, utiliza el código que se muestra en el Ejemplo 4-8.

Ejemplo 4-8. /etc/consul.d/backend.hcl
service {
  name = "backend"
  # backend runs on port 7000.
  port = 7000

  meta {
    version = "v1"
  }

  # The backend service doesn't call
  # any other services so it doesn't
  # need an "upstreams" stanza.
  #
  # The connect stanza is still required to
  # indicate that it needs a sidecar proxy.
  connect {
    sidecar_service {
      # backend's proxy will listen on port 22000.
      port = 22000
    }
  }
}

Tus propios servicios necesitarán archivos de configuración similares. Tendrás que establecer el nombre del servicio, el puerto en el que escucha y las dependencias de los servicios ascendentes (consulta "Servicios ascendentes").

Tienes que decirle a Cónsul que recargue su configuración para que recoja los nuevos archivos. Para ello, utiliza el comando consul reload:

$ consul reload

Configuration reload triggered

Puedes utilizar el comando consul catalog services para comprobar si tus servicios se han registrado correctamente:

$ consul catalog services

backend
backend-sidecar-proxy
consul
frontend
frontend-sidecar-proxy

Deberías ver frontend y backend en la lista, junto con sus proxies sidecar.

Nota

¿Por qué aparecen frontend-sidecar-proxy y backend-sidecar-proxy? Bajo el capó, Consul trata los proxies sidecar como servicios separados. No verás los proxies listados en la interfaz de usuario porque están ocultos, pero sí en la API o CLI.

En la interfaz de usuario de http://localhost:8500, frontend y backend deberían aparecer en la lista(Figura 4-11), aunque se mostrarán como no saludables. Esto se debe a que sus proxies sidecar aún no se están ejecutando.

Image of the Consul UI
Figura 4-11. Los servicios frontend y backend aparecen en la interfaz de usuario, pero se muestran como no saludables porque sus proxies sidecar aún no se están ejecutando

Ahora que tus servicios están registrados en Consul, es hora de que despliegue sus proxies sidecar.

Implementación de proxies Sidecar en máquinas virtuales

Para que tus servicios estén sanos, sus proxies sidecar deben estar funcionando. Los proxies sidecar ejecutan Envoy, que ya está instalado en la VM Vagrant. Si estás ejecutando tus propias máquinas virtuales, consulta las instrucciones de instalación de Envoy.

Al igual que con los servicios frontend y backend, configurarás un servicio systemd para ejecutar cada proxy sidecar . El comando que systemd utilizará para ejecutar los proxies sidecar es:

consul connect envoy

Este comando acepta una bandera, -sidecar-for, que se utiliza para configurar el proxy Envoy para un servicio específico.

Nota

Consul no admite la ejecución de un único proxy Envoy para múltiples servicios, porque cada proxy Envoy debe codificar la identidad del servicio de origen en cada solicitud. Además, querrás configurar reglas diferentes para el proxy de cada servicio.

Primero, crea los dos archivos de unidad:

$ sudo touch /etc/systemd/system/frontend-sidecar-proxy.service
$ sudo touch /etc/systemd/system/backend-sidecar-proxy.service

/etc/systemd/system/frontend-sidecar-proxy.service debería coincidir con el Ejemplo 4-9.

Ejemplo 4-9. /etc/systemd/system/frontend-sidecar-proxy.service
[Unit]
Description="Frontend sidecar proxy service"
Requires=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/bin/consul connect envoy -sidecar-for frontend \
  -admin-bind 127.0.0.1:19000
Restart=on-failure

[Install]
WantedBy=multi-user.target

Y /etc/systemd/system/backend-sidecar-proxy.service debería coincidir con el Ejemplo 4-10.

Ejemplo 4-10. /etc/systemd/system/backend-sidecar-proxy.service
[Unit]
Description="Backend sidecar proxy service"
Requires=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/bin/consul connect envoy -sidecar-for backend \
  -admin-bind 127.0.0.1:19001
Restart=on-failure

[Install]
WantedBy=multi-user.target

A continuación, activa los dos servicios:

$ sudo systemctl enable frontend-sidecar-proxy
$ sudo systemctl enable backend-sidecar-proxy

¡Ahora ponlos en marcha!

$ sudo systemctl start frontend-sidecar-proxy
$ sudo systemctl start backend-sidecar-proxy

Comprueba que sus estados muestran activo y en funcionamiento:

$ sudo systemctl status frontend-sidecar-proxy

 frontend-sidecar-proxy.service - "Frontend sidecar proxy service"
     Loaded: loaded...
     Active: active (running)...
$ sudo systemctl status backend-sidecar-proxy

 backend-sidecar-proxy.service - "Backend sidecar proxy service"
     Loaded: loaded...
     Active: active (running)...

Con los proxies ahora en funcionamiento, la interfaz de usuario debería mostrar todo en buen estado (verFigura 4-12).

Image of the Consul UI
Figura 4-12. Los servicios frontend y backend están ahora sanos porque sus proxies sidecar se están ejecutando

Recarga la IU de Birdwatcher en http://localhost:6060 para ver si ha cambiado algo. La interfaz de usuario debería tener el mismo aspecto y funcionar igual que antes, así que ¿cómo sabes si el tráfico se enruta a través de la malla de servicio?

Una forma de comprobar si el tráfico se dirige a través de la malla es crear una intención que deniegue todo el tráfico. Las intenciones son reglas de autorización que dictan a qué servicios se les permite comunicarse. Las intenciones se tratan en detalle en el Capítulo 6, pero puedes utilizarlas ahora como una prueba rápida para ver si el tráfico se dirige a través de la malla.

Crea una intención para denegar todo el tráfico entre servicios utilizando la CLI de Consul:

$ consul intention create -deny '*' '*'

Created: * => * (deny)

Ahora intenta recargar de nuevo la IU del Observador de Aves. La IU debería cargar un nuevo pájaro, aunque la intención debería ser denegar el tráfico, así que ¿qué está pasando?

A diferencia de lo que ocurre en Kubernetes, cuando añades servicios a la malla de servicios en las máquinas virtuales tienes que hacer algunos cambios en las URL que utilizan tus servicios para que dirijan el tráfico a través de sus proxies sidecar. En este momento, frontend sigue llamando directamente a backend y elude tanto su proxy local como el proxy de backend, como se muestra en la Figura 4-13. Los proxies imponen las intenciones, por eso la interfaz de usuario de Birdwatcher sigue cargando pájaros.

Frontend calling backend bypassing the sidecar proxies.
Figura 4-13. frontend llama directamente a backend, saltándose los proxies sidecar

Configurar el enrutamiento en máquinas virtuales

Tienes que configurar frontend para que dirija las peticiones a backend a través de su proxy sidecar. ¿Recuerdas cuando configuraste frontend's upstreams? Configuraste el local_bind_port para el servicio backend en 6001. Ahora sólo tienes que configurar frontend para que utilice ese puerto.

Por suerte, el servicio frontend expone la variable de entorno BACKEND_URL para configurar la URL que se utilizará para llamar a backend.

Consejo

En tus propios servicios, es probable que tengas la misma posibilidad de configurar las URL ascendentes mediante una variable de entorno o un archivo de configuración. Si no es así, tendrás que modificar el código de tu servicio.

Actualmente, en tu archivo frontend.service, esta variable de entorno está establecida en http://localhost:7000, así que todo lo que tienes que hacer es establecerla en http://localhost:6001.

Edita /etc/systemd/system/frontend.service utilizando sudo (frontend.service, no frontend-sidecar-proxy.service) y cambia la variable de entorno BACKEND_URL por http://localhost:6001:

...
Environment=BACKEND_URL=http://localhost:6001
...

Ahora ejecuta systemctl daemon-reload para que systemd cargue la configuración actualizada y luego utiliza systemctl restart para reiniciar el servicio frontend:

$ sudo systemctl daemon-reload
$ sudo systemctl restart frontend

Si vuelves a cargar la IU de Birdwatcher en http://localhost:6060, ahora deberías ver un error:

Unable to call backend: Get "http://localhost:6001/bird": EOF

Este error confirma que frontend está intentando llamar a backend a través de su proxy sidecar y la llamada está fallando porque el proxy sidecar de backendestá rechazando la petición.

Borra la intención de permitir el tráfico:

$ consul intention delete '*' '*'

Intention deleted.

Vuelve a la interfaz de usuario y pulsa el botón Barajar. Los pájaros deberían empezar a cargarse de nuevo.

Ahora has confirmado que las peticiones entre frontend y backend se enrutan a través de la malla de servicios.7 La Figura 4-14 muestra el aspecto actual de la arquitectura.

Frontend calling backend through the sidecar proxies.
Figura 4-14. frontend está llamando a backend a través de los proxies sidecar de la malla. Tú sigues accediendo directamente a frontend.
Nota

Hay dos conjuntos de puertos para un proxy sidecar: puertos ascendentes y puertos públicos. Un servicio utiliza los puertos ascendentes de su proxy para dirigirse a sus dependencias. En este ejemplo, 6001 es un puerto ascendente.

Los puertos públicos son los puertos en los que se recibirá el tráfico entrante de otros proxies sidecar. Como se muestra en la Figura 4-14, el puerto público del proxy sidecar de backendes el 22000. Consul configura todos los proxies para que conozcan los puertos públicos de los demás proxies. Así es como el proxy de frontendpuede enviar tráfico al proxy de backend.

Resumen

En este capítulo has aprendido a añadir servicios a la malla de servicios de Consul. En Kubernetes, esto era una simple cuestión de anotar tus pods con la anotación consul.hashicorp.com/inject: "true". Bajo el capó, Consul se encargaba de inyectar automáticamente el proxy sidecar y de interceptar el tráfico.

En las máquinas virtuales, registraste los servicios con Consul mediante archivos de configuración y ejecutaste los proxies sidecar utilizando systemd. A continuación, aprendiste a configurar los servicios para que se comuniquen con sus dependencias ascendentes a través de sus proxies sidecar locales.

Ahora tus servicios se comunican a través de la malla, pero no has aprendido a exponerlos a llamantes que no están en la malla. Por eso no puedes cargar la interfaz de usuario de frontenden Kubernetes y por eso, en las máquinas virtuales, te saltas la malla para cargar la interfaz de usuario.

En el próximo capítulo, aprenderás a utilizar pasarelas de entrada para exponer servicios orientados al usuario.

1 Si los servicios estuvieran en espacios de nombres diferentes, utilizarías http://backend.<espacio de nombres>.

2 Si ejecutas Kubernetes en la nube o en Linux, utiliza kubectl port-forward service/frontend 6060.

3 Un contenedor init es un contenedor que se ejecuta antes de los contenedores principales de un pod.

4 Si aún tienes servicios que no pueden estar en la malla, puedes utilizar una pasarela de terminación. Las pasarelas de terminación se tratan en el Capítulo 10.

5 systemctl enable configura los servicios para que se reinicien cuando se reinicie la VM.

6 Puedes colocar la configuración de tu servicio en cualquier directorio, siempre que éste se pase a Consul utilizando la bandera -config-dir.

7 Técnicamente, no todas las peticiones están viajando a través de la malla del servicio. Tu navegador sigue conectándose directamente con el servicio frontend, no con su proxy. En el próximo capítulo añadirás una pasarela de entrada para solucionar esto.

Get Consulta: En marcha now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.