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:
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:
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.
linkerd check --pre
El último paso de la instalación es instalar el CRD de Linkerd en nuestro cluster:
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -
Para la validación de la instalación puedes ejecutar el siguiente comando:
linkerd check
o puedes verificar que ya está en estado RUNNING todo lo que se encuentra en el namespace linkerd:
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:
- Agregando a la aplicación (manifest) la annotations:
annotations:
linkerd.io/inject: enabled
- Agregando al namespace el annotations linkerd.io/injec: enabled
kubectl annotate namespace linkerd.io/inject=enabled
- Haciendo un deploy de una aplicación e inyectarle Linkerd:
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:
kubectl create namespace bookinfo
- Aplicamos el annotations en el namespace:
kubectl annotate namespace bookinfo linkerd.io/inject=enabled
- Instalamos la aplicación:
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
---
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-productpage
spec:
selector:
app: productpage
ports:
- port: 80
targetPort: 9080
type: LoadBalancer
---
port-fordward
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:
kubectl get pods -n bookinfo
o podemos ejecutar el siguiente comando:
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:
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}}.
- 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:
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:
linkerd jaeger install | kubectl apply -f -
Verificamos que todo se haya instalado correctamente:
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:
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
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:
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í:
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:
linkerd check
Y si unimos todos los comandos de prometheus, grafana, jaeger tenemos:
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):
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:
kubectl delete ns bookinfo
- Eliminar las extensiones:
linkerd viz uninstall | kubectl delete -f -
- Eliminamos jaeger:
linkerd jaeger uninstall | kubectl delete -f -
- Eliminar el control plane, CRDs, namespace, etc:
linkerd uninstall | kubectl delete -f -
Listo espero te haya funcionado si tienes dudas o comentarios no dudes en contactarme o dejarme tu comentario, saludos.