Este artículo es la segunda parte de la serie Beats. Se recomienda leer previamente Beats Parte 1 – ¿Conoces los Beats de Elasticsearch? Introducción y casos de uso.
Introducción
Vamos a ver cómo se pueden desplegar ciertos Beats en una infraestructura cloud de Kubernetes de cara a extraer todos los indicadores de rendimiento y disponibilidad útiles de todos los elementos del cluster.
Algunos Beats están pensandos para instalarse en clusters de Kubernetes para permitir extraer datos de todo el cluster de forma sencilla y centralizada, ya sea a nivel de sistema (cpu, memoria, etc…) a nivel de aplicación (jvm heap, nginx requests, etc…), o recursos propios de k8s (tiempo de respuesta, métricas DNS, …)
Una de las formas es instalarlo de forma efectiva es como Daemonset, para que se levante por cada nodo del cluster un Pod con el Beat deseado de cara a que cada Pod extraiga los datos del Node de k8s sobre el cual se ha desplegado.
Realizarlo de esta forma nos permite utilizar metricbeat, filebeat o heartbeat con las funcionalidades de Autodiscover que, una vez se encuentren correctamente configurados, monitorizar una aplicación será tan sencillo como poner anotaciones de k8s a nivel de pod o de deployment para indicar qué información queremos extraer.
Comentaremos el uso de Autodiscover en la tercera parte de esta serie de artículos.
Instalación de Filebeat sobre Kubernetes
Recursos de Kubernetes necesarios
Es necesario adaptar y aplicar estos recursos en un cluster de k8s. Identificar primero qué namespace se utilizará para la instalación.
Se crearán objetos de tipo ServiceAccount y ClusterRole de cara a permitir a Filebeat acceder a los demás espacios de nombres del cluster, listar sus pods, extraer sus métricas y metadatos.
Aplicar estos recursos, ya sea mediante kubectl apply o cualquier gestor de recursos de Kubernetes.
Service account
--- apiVersion: v1 kind: ServiceAccount metadata: name: filebeat-dynamic namespace: iometrics-pro #Adaptar labels: k8s-app: filebeat-dynamic
Creamos el ServiceAccount sobre el namespace para permitir a filebeat interactuar con la API de kubernetes
ClusterRole
--- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: filebeat-dynamic labels: k8s-app: filebeat-dynamic rules: - apiGroups: [""] # "" Indica que se solicita acceder al "Core" de la API resources: - namespaces - pods - nodes verbs: - get - watch - list
Creamos un ClusterRole con los permisos acotados a los recursos de la API a los cuales necesitaremos acceder
ClusterRoleBinding
--- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: filebeat-dynamic subjects: - kind: ServiceAccount name: filebeat-dynamic namespace: kube-system roleRef: kind: ClusterRole name: filebeat-dynamic apiGroup: rbac.authorization.k8s.io
Aplicamos un ClusterRoleBinding, para asociar el ServiceAccount con ClusterRole previamente creados
DaemonSet
--- apiVersion: apps/v1 kind: DaemonSet metadata: name: filebeat-dynamic labels: k8s-app: filebeat-dynamic spec: selector: matchLabels: k8s-app: filebeat-dynamic template: metadata: labels: k8s-app: filebeat-dynamic name: filebeat-dynamic spec: serviceAccountName: filebeat-dynamic terminationGracePeriodSeconds: 10 hostNetwork: true dnsPolicy: ClusterFirstWithHostNet containers: - name: filebeat image: docker.elastic.co/beats/filebeat:7.16.2 # Versión deseada imagePullPolicy: Always args: [ "-c", "/filebeat/filebeat.yml", "-e"] env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName securityContext: runAsUser: 0 resources: limits: cpu: 200m memory: 200Mi requests: cpu: 10m memory: 50Mi volumeMounts: - name: data mountPath: /usr/share/filebeat/data - name: config mountPath: /filebeat/filebeat.yml readOnly: false subPath: filebeat.yml volumes: - name: data hostPath: path: /var/lib/filebeat-data type: DirectoryOrCreate - name: config configMap: defaultMode: 0640 name: filebeat-config
Aplicamos el Daemonset, que será el encargado de levantar un Pod por cada nodo disponible del cluster. En él se indica el origen de la imagen de filebeat, argumentos de arranque del proceso, la variable de entorno NODE_NAME que utilizará internamente filebeat para saber sobre qué nodo está corriendo, límites de CPU y de memoria para la gestión de recursos del pod y volumen para la persistencia de datos de filebeat además del filebeat.yml que contiene toda la configuración que utiliza filebeat y que se monta como un configMap que definimos a continuación.
ConfigMap
--- apiVersion: v1 kind: ConfigMap metadata: name: filebeat-config labels: k8s-app: filebeat-dynamic data: filebeat.yml: |- setup.template.enabled: true filebeat.inputs: - type: container paths: - /var/log/containers/*.log processors: - add_kubernetes_metadata: host: ${NODE_NAME} matchers: - logs_path: logs_path: "/var/log/containers/" processors: - add_cloud_metadata: - add_host_metadata: output.elasticsearch: ... # Ver documentación de elasticsearch para configurar según necesidad
Es necesario adaptar la configuración a las necesidades del caso de uso. Ver la documentación oficial de filebeat para configuración avanzada.
Con la directiva setup.template.enabled, al levantarse filebeat por primera vez se realizará el setup, que consiste en enviar a Elasticsearch los index templates que llevarán los mappings y políticas de ILM necesarios para almacenar y estructurar de forma correcta los datos en los índices filebeat-*.
También existe otra opción setup.dashboards.enabled que permite subir los dashboards predefinidos que se pueden visualizar en la Parte 1. Necesita configuración adicional para apuntar a Kibana, ya que los dashboards se suben a ese componente.
Con filebeat.inputs, ya le estamos indicando a filebeat que extraiga los logs de todos los contenedores por lo que en cuanto se levante empezará a enviarlos a Elasticsearch.
Verificar el despliegue
Una vez que se han aplicado correctamente todos los recursos de kubernetes, procederemos a verificar que se ha levantado correctamente un pod por cada nodo del cluster, y que sus estados son “Running”.
También es buena práctica hacer describe del Daemonset y de un Pod, además de revisar los logs de un Pod para descartar mensajes de error y verificar que todo ha funcionado correctamente.
Verificar la recepción de los datos
Ubicarse en Kibana, al índice configurado para la recepción (por defecto filebeat-*). Ver que se reciben correctamente los logs de los distintos contenedores desplegados en el cluster de Kubernetes.