You are viewing documentation for Kubernetes version: v1.20
Kubernetes v1.20 ya no mantiene activamente la documentación. La versión que está viendo actualmente es una instantánea estática. Para la documentación actualizada, visita la última versión.
Escribiendo Logs con Stackdriver
Antes de seguir leyendo esta página, deberías familiarizarte con el resumen de escritura de logs en Kubernetes.
Nota: Por defecto, Stackdriver recolecta toda la salida estándar de tus contenedores, así como el flujo de la salida de error. Para recolectar cualquier log tu aplicación escribe en un archivo (por ejemplo), ver la estrategia de sidecar en el resumen de escritura de logs en Kubernetes.
Despliegue
Para ingerir logs, debes desplegar el agente de Stackdriver Logging en cada uno de los nodos de tu clúster.
Dicho agente configura una instancia de fluentd
, donde la configuración se guarda en un ConfigMap
y las instancias se gestionan a través de un DaemonSet
de Kubernetes. El despliegue actual del
ConfigMap
y el DaemonSet
dentro de tu clúster depende de tu configuración individual del clúster.
Desplegar en un nuevo clúster
Google Kubernetes Engine
Stackdriver es la solución por defecto de escritura de logs para aquellos clústeres desplegados en Google Kubernetes Engine. Stackdriver Logging se despliega por defecto en cada clúster a no ser que se le indique de forma explícita no hacerlo.
Otras plataformas
Para desplegar Stackdriver Logging en un nuevo clúster que estés creando con
kube-up.sh
, haz lo siguiente:
- Configura la variable de entorno
KUBE_LOGGING_DESTINATION
con el valorgcp
. - Si no estás trabajando en GCE, incluye
beta.kubernetes.io/fluentd-ds-ready=true
en la variableKUBE_NODE_LABELS
.
Una vez que tu clúster ha arrancado, cada nodo debería ejecutar un agente de Stackdriver Logging.
Los DaemonSet
y ConfigMap
se configuran como extras. Si no estás usando kube-up.sh
,
considera la posibilidad de arrancar un clúster sin una solución pre-determinada de escritura de logs
y entonces desplegar los agentes de Stackdriver Logging una vez el clúster esté ejecutándose.
Advertencia: El proceso de Stackdriver Logging reporta problemas conocidos en plataformas distintas a Google Kubernetes Engine. Úsalo bajo tu propio riesgo.
Desplegar a un clúster existente
Aplica una etiqueta en cada nodo, si no estaba presente ya.
El despliegue del agente de Stackdriver Logging utiliza etiquetas de nodo para determinar en qué nodos debería desplegarse. Estas etiquetas fueron introducidas para distinguir entre nodos de Kubernetes de la versión 1.6 o superior. Si el clúster se creó con Stackdriver Logging configurado y el nodo tiene la versión 1.5.X o inferior, ejecutará fluentd como un pod estático. Puesto que un nodo no puede tener más de una instancia de fluentd, aplica únicamente las etiquetas a los nodos que no tienen un pod de fluentd ya desplegado. Puedes confirmar si tu nodo ha sido etiquetado correctamente ejecutando
kubectl describe
de la siguiente manera:kubectl describe node $NODE_NAME
La salida debería ser similar a la siguiente:
Name: NODE_NAME Role: Labels: beta.kubernetes.io/fluentd-ds-ready=true ...
Asegúrate que la salida contiene la etiqueta
beta.kubernetes.io/fluentd-ds-ready=true
. Si no está presente, puedes añadirla usando el comandokubectl label
como se indica:kubectl label node $NODE_NAME beta.kubernetes.io/fluentd-ds-ready=true
Nota: Si un nodo falla y tiene que volver a crearse, deberás volver a definir la etiqueta al nuevo nodo. Para facilitar esta tarea, puedes utilizar el parámetro de línea de comandos del Kubelet para aplicar dichas etiquetas cada vez que se arranque un nodo.Despliega un
ConfigMap
con la configuración del agente de escritura de logs ejecutando el siguiente comando:kubectl apply -f https://k8s.io/examples/debug/fluentd-gcp-configmap.yaml
Este comando crea el
ConfigMap
en el espacio de nombresdefault
. Puedes descargar el archivo manualmente y cambiarlo antes de crear el objetoConfigMap
.Despliega el agente
DaemonSet
de escritura de logs ejecutando el siguiente comando:kubectl apply -f https://k8s.io/examples/debug/fluentd-gcp-ds.yaml
Puedes descargar y editar este archivo antes de usarlo igualmente.
Verificar el despliegue de tu agente de escritura de logs
Tras el despliegue del DaemonSet
de StackDriver, puedes comprobar el estado de
cada uno de los despliegues de los agentes ejecutando el siguiente comando:
kubectl get ds --all-namespaces
Si tienes 3 nodos en el clúster, la salida debería ser similar a esta:
NAMESPACE NAME DESIRED CURRENT READY NODE-SELECTOR AGE
...
default fluentd-gcp-v2.0 3 3 3 beta.kubernetes.io/fluentd-ds-ready=true 5m
...
Para comprender cómo funciona Stackdriver, considera la siguiente especificación de un generador de logs sintéticos counter-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
Esta especificación de pod tiene un contenedor que ejecuta una secuencia de comandos bash que escribe el valor de un contador y la fecha y hora cada segundo, de forma indefinida. Vamos a crear este pod en el espacio de nombres por defecto.
kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml
Puedes observar el pod corriendo:
kubectl get pods
NAME READY STATUS RESTARTS AGE
counter 1/1 Running 0 5m
Durante un período de tiempo corto puedes observar que el estado del pod es 'Pending', debido a que el kubelet
tiene primero que descargar la imagen del contenedor. Cuando el estado del pod cambia a Running
puedes usar el comando kubectl logs
para ver la salida de este pod contador.
kubectl logs counter
0: Mon Jan 1 00:00:00 UTC 2001
1: Mon Jan 1 00:00:01 UTC 2001
2: Mon Jan 1 00:00:02 UTC 2001
...
Como se describe en el resumen de escritura de logs, este comando visualiza las entradas de logs del archivo de logs del contenedor. Si se termina el contenedor y Kubernetes lo reinicia, todavía puedes acceder a los logs de la ejecución previa del contenedor. Sin embargo, si el pod se desaloja del nodo, los archivos de log se pierden. Vamos a demostrar este comportamiento mediante el borrado del contenedor que ejecuta nuestro contador:
kubectl delete pod counter
pod "counter" deleted
y su posterior re-creación:
kubectl create -f https://k8s.io/examples/debug/counter-pod.yaml
pod/counter created
Tras un tiempo, puedes acceder a los logs del pod contador otra vez:
kubectl logs counter
0: Mon Jan 1 00:01:00 UTC 2001
1: Mon Jan 1 00:01:01 UTC 2001
2: Mon Jan 1 00:01:02 UTC 2001
...
Como era de esperar, únicamente se visualizan las líneas de log recientes. Sin embargo, para una aplicación real seguramente prefieras acceder a los logs de todos los contenedores, especialmente cuando te haga falta depurar problemas. Aquí es donde haber habilitado Stackdriver Logging puede ayudarte.
Ver logs
El agente de Stackdriver Logging asocia metadatos a cada entrada de log, para que puedas usarlos posteriormente en consultas para seleccionar sólo los mensajes que te interesan: por ejemplo, los mensajes de un pod en particular.
Los metadatos más importantes son el tipo de recurso y el nombre del log.
El tipo de recurso de un log de contenedor tiene el valor container
, que se muestra como
GKE Containers
en la UI (incluso si el clúster de Kubernetes no está en Google Kubernetes Engine).
El nombre de log es el nombre del contenedor, de forma que si tienes un pod con
dos contenedores, denominados container_1
y container_2
en la especificación, sus logs
tendrán los nombres container_1
y container_2
respectivamente.
Los componentes del sistema tienen el valor compute
como tipo de recursos, que se muestra como
GCE VM Instance
en la UI. Los nombres de log para los componentes del sistema son fijos.
Para un nodo de Google Kubernetes Engine, cada entrada de log de cada componente de sistema tiene uno de los siguientes nombres:
- docker
- kubelet
- kube-proxy
Puedes aprender más acerca de cómo visualizar los logs en la página dedicada a Stackdriver.
Uno de los posibles modos de ver los logs es usando el comando de línea de interfaz
gcloud logging
del SDK de Google Cloud.
Este comando usa la sintaxis de filtrado de StackDriver Logging
para consultar logs específicos. Por ejemplo, puedes ejecutar el siguiente comando:
gcloud beta logging read 'logName="projects/$YOUR_PROJECT_ID/logs/count"' --format json | jq '.[].textPayload'
...
"2: Mon Jan 1 00:01:02 UTC 2001\n"
"1: Mon Jan 1 00:01:01 UTC 2001\n"
"0: Mon Jan 1 00:01:00 UTC 2001\n"
...
"2: Mon Jan 1 00:00:02 UTC 2001\n"
"1: Mon Jan 1 00:00:01 UTC 2001\n"
"0: Mon Jan 1 00:00:00 UTC 2001\n"
Como puedes observar, muestra los mensajes del contenedor contador tanto de la primera como de la segunda ejecución, a pesar de que el kubelet ya había eliminado los logs del primer contenedor.
Exportar logs
Puedes exportar los logs al Google Cloud Storage o a BigQuery para llevar a cabo un análisis más profundo. Stackdriver Logging ofrece el concepto de destinos, donde puedes especificar el destino de las entradas de logs. Más información disponible en la página de exportación de logs de StackDriver.
Configurar los agentes de Stackdriver Logging
En ocasiones la instalación por defecto de Stackdriver Logging puede que no se ajuste a tus necesidades, por ejemplo:
- Puede que quieras añadir más recursos porque el rendimiento por defecto no encaja con tus necesidades.
- Puede que quieras añadir un parseo adicional para extraer más metadatos de tus mensajes de log, como la severidad o referencias al código fuente.
- Puede que quieras enviar los logs no sólo a Stackdriver o sólo enviarlos a Stackdriver parcialmente.
En cualquiera de estos casos, necesitas poder cambiar los parámetros del DaemonSet
y el ConfigMap
.
Prerequisitos
Si estás usando GKE y Stackdriver Logging está habilitado en tu clúster, no puedes cambiar su configuración, porque ya está gestionada por GKE. Sin embargo, puedes deshabilitar la integración por defecto y desplegar la tuya propia.
Nota: Tendrás que mantener y dar soporte tú mismo a la nueva configuración desplegada: actualizar la imagen y la configuración, ajustar los recuros y todo eso.
Para deshabilitar la integración por defecto, usa el siguiente comando:
gcloud beta container clusters update --logging-service=none CLUSTER
Puedes encontrar notas acerca de cómo instalar los agentes de Stackdriver Logging en un clúster ya ejecutándose en la sección de despliegue.
Cambiar los parámetros del DaemonSet
Cuando tienes un DaemonSet
de Stackdriver Logging en tu clúster, puedes simplemente
modificar el campo template
en su especificación, y el controlador del daemonset actualizará los pods por ti. Por ejemplo,
asumamos que acabas de instalar el Stackdriver Logging como se describe arriba. Ahora quieres cambiar
el límite de memoria que se le asigna a fluentd para poder procesar más logs de forma segura.
Obtén la especificación del DaemonSet
que corre en tu clúster:
kubectl get ds fluentd-gcp-v2.0 --namespace kube-system -o yaml > fluentd-gcp-ds.yaml
A continuación, edita los requisitos del recurso en el spec
y actualiza el objeto DaemonSet
en el apiserver usando el siguiente comando:
kubectl replace -f fluentd-gcp-ds.yaml
Tras un tiempo, los pods de agente de Stackdriver Logging se reiniciarán con la nueva configuración.
Cambiar los parámetros de fluentd
La configuración de Fluentd se almacena en un objeto ConfigMap
. Realmente se trata de un conjunto
de archivos de configuración que se combinan conjuntamente. Puedes aprender acerca de
la configuración de fluentd en el sitio oficial.
Imagina que quieres añadir una nueva lógica de parseo a la configuración actual, de forma que fluentd pueda entender el formato de logs por defecto de Python. Un filtro apropiado de fluentd para conseguirlo sería:
<filter reform.**>
type parser
format /^(?<severity>\w):(?<logger_name>\w):(?<log>.*)/
reserve_data true
suppress_parse_error_log true
key_name log
</filter>
Ahora tienes que añadirlo a la configuración actual y que los agentes de Stackdriver Logging la usen.
Para ello, obtén la versión actual del ConfigMap
de Stackdriver Logging de tu clúster
ejecutando el siguiente comando:
kubectl get cm fluentd-gcp-config --namespace kube-system -o yaml > fluentd-gcp-configmap.yaml
Luego, como valor de la clave containers.input.conf
, inserta un nuevo filtro justo después
de la sección source
.
Nota: El orden es importante.
Actualizar el ConfigMap
en el apiserver es más complicado que actualizar el DaemonSet
.
Es mejor considerar que un ConfigMap
es inmutable. Así, para poder actualizar la configuración, deberías
crear un nuevo ConfigMap
con otro nombre y cambiar el DaemonSet
para que apunte al nuevo
siguiendo la guía de arriba.
Añadir plugins de fluentd
Fluentd está desarrollado en Ruby y permite extender sus capacidades mediante el uso de plugins. Si quieres usar un plugin que no está incluido en la imagen por defecto del contenedor de Stackdriver Logging, debes construir tu propia imagen. Imagina que quieres añadir un destino Kafka para aquellos mensajes de un contenedor en particular para poder procesarlos posteriormente. Puedes reusar los fuentes de imagen de contenedor con algunos pequeños cambios:
- Cambia el archivo Makefile para que apunte a tu repositorio de contenedores, ej.
PREFIX=gcr.io/<your-project-id>
. - Añade tu dependencia al archivo Gemfile, por ejemplo
gem 'fluent-plugin-kafka'
.
Luego, ejecuta make build push
desde ese directorio. Cuando el DaemonSet
haya tomado los cambios de la nueva imagen,
podrás usar el plugin que has indicado en la configuración de fluentd.