Lo que necesita saber sobre el registro de clústeres en Kubernetes

El registro de aplicaciones y servidores es una función importante para que los desarrolladores, operadores y equipos de seguridad comprendan el estado de una aplicación que se ejecuta en su entorno de producción.
El registro permite a los operadores determinar si las aplicaciones y los componentes necesarios funcionan correctamente y detectar si ocurre algo inusual para que puedan reaccionar ante la situación.
Para los desarrolladores, el registro proporciona visibilidad del código de solución de problemas durante y después del desarrollo. En un entorno de producción, el desarrollador suele depender de una función de registro sin herramientas de depuración. Junto con el registro de los sistemas, los desarrolladores pueden trabajar codo a codo con los operadores para solucionar problemas de manera efectiva.
El beneficiario más importante de las instalaciones de registro es el equipo de seguridad, especialmente en un entorno nativo de la nube. La capacidad de recopilar información de las aplicaciones y los registros del sistema permite que el equipo de seguridad analice los datos de la autenticación, el acceso a las aplicaciones y las actividades de malware a las que pueden responder si es necesario.
Kubernetes es la plataforma de contenedores líder en la que cada vez se implementan más aplicaciones en producción. Creo que comprender la arquitectura de registro de Kubernetes es un esfuerzo muy importante que todo equipo de desarrollo, operaciones y seguridad debe tomar en serio.
En este artículo explicaré cómo funcionan los diferentes modelos de registro de contenedores en Kubernetes.
Registro del sistema y registro de la aplicación
Antes de profundizar en la arquitectura de registro de Kubernetes, me gustaría explorar los diferentes enfoques de registro y cómo ambas características son características críticas del registro de Kubernetes.
Hay dos tipos de componentes del sistema: los que se ejecutan en un contenedor y los que no. Por ejemplo:
- El programador de Kubernetes e
kube-proxy
ejecutar en un contenedor. - El
kubelet
y el tiempo de ejecución del contenedor no se ejecuta en contenedores.
Al igual que los registros de contenedores, los registros de contenedores del sistema se almacenan en /var/log
directorios y debe rotarlos regularmente.
Aquí considero el registro del contenedor. Primero, analizo el registro a nivel de clúster y por qué es importante para los operadores de clúster. Los registros del clúster proporcionan información sobre el rendimiento del clúster. Información como por qué los pods fueron desalojados o el nodo muere. El registro de clústeres también puede capturar información como el acceso a clústeres y aplicaciones y cómo la aplicación utiliza los recursos informáticos. En general, una función de registro de clúster proporciona a los operadores de clúster información útil para la seguridad y el funcionamiento del clúster.
La otra forma de capturar registros de contenedores es a través de la función de registro nativa de la aplicación. Es muy probable que el diseño de aplicaciones modernas tenga un mecanismo de registro que ayude a los desarrolladores a solucionar problemas de rendimiento de aplicaciones a través de una salida estándar (stdout
) y flujos de error (stderr
).
Para tener una función de registro efectiva, la implementación de Kubernetes requiere componentes de registro tanto de la aplicación como del sistema.
3 tipos de registro de contenedores de Kubernetes
Hay tres métodos importantes de registro a nivel de clúster que se ven en la mayoría de las implementaciones de Kubernetes en estos días.
- Agente de registro a nivel de nodo
- Solicitud de registro de contenedor de sidecar
- Exponga los registros de la aplicación directamente al backend de registro
Agente de registro a nivel de nodo
Me gustaría considerar el agente de registro a nivel de nodo. Por lo general, los implementa utilizando un DaemonSet como su estrategia de implementación para implementar un pod (que actúa como un agente de registro) en todos los nodos de Kubernetes. Luego, este agente de registro se configura para leer registros de todos los nodos de Kubernetes. Por lo general, configura el agente para leer los nodos /var/logs
adquisición de directorio stdout
/stderr
transmitir y enviarlo a la tienda backend de grabación.
La siguiente figura muestra el registro a nivel de nodo ejecutándose como agente en todos los nodos.
Para configurar el registro a nivel de nodo mediante el fluentd
enfoque como ejemplo, debe hacer lo siguiente:
- Primero, debe crear una cuenta de servicio llamada
fluentdd
. Esta cuenta de servicio es utilizada por Fluentd Pods para acceder a la API de Kubernetes y debe crearlos en el espacio de nombres de registro etiquetadoapp: fluentd
.#fluentd-SA.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd
namespace: logging
labels:
app: fluentdPuedes ver el ejemplo completo en este repositorio.
- Por lo tanto, es necesario crear un ConfigMap
fluentd-configmap
. Esto proporciona un archivo de configuración para elfluentd daemonset
con todas las propiedades requeridas.#fluentd-daemonset.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: fluentd
namespace: logging
labels:
app: fluentd
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
app: fluentd
kubernetes.io/cluster-service: "true"
template:
metadata:
labels:
app: fluentd
kubernetes.io/cluster-service: "true"
spec:
serviceAccount: fluentd
Contenedores:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.7.3-debian-elasticsearch7-1.0
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch.logging.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
- name: FLUENT_ELASTICSEARCH_USER
value: "elastic"
- name: FLUENT_ELASTICSEARCH_PASSWORD
valueFrom:
secretKeyRef:
name: efk-pw-elastic
key: password
- name: FLUENT_ELASTICSEARCH_SED_DISABLE
value: "true"
resources:
limits:
memory: 512Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/Contenedores
readOnly: true
- name: fluentconfig
mountPath: /fluentd/etc/fluent.conf
subPath: fluent.conf
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/Contenedores
- name: fluentconfig
configMap:
name: fluentdconfPuedes ver el ejemplo completo en este repositorio.
Ahora, miro el código sobre cómo implementar un fluentd daemonset
como agente de registro.
#fluentd-daemonset.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: fluentd
namespace: logging
labels:
app: fluentd
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
app: fluentd
kubernetes.io/cluster-service: "true"
template:
metadata:
labels:
app: fluentd
kubernetes.io/cluster-service: "true"
spec:
serviceAccount: fluentd
Contenedores:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.7.3-debian-elasticsearch7-1.0
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch.logging.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
- name: FLUENT_ELASTICSEARCH_USER
value: "elastic"
- name: FLUENT_ELASTICSEARCH_PASSWORD
valueFrom:
secretKeyRef:
name: efk-pw-elastic
key: password
- name: FLUENT_ELASTICSEARCH_SED_DISABLE
value: "true"
resources:
limits:
memory: 512Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/Contenedores
readOnly: true
- name: fluentconfig
mountPath: /fluentd/etc/fluent.conf
subPath: fluent.conf
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/Contenedores
- name: fluentconfig
configMap:
name: fluentdconf
Para poner esto junto:
kubectl apply -f fluentd-SA.yaml
-f fluentd-configmap.yaml
-f fluentd-daemonset.yaml
Solicitud de registro de contenedor de sidecar
El otro enfoque es utilizar un contenedor sidecar dedicado con un agente de registro. La implementación más común del contenedor sidecar es el uso Fluido como recolector de troncos. En la implementación empresarial (donde no se preocupará por una pequeña sobrecarga de recursos informáticos), se utiliza un contenedor sidecar fluentd
(o similar) ofrece flexibilidad sobre el registro a nivel de clúster. Esto se debe a que puede ajustar y configurar el recopilador según el tipo de registros, la frecuencia y otros posibles ajustes que necesite adquirir.
La siguiente figura muestra un contenedor sidecar como agente de registro.
Por ejemplo, un pod ejecuta un solo contenedor y el contenedor escribe en dos archivos de registro diferentes usando dos formatos diferentes. Aquí hay un archivo de configuración para el pod:
#log-sidecar.yaml
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
Contenedores:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
Para armar esto, puede ejecutar este pod:
$ kubectl apply -f log-sidecar.yaml
Para verificar si el contenedor de sidecar funciona como agente de registro, puede hacer lo siguiente:
$ kubectl logs counter count-log
El resultado esperado debería verse así:
$ kubectl logs counter count-log-1Thu 04 Nov 2021 09:23:21 NZDT
Thu 04 Nov 2021 09:23:22 NZDT
Thu 04 Nov 2021 09:23:23 NZDT
Thu 04 Nov 2021 09:23:24 NZDT
Exponga los registros de la aplicación directamente al backend de registro
El tercer enfoque, que (en mi opinión) es la solución de registro más flexible para los registros de aplicaciones y contenedores de Kubernetes, es transferir los registros directamente a la solución de back-end de registro. Si bien este modelo no se basa en la capacidad nativa de Kubernetes, ofrece la flexibilidad que la mayoría de las empresas necesitan, como por ejemplo:
- Amplíe una variedad más amplia de soporte para protocolos de red y formatos de salida.
- Habilita las capacidades de equilibrio de carga y mejora el rendimiento.
- Configurable para aceptar requisitos de registro complejos a través de la agregación ascendente
Dado que este tercer enfoque se basa en la funcionalidad que no es de Kubernetes al enviar registros directamente desde cada aplicación, está fuera del alcance de Kubernetes.
Conclusión
El registrador de Kubernetes es un componente muy importante para la implementación empresarial de un clúster de Kubernetes. He discutido tres modelos posibles que están disponibles para su uso. Necesitas encontrar un modelo que se adapte a tus necesidades.
Como se muestra, el registro a nivel de nodo que utiliza daemonset
Es el modelo de implementación más simple de usar, pero también tiene algunas limitaciones que pueden no satisfacer las necesidades de su organización. Por otro lado, el modelo sidecar ofrece flexibilidad y personalización que le permiten personalizar el tipo de registro que se capturará, lo que le brinda una sobrecarga de recursos informáticos. Finalmente, exponer los registros de la aplicación directamente a la función de registro de back-end es otro enfoque tentador que permite una mayor personalización.
La decisión es tuya. Solo necesita encontrar el enfoque que se adapte a los requisitos de su organización.
Artículos de interés