
Si en el anterior post se realizaba una introducción a los operadores, con este se pretende dar inicio a una serie de artículos en los que describir las principales herramientas de monitorización en Kubernetes y su proceso de instalación mediante operadores.
Como bien deja intuir el título, esta primera entrega estará centrada en Jaeger, el popular sistema de tracing distribuido, con persistencia sobre una base de datos Cassandra. Sin más dilación, comenzamos.
Caso de uso
Se dispone de una cluster “vanilla” de Kubernetes, compuesto por un único nodo y con varios microservicios desplegados, en el que se quiere instalar un Jaeger con persistencia sobre Cassandra, haciendo uso de los correspondientes operadores.
¿Que es Jaeger?
Jaeger es un sistema de trazabilidad distribuida open source, desarrollado por Uber, con el que poder monitorizar lo que ocurre a nivel de red en un sistema de microservicios distribuido. Es decir, permite realizar un seguimiento de los microservicios por los que pasa una petición, identificar a que instancia en concreto a accede, medir el tiempo exacto invertido en cada punto o la latencia de red entre otros factores.
A diferencia de Zipkin, el otro gran sistema de trazabilidad distribuida, Jaeger está basado en el estandar de Opentracing definido por Google y acogido por la CNCF (Cloud Native Computing Foundation), lo que permite que su implementación no esté atada a un producto en específico y que en el futuro pueda ser sustituir por otra alternativa de forma transparente.
El funcionamiento es el siguiente, Jaeger despliega sobre Kubernetes un collector encargado de recolectar y persistir las trazas que deberán ser enviadas por los microservicios, ya sea mediante una librería embebida, un agente o por Istio. Estas trazas pueden ser almacenadas en memoria (sin persistencia entre reinicios), Kafka, Elasticsearch o Cassandra, pero para el caso de uso definido se hará uso de esta última.
Finalmente el producto dispone de una Web UI construida sobre React con la que visualizar los datos recolectados.
Instalación
Helm
Para la instalación de Jaeger y Cassandra será necesario disponer de Helm, la herramienta para la instalación, actualización y gestión de aplicaciones complejas sobre entornos Kubernetes.
En esencia se compone de dos partes:
- Helm: Es el cliente local para la interacción/gestión de las aplicaciones sobre Kubernetes.
- Tiller: Es el componente instalado sobre Kubernetes encargado de gestionar las aplicaciones instaladas.
Como Tiller requiere de permisos específicos para la gestión de recursos en Kubernetes, se debe crear un nuevo Service Account con rol de administrador.
# Create ServiceAccount for Tiller
kubectl -n kube-system create sa tiller
# Create ClusterRoleBinding for Tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
Finalmente solo queda instalar la instalación de Tiller via Helm.
# Install tiller
helm init --service-account tiller
Cassandra
Apache Cassandra es una base de datos NoSQL distribuida escrita en java y basada en un modelo de almacenamiento clave-valor.
Aunque el operador se encuentre actualmente en estado alpha, lo cierto es que funciona francamente bien para el cometido designado, que no es otro que almacenar las trazas de Jaeger.
Para ello, el primer paso será descargarse las plantillas de Helm del operador desde el repositorio de GitHub, ya que en el momento de escribir este artículo no se encuentran subidas a ningún repositorio de charts.
Una vez descargadas, será necesiario editar el fichero helm/cassandra-operator/templates/deployment.yaml y añadir un comando para el arranque del contenedor, en el que se defina el namespace de instalación cassandra-system, ya que de lo contrario será instalado en el default.
...
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
command: ["java"]
args: ["-jar", "/opt/lib/cassandra-operator/cassandra-operator.jar", "--namespace=NAMESPACE"]
...
Antes de proceder con la instalación, es recomendable revisar el fichero helm/cassandra-operator/values.yaml, por si se quisiera modificar alguno de sus valores, pero en principio no es necesario para el caso de uso actual. Una vez revisado, se procede a instalar el operador vía Helm:
# Create namespaces
kubectl create namespace cassandra-system
# Install Cassandra operator
helm install helm/cassandra-operator -n cassandra-operator --namespace=cassandra-system
Con el operador ya desplegado, es el momento de definir la configuración de Cassandra mediante otro chart de Helm, que también deberá ser descargado desde GitHub. Este chart se compone únicamente de un CRD denominado CassandraDataCenter, que al ser desplegado en Kubernetes será leído por el operador y creará el cluster de Cassandra definido en él.
De nuevo, antes de proceder con la instalación, es recomendable revisar el fichero Helm/cassandra/values.yaml, por si se quisiera modificar alguno de sus valores, como por ejemplo, el scrapping de Prometheus. Una vez revisado, es el momento de instalar Cassandra vía Helm:
# Install Cassandra
helm install helm/cassandra -n cassandra --namespace=cassandra-system
(Es muy importante que, para poder conectarse después con Jaeger, el nombre de la release de Cassandra no lleve guiones.)
Jaeger
Una vez instalado el sistema de persistencia, es hora de proceder con el despliegue del operador de Jaeger, si bien esta vez no será necesario descargar los charts de GitHub, ya que se encuentran subidos al repositorio oficial de Helm.
Como siempre, es recomendable revisar el fichero values, por si se quisiera modificar alguno de sus valores, pero en principio no es necesario para el caso de uso actual. Una vez revisado, es el momento de instalar el operador vía Helm:
# Create namespace
kubectl create namespace jaeger-system
# Install Jaeger operator
helm install stable/jaeger-operator -n jaeger-operator --namespaces=jaeger-system
Con el operador ya desplegado, es el momento de definir la configuración de Jaeger, pero esta vez sin chart de Helm, ya que no se encuentra disponible en el momento de escribir este artículo. Simplemente habrá que crear un CRD denominado Jaeger, que al ser creado en Kubernetes será leído por el operador y desplegará los componentes de Jaeger con la configuración especificada.
En esta ocasión, la configuración proporcionada será la específica para funcionar junto a Cassandra, si bien podéis encontrar más ejemplos en el repositorio de GitHub.
kubectl apply -f - <<EOF
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: jaeger
namespace: jaeger-system
spec:
strategy: production
storage:
type: cassandra
options:
cassandra:
servers: cassandra-cassandra-nodes.cassandra-system.svc.cluster.local
keyspace: jaeger_v1_cassandra
cassandraCreateSchema:
datacenter: cassandra
ingress:
enabled: true
EOF
Como se puede observar, se ha definido la propiedad “ingress” a true para exponer la Web UI al exterior.
Conclusiones
En conclusión, los operadores de Jaeger y Cassandra, sin ser especialmente avanzados, permiten simplificar la instalación de ambos productos y dejar preparado un completo sistema de tracing distribuido.
Eso sí, será necesario configurar los microservicios, el agente de Jaeger, Istio o vuestra solución favorita para enviar las trazas al collector de Jaeger.