Cómo configurar una pila de registro de Elasticsearch, Fluentd y Kibana (EFK) en Kubernetes

Introducción
Al ejecutar varios servicios y aplicaciones en un clúster de Kubernetes, una pila de registro centralizada a nivel de clúster puede ayudarlo a clasificar y analizar rápidamente el gran volumen de datos de registro generados por sus pods. Una solución de registro centralizada popular es la pila de Elasticsearch , Fluentd y Kibana (EFK).
Elasticsearch es un motor de búsqueda distribuido, escalable y en tiempo real que permite realizar búsquedas de texto completo y estructuradas, así como análisis. Se utiliza habitualmente para indexar y buscar en grandes volúmenes de datos de registro, pero también se puede utilizar para buscar en muchos tipos diferentes de documentos.
Elasticsearch se implementa comúnmente junto con Kibana , una potente interfaz de visualización de datos y un panel de control para Elasticsearch. Kibana le permite explorar sus datos de registro de Elasticsearch a través de una interfaz web y crear paneles de control y consultas para responder preguntas rápidamente y obtener información sobre sus aplicaciones de Kubernetes.
En este tutorial, utilizaremos Fluentd para recopilar, transformar y enviar datos de registro al backend de Elasticsearch. Fluentd es un recopilador de datos de código abierto popular que configuraremos en nuestros nodos de Kubernetes para rastrear archivos de registro de contenedores, filtrar y transformar los datos de registro y enviarlos al clúster de Elasticsearch, donde se indexarán y almacenarán.
Comenzaremos configurando y lanzando un clúster de Elasticsearch escalable y luego crearemos el servicio y la implementación de Kibana Kubernetes. Para concluir, configuraremos Fluentd como un DaemonSet para que se ejecute en cada nodo de trabajo de Kubernetes.
Si está buscando un servicio de alojamiento de Kubernetes administrado, consulte nuestro servicio de Kubernetes simple y administrado diseñado para el crecimiento.
Prerrequisitos
Antes de comenzar con esta guía, asegúrese de tener lo siguiente disponible:
-
Un clúster de Kubernetes 1.10+ con control de acceso basado en roles (RBAC) habilitado
- Asegúrese de que su clúster tenga suficientes recursos disponibles para implementar la pila EFK y, si no es así, escale su clúster agregando nodos de trabajo. Implementaremos un clúster Elasticsearch de 3 pods (puede reducirlo a 1 si es necesario), así como un solo pod de Kibana. Cada nodo de trabajo también ejecutará un pod de Fluentd. El clúster de esta guía consta de 3 nodos de trabajo y un plano de control administrado.
-
La
kubectl
herramienta de línea de comandos instalada en su máquina local, configurada para conectarse a su clúster. Puede leer más sobre la instalaciónkubectl
en la documentación oficial.
Una vez que tenga estos componentes configurados, estará listo para comenzar con esta guía.
Paso 1: creación de un espacio de nombres
Antes de implementar un clúster de Elasticsearch, primero crearemos un espacio de nombres en el que instalaremos toda nuestra instrumentación de registro. Kubernetes le permite separar los objetos que se ejecutan en su clúster mediante una abstracción de "clúster virtual" llamada espacios de nombres. En esta guía, crearemos un kube-logging
espacio de nombres en el que instalaremos los componentes de la pila EFK. Este espacio de nombres también nos permitirá limpiar y eliminar rápidamente la pila de registro sin ninguna pérdida de función para el clúster de Kubernetes.
Para comenzar, primero investigue los espacios de nombres existentes en su clúster utilizando kubectl
:
- kubectl get namespaces
Debería ver los siguientes tres espacios de nombres iniciales, que vienen preinstalados con su clúster de Kubernetes:
OutputNAME STATUS AGEdefault Active 5mkube-system Active 5mkube-public Active 5m
El default
espacio de nombres alberga objetos que se crean sin especificar un espacio de nombres. El kube-system
espacio de nombres contiene objetos creados y utilizados por el sistema Kubernetes, como kube-dns
, kube-proxy
y kubernetes-dashboard
. Es una buena práctica mantener este espacio de nombres limpio y no contaminarlo con las cargas de trabajo de instrumentación y aplicación.
El kube-public
espacio de nombres es otro espacio de nombres creado automáticamente que se puede utilizar para almacenar objetos que desea que sean legibles y accesibles en todo el clúster, incluso para usuarios no autenticados.
Para crear el kube-logging
espacio de nombres, primero abra y edite un archivo llamado kube-logging.yaml
usando su editor favorito, como nano:
- nano kube-logging.yaml
Dentro de su editor, pegue el siguiente objeto de espacio de nombres YAML:
kube-logging.yaml
kind: NamespaceapiVersion: v1metadata: name: kube-logging
Luego, guarde y cierre el archivo.
Aquí, especificamos los objetos de Kubernetes kind
como un Namespace
objeto. Para obtener más información sobre Namespace
los objetos, consulte el Tutorial de espacios de nombres en la documentación oficial de Kubernetes. También especificamos la versión de la API de Kubernetes utilizada para crear el objeto ( v1
) y le asignamos un name
, kube-logging
.
Una vez que haya creado el kube-logging.yaml
archivo de objeto de espacio de nombres, cree el espacio de nombres utilizando kubectl create
el -f
indicador de nombre de archivo:
- kubectl create -f kube-logging.yaml
Deberías ver el siguiente resultado:
Outputnamespace/kube-logging created
Luego puedes confirmar que el espacio de nombres se creó correctamente:
- kubectl get namespaces
En este punto, deberías ver el nuevo kube-logging
espacio de nombres:
OutputNAME STATUS AGEdefault Active 23mkube-logging Active 1mkube-public Active 23mkube-system Active 23m
Ahora podemos implementar un clúster Elasticsearch en este espacio de nombres de registro aislado.
Paso 2: Creación del conjunto de estado de Elasticsearch
Ahora que hemos creado un espacio de nombres para alojar nuestra pila de registro, podemos comenzar a implementar sus diversos componentes. Primero, comenzaremos implementando un clúster Elasticsearch de 3 nodos.
En esta guía, utilizamos 3 pods de Elasticsearch para evitar el problema de "cerebro dividido" que ocurre en clústeres de múltiples nodos de alta disponibilidad. En un nivel alto, el "cerebro dividido" es lo que surge cuando uno o más nodos no pueden comunicarse con los demás y se eligen varios maestros "divididos". Con 3 nodos, si uno se desconecta del clúster temporalmente, los otros dos nodos pueden elegir un nuevo maestro y el clúster puede continuar funcionando mientras el último nodo intenta volver a unirse. Para obtener más información, consulte Una nueva era para la coordinación de clústeres en Elasticsearch y configuraciones de votación.
Creación del servicio sin interfaz gráfica
Para comenzar, crearemos un servicio de Kubernetes sin interfaz gráfica llamado elasticsearch
que definirá un dominio DNS para los 3 pods. Un servicio sin interfaz gráfica no realiza balanceo de carga ni tiene una IP estática; para obtener más información sobre los servicios sin interfaz gráfica, consulte la documentación oficial de Kubernetes.
Abra un archivo llamado elasticsearch_svc.yaml
usando su editor favorito:
- nano elasticsearch_svc.yaml
Pegue el siguiente YAML del servicio Kubernetes:
Elasticsearch_svc.yaml
kind: ServiceapiVersion: v1metadata: name: elasticsearch namespace: kube-logging labels: app: elasticsearchspec: selector: app: elasticsearch clusterIP: None ports: - port: 9200 name: rest - port: 9300 name: inter-node
Luego, guarde y cierre el archivo.
Definimos un Service
objeto llamado elasticsearch
en el kube-logging
espacio de nombres y le asignamos la app: elasticsearch
etiqueta. Luego, configuramos el .spec.selector
objeto app: elasticsearch
para que el servicio seleccione los pods con la app: elasticsearch
etiqueta. Cuando asociamos nuestro Elasticsearch StatefulSet con este servicio, el servicio devolverá registros DNS A que apuntan a los pods de Elasticsearch con la app: elasticsearch
etiqueta.
Luego, configuramos clusterIP: None
, que hace que el servicio sea headless. Por último, definimos los puertos 9200
y 9300
que se utilizan para interactuar con la API REST y para la comunicación entre nodos, respectivamente.
Crea el servicio usando kubectl
:
- kubectl create -f elasticsearch_svc.yaml
Deberías ver el siguiente resultado:
Outputservice/elasticsearch created
Por último, vuelva a verificar que el servicio se haya creado correctamente utilizando kubectl get
:
kubectl get services --namespace=kube-logging
Deberías ver lo siguiente:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEelasticsearch ClusterIP None none 9200/TCP,9300/TCP 26s
Ahora que hemos configurado nuestro servicio sin interfaz gráfica y un .elasticsearch.kube-logging.svc.cluster.local
dominio estable para nuestros pods, podemos continuar y crear el StatefulSet.
Creando el StatefulSet
Un StatefulSet de Kubernetes le permite asignar una identidad estable a los pods y otorgarles almacenamiento estable y persistente. Elasticsearch requiere almacenamiento estable para conservar los datos durante la reprogramación y los reinicios de los pods. Para obtener más información sobre la carga de trabajo StatefulSet, consulte la página Statefulsets de la documentación de Kubernetes.
Abra un archivo llamado elasticsearch_statefulset.yaml
en su editor favorito:
- nano elasticsearch_statefulset.yaml
Nos desplazaremos a través de la definición del objeto StatefulSet sección por sección, pegando bloques en este archivo.
Comience pegando el siguiente bloque:
Conjunto de estado elástico de búsqueda.yaml
apiVersion: apps/v1kind: StatefulSetmetadata: name: es-cluster namespace: kube-loggingspec: serviceName: elasticsearch replicas: 3 selector: matchLabels: app: elasticsearch template: metadata: labels: app: elasticsearch
En este bloque, definimos un StatefulSet llamado es-cluster
en el kube-logging
espacio de nombres. Luego, lo asociamos con nuestro elasticsearch
servicio creado previamente mediante el serviceName
campo. Esto garantiza que cada Pod en el StatefulSet será accesible mediante la siguiente dirección DNS: es-cluster-[0,1,2].elasticsearch.kube-logging.svc.cluster.local
, donde [0,1,2]
corresponde al ordinal entero asignado del Pod.
Especificamos 3 replicas
(Pods) y establecemos el matchLabels
selector en app: elasticseach
, que luego reflejamos en la .spec.template.metadata
sección. Los campos .spec.selector.matchLabels
y .spec.template.metadata.labels
deben coincidir.
Ahora podemos pasar a la especificación del objeto. Pegue el siguiente bloque de YAML inmediatamente debajo del bloque anterior:
Conjunto de estado elástico de búsqueda.yaml
. . . spec: containers: - name: elasticsearch image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0 resources: limits: cpu: 1000m requests: cpu: 100m ports: - containerPort: 9200 name: rest protocol: TCP - containerPort: 9300 name: inter-node protocol: TCP volumeMounts: - name: data mountPath: /usr/share/elasticsearch/data env: - name: cluster.name value: k8s-logs - name: node.name valueFrom: fieldRef: fieldPath: metadata.name - name: discovery.seed_hosts value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch" - name: cluster.initial_master_nodes value: "es-cluster-0,es-cluster-1,es-cluster-2" - name: ES_JAVA_OPTS value: "-Xms512m -Xmx512m"
Aquí definimos los Pods en el StatefulSet. Nombramos los contenedores elasticsearch
y elegimos la docker.elastic.co/elasticsearch/elasticsearch:7.2.0
imagen de Docker. En este punto, puedes modificar esta etiqueta de imagen para que corresponda con tu propia imagen interna de Elasticsearch o con una versión diferente. Ten en cuenta que, a los efectos de esta guía, solo 7.2.0
se ha probado Elasticsearch.
Luego, usamos el resources
campo para especificar que el contenedor necesita al menos 0,1 vCPU garantizados y puede alcanzar hasta 1 vCPU (lo que limita el uso de recursos del pod cuando se realiza una ingesta inicial grande o se enfrenta a un pico de carga). Debe modificar estos valores según la carga prevista y los recursos disponibles. Para obtener más información sobre las solicitudes y los límites de recursos, consulte la documentación oficial de Kubernetes.
Luego, abrimos y nombramos los puertos 9200
y 9300
para la API REST y la comunicación entre nodos, respectivamente. Especificamos un volumeMount
llamado data
que montará el PersistentVolume nombrado data
en el contenedor en la ruta /usr/share/elasticsearch/data
. Definiremos los VolumeClaims para este StatefulSet en un bloque YAML posterior.
Finalmente, establecemos algunas variables de entorno en el contenedor:
cluster.name
:El nombre del clúster Elasticsearch, que en esta guía esk8s-logs
.node.name
: El nombre del nodo, que establecemos en el.metadata.name
campo mediantevalueFrom
. Esto se resolverá enes-cluster-[0,1,2]
, según el ordinal asignado al nodo.discovery.seed_hosts
: Este campo establece una lista de nodos que cumplen los requisitos para ser maestros en el clúster y que generarán el proceso de descubrimiento de nodos. En esta guía, gracias al servicio sin interfaz gráfica que configuramos anteriormente, nuestros pods tienen dominios con el formatoes-cluster-[0,1,2].elasticsearch.kube-logging.svc.cluster.local
, por lo que configuramos esta variable en consecuencia. Si utilizamos la resolución DNS de Kubernetes en el espacio de nombres local, podemos acortarlo aes-cluster-[0,1,2].elasticsearch
. Para obtener más información sobre el descubrimiento de Elasticsearch, consulte la documentación oficial de Elasticsearch.cluster.initial_master_nodes
: Este campo también especifica una lista de nodos elegibles para ser maestros que participarán en el proceso de elección de maestros. Tenga en cuenta que para este campo debe identificar los nodos por sunode.name
, y no por sus nombres de host.ES_JAVA_OPTS
:Aquí configuramos esto para-Xms512m -Xmx512m
indicarle a la JVM que use un tamaño de montón mínimo y máximo de 512 MB. Debe ajustar estos parámetros según la disponibilidad y las necesidades de recursos de su clúster. Para obtener más información, consulte Configurar el tamaño del montón.
El siguiente bloque que pegaremos tendrá el siguiente aspecto:
Conjunto de estado elástico de búsqueda.yaml
. . . initContainers: - name: fix-permissions image: busybox command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"] securityContext: privileged: true volumeMounts: - name: data mountPath: /usr/share/elasticsearch/data - name: increase-vm-max-map image: busybox command: ["sysctl", "-w", "vm.max_map_count=262144"] securityContext: privileged: true - name: increase-fd-ulimit image: busybox command: ["sh", "-c", "ulimit -n 65536"] securityContext: privileged: true
En este bloque, definimos varios contenedores de inicio que se ejecutan antes del elasticsearch
contenedor de la aplicación principal. Estos contenedores de inicio se ejecutan hasta su finalización en el orden en que se definen. Para obtener más información sobre los contenedores de inicio, consulte la documentación oficial de Kubernetes.
El primero, llamado fix-permissions
, ejecuta un chown
comando para cambiar el propietario y el grupo del directorio de datos de Elasticsearch a 1000:1000
, el UID del usuario de Elasticsearch. De manera predeterminada, Kubernetes monta el directorio de datos como root
, lo que lo hace inaccesible para Elasticsearch. Para obtener más información sobre este paso, consulte las “Notas para el uso en producción y valores predeterminados” de Elasticsearch.
El segundo, llamado increase-vm-max-map
, ejecuta un comando para aumentar los límites del sistema operativo en cuanto a los recuentos de mmap, que de forma predeterminada pueden ser demasiado bajos, lo que genera errores de falta de memoria. Para obtener más información sobre este paso, consulte la documentación oficial de Elasticsearch.
El siguiente contenedor Init que se ejecuta es increase-fd-ulimit
, que ejecuta el ulimit
comando para aumentar la cantidad máxima de descriptores de archivos abiertos. Para obtener más información sobre este paso, consulte las “Notas para el uso en producción y valores predeterminados” en la documentación oficial de Elasticsearch.
Nota: Las Notas de Elasticsearch para uso en producción también mencionan la desactivación del intercambio por razones de rendimiento. Según la instalación o el proveedor de Kubernetes, es posible que el intercambio ya esté desactivado. Para comprobarlo, exec
ingrese a un contenedor en ejecución y ejecute cat /proc/swaps
para enumerar los dispositivos de intercambio activos. Si no ve nada allí, el intercambio está desactivado.
Ahora que hemos definido nuestro contenedor de aplicación principal y los contenedores Init que se ejecutan antes para ajustar el sistema operativo del contenedor, podemos agregar la pieza final a nuestro archivo de definición de objeto StatefulSet: el volumeClaimTemplates
.
Pegue en el siguiente volumeClaimTemplate
bloque:
Conjunto de estado elástico de búsqueda.yaml
. . . volumeClaimTemplates: - metadata: name: data labels: app: elasticsearch spec: accessModes: [ "ReadWriteOnce" ] storageClassName: do-block-storage resources: requests: storage: 100Gi
En este bloque, definimos el StatefulSet volumeClaimTemplates
. Kubernetes lo usará para crear PersistentVolumes para los Pods. En el bloque anterior, le asignamos un nombre data
(que es el que name
mencionamos en el volumeMount
s definido anteriormente) y le asignamos la misma app: elasticsearch
etiqueta que nuestro StatefulSet.
Luego, especificamos su modo de acceso como ReadWriteOnce
, lo que significa que solo puede ser montado como lectura-escritura por un solo nodo. Definimos la clase de almacenamiento como do-block-storage
en esta guía, ya que usamos un clúster Kubernetes de DigitalOcean para fines de demostración. Debe cambiar este valor según dónde esté ejecutando su clúster Kubernetes. Para obtener más información, consulte la documentación de Volumen persistente.
Por último, especificamos que queremos que cada PersistentVolume tenga un tamaño de 100 GiB. Debes ajustar este valor según tus necesidades de producción.
La especificación completa de StatefulSet debería verse así:
Conjunto de estado elástico de búsqueda.yaml
apiVersion: apps/v1kind: StatefulSetmetadata: name: es-cluster namespace: kube-loggingspec: serviceName: elasticsearch replicas: 3 selector: matchLabels: app: elasticsearch template: metadata: labels: app: elasticsearch spec: containers: - name: elasticsearch image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0 resources: limits: cpu: 1000m requests: cpu: 100m ports: - containerPort: 9200 name: rest protocol: TCP - containerPort: 9300 name: inter-node protocol: TCP volumeMounts: - name: data mountPath: /usr/share/elasticsearch/data env: - name: cluster.name value: k8s-logs - name: node.name valueFrom: fieldRef: fieldPath: metadata.name - name: discovery.seed_hosts value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch" - name: cluster.initial_master_nodes value: "es-cluster-0,es-cluster-1,es-cluster-2" - name: ES_JAVA_OPTS value: "-Xms512m -Xmx512m" initContainers: - name: fix-permissions image: busybox command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"] securityContext: privileged: true volumeMounts: - name: data mountPath: /usr/share/elasticsearch/data - name: increase-vm-max-map image: busybox command: ["sysctl", "-w", "vm.max_map_count=262144"] securityContext: privileged: true - name: increase-fd-ulimit image: busybox command: ["sh", "-c", "ulimit -n 65536"] securityContext: privileged: true volumeClaimTemplates: - metadata: name: data labels: app: elasticsearch spec: accessModes: [ "ReadWriteOnce" ] storageClassName: do-block-storage resources: requests: storage: 100Gi
Una vez que esté satisfecho con su configuración de Elasticsearch, guarde y cierre el archivo.
Ahora, implemente el StatefulSet usando kubectl
:
- kubectl create -f elasticsearch_statefulset.yaml
Deberías ver el siguiente resultado:
Outputstatefulset.apps/es-cluster created
Puede supervisar el StatefulSet a medida que se implementa mediante kubectl rollout status
:
- kubectl rollout status sts/es-cluster --namespace=kube-logging
Debería ver el siguiente resultado a medida que se implementa el clúster:
OutputWaiting for 3 pods to be ready...Waiting for 2 pods to be ready...Waiting for 1 pods to be ready...partitioned roll out complete: 3 new pods have been updated...
Una vez que se hayan implementado todos los pods, puede verificar que su clúster Elasticsearch esté funcionando correctamente realizando una solicitud a la API REST.
Para ello, primero reenvíe el puerto local 9200
al puerto 9200
en uno de los nodos Elasticsearch ( es-cluster-0
) usando kubectl port-forward
:
- kubectl port-forward es-cluster-0 9200:9200 --namespace=kube-logging
Luego, en una ventana de terminal separada, realice una curl
solicitud contra la API REST:
- curl http://localhost:9200/_cluster/state?pretty
Deberías ver el siguiente resultado:
Output{ "cluster_name" : "k8s-logs", "compressed_size_in_bytes" : 348, "cluster_uuid" : "QD06dK7CQgids-GQZooNVw", "version" : 3, "state_uuid" : "mjNIWXAzQVuxNNOQ7xR-qg", "master_node" : "IdM5B7cUQWqFgIHXBp0JDg", "blocks" : { }, "nodes" : { "u7DoTpMmSCixOoictzHItA" : { "name" : "es-cluster-1", "ephemeral_id" : "ZlBflnXKRMC4RvEACHIVdg", "transport_address" : "10.244.8.2:9300", "attributes" : { } }, "IdM5B7cUQWqFgIHXBp0JDg" : { "name" : "es-cluster-0", "ephemeral_id" : "JTk1FDdFQuWbSFAtBxdxAQ", "transport_address" : "10.244.44.3:9300", "attributes" : { } }, "R8E7xcSUSbGbgrhAdyAKmQ" : { "name" : "es-cluster-2", "ephemeral_id" : "9wv6ke71Qqy9vk2LgJTqaA", "transport_address" : "10.244.40.4:9300", "attributes" : { } } },...
Esto indica que nuestro clúster Elasticsearch k8s-logs
se ha creado correctamente con 3 nodos: es-cluster-0
, es-cluster-1
y es-cluster-2
. El nodo maestro actual es es-cluster-0
.
Ahora que su clúster Elasticsearch está en funcionamiento, puede continuar configurando una interfaz de Kibana para él.
Paso 3: creación de la implementación y el servicio de Kibana
Para iniciar Kibana en Kubernetes, crearemos un servicio llamado kibana
y una implementación que consta de una réplica de pod. Puede escalar la cantidad de réplicas según sus necesidades de producción y, opcionalmente, especificar un LoadBalancer
tipo para el servicio para equilibrar la carga de las solicitudes en los pods de implementación.
Esta vez, crearemos el servicio y la implementación en el mismo archivo. Abra un archivo llamado kibana.yaml
en su editor favorito:
- nano kibana.yaml
Pegue la siguiente especificación de servicio:
kibana.yaml
apiVersion: v1kind: Servicemetadata: name: kibana namespace: kube-logging labels: app: kibanaspec: ports: - port: 5601 selector: app: kibana---apiVersion: apps/v1kind: Deploymentmetadata: name: kibana namespace: kube-logging labels: app: kibanaspec: replicas: 1 selector: matchLabels: app: kibana template: metadata: labels: app: kibana spec: containers: - name: kibana image: docker.elastic.co/kibana/kibana:7.2.0 resources: limits: cpu: 1000m requests: cpu: 100m env: - name: ELASTICSEARCH_URL value: http://elasticsearch:9200 ports: - containerPort: 5601
Luego, guarde y cierre el archivo.
En esta especificación, hemos definido un servicio llamado kibana
en el kube-logging
espacio de nombres y le hemos dado la app: kibana
etiqueta.
También hemos especificado que debe ser accesible en el puerto 5601
y usar la app: kibana
etiqueta para seleccionar los Pods de destino del Servicio.
En la Deployment
especificación, definimos una implementación llamada kibana
y especificamos que nos gustaría 1 réplica de Pod.
Usamos la docker.elastic.co/kibana/kibana:7.2.0
imagen. En este punto, puedes sustituirla por tu propia imagen de Kibana pública o privada para usarla.
Especificamos que nos gustaría tener al menos 0,1 vCPU garantizados para el pod, con un límite de 1 vCPU. Puedes cambiar estos parámetros según la carga prevista y los recursos disponibles.
A continuación, usamos la ELASTICSEARCH_URL
variable de entorno para configurar el punto de conexión y el puerto para el clúster de Elasticsearch. Con el DNS de Kubernetes, este punto de conexión corresponde a su nombre de servicio elasticsearch
. Este dominio se resolverá en una lista de direcciones IP para los 3 pods de Elasticsearch. Para obtener más información sobre el DNS de Kubernetes, consulte DNS para servicios y pods.
Por último, establecemos el puerto del contenedor de Kibana en 5601
, al cual el kibana
Servicio enviará las solicitudes.
Una vez que esté satisfecho con su configuración de Kibana, puede implementar el servicio y la implementación mediante kubectl
:
- kubectl create -f kibana.yaml
Deberías ver el siguiente resultado:
Outputservice/kibana createddeployment.apps/kibana created
Puede comprobar que la implementación se realizó correctamente ejecutando el siguiente comando:
- kubectl rollout status deployment/kibana --namespace=kube-logging
Deberías ver el siguiente resultado:
Outputdeployment "kibana" successfully rolled out
Para acceder a la interfaz de Kibana, reenviaremos nuevamente un puerto local al nodo de Kubernetes que ejecuta Kibana. Obtenga los detalles del pod de Kibana con kubectl get
:
- kubectl get pods --namespace=kube-logging
OutputNAME READY STATUS RESTARTS AGEes-cluster-0 1/1 Running 0 55mes-cluster-1 1/1 Running 0 54mes-cluster-2 1/1 Running 0 54mkibana-6c9fb4b5b7-plbg2 1/1 Running 0 4m27s
Aquí observamos que nuestro Kibana Pod se llama kibana-6c9fb4b5b7-plbg2
.
Reenviar el puerto local 5601
al puerto 5601
de este Pod:
- kubectl port-forward kibana-6c9fb4b5b7-plbg2 5601:5601 --namespace=kube-logging
Deberías ver el siguiente resultado:
OutputForwarding from 127.0.0.1:5601 - 5601Forwarding from [::1]:5601 - 5601
Ahora, en su navegador web, visite la siguiente URL:
http://localhost:5601
Si ve la siguiente página de bienvenida de Kibana, habrá implementado Kibana correctamente en su clúster de Kubernetes:
Ahora puede pasar a implementar el componente final de la pila EFK: el recopilador de registros, Fluentd.
Paso 4: Creación del Fluentd DaemonSet
En esta guía, configuraremos Fluentd como un DaemonSet, que es un tipo de carga de trabajo de Kubernetes que ejecuta una copia de un Pod determinado en cada Nodo del clúster de Kubernetes. Con este controlador DaemonSet, implementaremos un Pod de agente de registro de Fluentd en cada nodo de nuestro clúster. Para obtener más información sobre esta arquitectura de registro, consulte “Uso de un agente de registro de nodos” en la documentación oficial de Kubernetes.
En Kubernetes, las aplicaciones en contenedores registran stdout
y stderr
tienen sus flujos de registro capturados y redirigidos a archivos JSON en los nodos. El pod de Fluentd rastreará estos archivos de registro, filtrará los eventos de registro, transformará los datos de registro y los enviará al backend de registro de Elasticsearch que implementamos en el paso 2.
Además de los registros de contenedores, el agente Fluentd registrará los registros de los componentes del sistema Kubernetes, como kubelet, kube-proxy y los registros de Docker. Para ver una lista completa de las fuentes registradas por el agente de registro de Fluentd, consulte el kubernetes.conf
archivo utilizado para configurar el agente de registro. Para obtener más información sobre el registro en clústeres de Kubernetes,
Deja una respuesta