viernes, 25 de octubre de 2024

Service Mesh Linkerd



En el post anterior se habló de lo que es un Service Mesh e instalamos Istio.

Hoy toca hablar sobre Linkerd, es un Service Mesh que no cuenta con tantas cosas como Istio, ¿esto es malo?, no es malo por que lo que hace, lo hace bien.

En comparación con Istio no es necesario crear los Istio ingress o gateways, solo se encarga del Service Mesh. Linkerd tiene mejor performance que Istio (según la documentación de Linkerd claro está). Como Linkerd es más pequeño puedes tener un ahorro en el costo de tu cluster de Kubernetes en tu proveedor de la nube.

Al igual que Istio cuenta con mTLS entre los microservicios cuando se inyecta el sidecar (proxy) de Linkerd, esta de más decir que esto te agregará un poco de latencia en tu aplicación.

Acá esta el video para que vayas conmigo haciendo el tutorial:





## Instalación

Al igual que Istio debemos instalar un cliente:

```bash
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install-edge | sh
```

Y mover el cliente a una ruta de tu Path para que funcione y listo.

Puedes ejecutar el siguiente comando para probar que esté funcionando:

```bash
linkerd version
```


Como solo hemos instalado el client veras un error en el server (control plane), esto es normal y más adelante lo solucionamos.

Ahora debemos comprobar que nuestro cluster de kubernetes cumple con la configuración de Linkerd.

```bash
linkerd check --pre
```

El último paso de la instalación es instalar el CRD de Linkerd en nuestro cluster:

```bash
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -
```

Para la validación de la instalación puedes ejecutar el siguiente comando:

```bash
linkerd check
```

o puedes verificar que ya está en estado RUNNING todo lo que se encuentra en el namespace linkerd:

```bash
kubectl get all -n linkerd
```

## Configuración de Linkerd

Para que tu aplicación funcione con Linkerd hay que inyectarle el sidecar de Linkerd. Para hacer esto podemos hacerlo de 3 formas:

1. Agregando a la aplicación (manifest) la annotations:

```yaml
annotations:
  linkerd.io/inject: enabled
```

2. Agregando al namespace el annotations linkerd.io/injec: enabled

```bash
kubectl annotate namespace linkerd.io/inject=enabled
```

3. Haciendo un deploy de una aplicación e inyectarle Linkerd:

```bash
cat deployment.yml | linkerd inject - | kubectl apply -f -
```

## Instalando la aplicación de prueba

Vamos a probar el service mes Linkerd usando la misma aplicación que instalamos con Istio.

- Creamos un namespace para nuestra aplicación de ejemplo:

```bash
kubectl create namespace bookinfo
```

- Aplicamos el annotations en el namespace:

```bash
kubectl annotate namespace bookinfo linkerd.io/inject=enabled
```

- Instalamos la aplicación:

```bash
kubectl -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio/release-1.23/samples/bookinfo/platform/kube/bookinfo.yaml
```

Vamos a crear un LoadBalancer para la aplicación o si quieres puedes hacer un port-forward:

**loadbalancer-bookinfo.yaml**

```yaml
---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-productpage
spec:
  selector:
    app: productpage
  ports:
    - port: 80
      targetPort: 9080
  type: LoadBalancer
---
```

port-fordward

```bash
kubectl -n bookinfo port-forward svc/productpage 9080:9080
```

Verificamos que Linkerd se haya inyectado en cada pod, es decir, que cada pod cuente con dos contenedores:

```bash
kubectl get pods -n bookinfo
```

o podemos ejecutar el siguiente comando:

```bash
linkerd -n bookinfo check --proxy
```

## Viz Dashboard y extensiones

Linkerd cuenta con su propio dashboard y en esta parte vamos a ver como instalarlo y realizar configuraciones de Prometheus y Grafana ya existentes en nuestro cluster (tal como hicimos en el tutorial de Istio).

Para instalar el dashboard que te incluye Prometheus y Grafana, ejecuta el siguiente comando:

```bash
linkerd viz install | kubectl apply -f -
```

En mi escenario yo ya cuento con Prometheus y Grafana instalados, por lo que tengo que tengo que pasarle ciertos parámetros a Viz, para que haga uso de lo que ya tengo instalado.

### Prometheus

Con la siguiente configuración podremos exportar las métricas del control plane y del proxy de Linkerd hacia Prometheus, tal cual hicimos en nuestro tutorial de Istio.

De igual forma puedes editar el configmap o puedes aplicar en un nuevo manifest agregando lo siguiente:

Debes modificar los valores que están dentro de {{.Values.linkerdNamespace}} y {{.Values.namespace}}.

```yaml
- job_name: "linkerd-controller"
  kubernetes_sd_configs:
    - role: pod
      namespaces:
        names:
          - "linkerd"
          - "linkerd-viz"
  relabel_configs:
    - source_labels:
        - __meta_kubernetes_pod_container_port_name
      action: keep
      regex: admin-http
    - source_labels: [__meta_kubernetes_pod_container_name]
      action: replace
      target_label: component

- job_name: "linkerd-service-mirror"
  kubernetes_sd_configs:
    - role: pod
  relabel_configs:
    - source_labels:
        - __meta_kubernetes_pod_label_linkerd_io_control_plane_component
        - __meta_kubernetes_pod_container_port_name
      action: keep
      regex: linkerd-service-mirror;admin-http$
    - source_labels: [__meta_kubernetes_pod_container_name]
      action: replace
      target_label: component

- job_name: "linkerd-proxy"
  kubernetes_sd_configs:
    - role: pod
  relabel_configs:
    - source_labels:
        - __meta_kubernetes_pod_container_name
        - __meta_kubernetes_pod_container_port_name
        - __meta_kubernetes_pod_label_linkerd_io_control_plane_ns
      action: keep
      regex: ^linkerd-proxy;linkerd-admin;linkerd$
    - source_labels: [__meta_kubernetes_namespace]
      action: replace
      target_label: namespace
    - source_labels: [__meta_kubernetes_pod_name]
      action: replace
      target_label: pod
    # special case k8s' "job" label, to not interfere with prometheus' "job"
    # label
    # __meta_kubernetes_pod_label_linkerd_io_proxy_job=foo =>
    # k8s_job=foo
    - source_labels: [__meta_kubernetes_pod_label_linkerd_io_proxy_job]
      action: replace
      target_label: k8s_job
    # drop __meta_kubernetes_pod_label_linkerd_io_proxy_job
    - action: labeldrop
      regex: __meta_kubernetes_pod_label_linkerd_io_proxy_job
    # __meta_kubernetes_pod_label_linkerd_io_proxy_deployment=foo =>
    # deployment=foo
    - action: labelmap
      regex: __meta_kubernetes_pod_label_linkerd_io_proxy_(.+)
    # drop all labels that we just made copies of in the previous labelmap
    - action: labeldrop
      regex: __meta_kubernetes_pod_label_linkerd_io_proxy_(.+)
    # __meta_kubernetes_pod_label_linkerd_io_foo=bar =>
    # foo=bar
    - action: labelmap
      regex: __meta_kubernetes_pod_label_linkerd_io_(.+)
    # Copy all pod labels to tmp labels
    - action: labelmap
      regex: __meta_kubernetes_pod_label_(.+)
      replacement: __tmp_pod_label_$1
    # Take `linkerd_io_` prefixed labels and copy them without the prefix
    - action: labelmap
      regex: __tmp_pod_label_linkerd_io_(.+)
      replacement: __tmp_pod_label_$1
    # Drop the `linkerd_io_` originals
    - action: labeldrop
      regex: __tmp_pod_label_linkerd_io_(.+)
    # Copy tmp labels into real labels
    - action: labelmap
      regex: __tmp_pod_label_(.+)
```

Ahora vamos a crear un archivo llamado prometheus-values.yaml y vamos a copiar lo siguiente para decirle a viz que haga uso de nuestro Prometheus:

```yaml
prometheusUrl: http://prometheus-service.monitoring.svc.cluster.local:8082/
prometheus:
  enabled: false
```

La primera línea es la url de Prometheus. La segunda es para decirle a Viz que no haga uso del Prometheus que instala (vamos, que haga uso de Prometheus que ya tenemos instalado).

### Linkerd Jaeger

Para instalar Jaegar es muy sencillo:

```bash
linkerd jaeger install | kubectl apply -f -
```

Verificamos que todo se haya instalado correctamente:

```bash
linkerd jaeger check
```

**Nota:** Recuerda que para que jaeger muestre las trazas la aplicación debe tener implementado tracing, en esta aplicación que estamos usando de prueba no tiene habilitado/programado el tracing:

Si se lo quieres habilitar lo puedes hacer con el siguiente comando:

```bash
kubectl -n bookinfo set env --all deploy OC_AGENT_HOST=collector.linkerd-jaeger:55678
```

Lo que hace este comando es que agrega una variable de entorno que habilita la aplicación a propagar y emitir trazas.

### Grafana

Para Grafana es más fácil, por que solo tenemos que pasarle un parámetro a Viz.

Los dashboards recomendados son:

- 14260, 11868, 14262, 14261, 14263

```bash
linkerd viz install --set grafana.url=http://grafana.ahioros.homelab.local | kubectl apply -f -
```

**NOTA:** en caso que estés usando un proveedor externo de Grafana debes usar el siguiente parámetro:

```bash
linkerd viz install --set grafana.externalUrl=https://dirección-grafana.net/ | kubectl apply -f -
```

### Comando completo

En nuestro caso tenemos que pasarle también el archivo prometheus-values.yaml por lo que el comando quedaría así:

```bash
linkerd viz install --set grafana.externalUrl=http://grafana.ahioros.homelab.local -f prometheus-values.yaml | kubectl apply -f -
```

Para obtener la funcionalidad de que aparezca el ícono de jaeger en el dashboard después de instalarlo debemos hacer lo siguiente:

linkerd viz install --set jaegerUrl=jaeger.linkerd-jaeger:16686 | kubectl apply -f -

Validamos nuevamente que todo se haya instalado correctamente:

```bash
linkerd check
```

Y si unimos todos los comandos de prometheus, grafana, jaeger tenemos:

```bash
linkerd viz install --set grafana.externalUrl=http://grafana.ahioros.homelab.local -f prometheus-values.yaml --set jaegerUrl=jaeger.linkerd-jaeger:16686 | kubectl apply -f -
```

### Linkerd Dashboard

Para ver el dashboard ejecutamos el siguiente comando (esto te abrirá una ventana en tu navegador):

```bash
linkerd viz dashboard
```


**Nota:** También puedes crearte un port-forward, LoadBalancer, Ingress, para ver el dashboard.

Al igual que con Istio la comunicación entre los microservicios es cifrada, te puedes dar cuenta aquí:


O entrando a algún Deployment y verás en la columna superior derecha que dice **meshed**

## Desinstalación de Linkerd

- Eliminamos la aplicación:

```bash
kubectl delete ns bookinfo
```

- Eliminar las extensiones:

```bash
linkerd viz uninstall | kubectl delete -f -
```

- Eliminamos jaeger:

```bash
linkerd jaeger uninstall | kubectl delete -f -
```

- Eliminar el control plane, CRDs, namespace, etc:

```bash
linkerd uninstall | kubectl delete -f -
```

Listo espero te haya funcionado si tienes dudas o comentarios no dudes en contactarme o dejarme tu comentario, saludos.

No hay comentarios.: