Spanish Translation
This commit is contained in:
committed by
Rael Garcia
parent
71d08b0932
commit
6df3223d72
@@ -1,4 +1,4 @@
|
||||
---
|
||||
title: "Monitorización, Logs y Debugging"
|
||||
weight: 80
|
||||
---
|
||||
---
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
---
|
||||
content_template: templates/concept
|
||||
title: Auditoría
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
La auditoría de Kubernetes proporciona un conjunto de registros cronológicos referentes a la seguridad
|
||||
que documentan la secuencia de actividades que tanto los usuarios individuales, como
|
||||
los administradores y otros componentes del sistema ha realizado en el sistema.
|
||||
Así, permite al administrador del clúster responder a las siguientes cuestiones:
|
||||
|
||||
- ¿qué ha pasado?
|
||||
- ¿cuándo ha pasado?
|
||||
- ¿quién lo ha iniciado?
|
||||
- ¿sobre qué ha pasado?
|
||||
- ¿dónde se ha observado?
|
||||
- ¿desde dónde se ha iniciado?
|
||||
- ¿hacia dónde iba?
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
El componente [Kube-apiserver][kube-apiserver] lleva a cabo la auditoría. Cada petición en cada fase
|
||||
de su ejecución genera un evento, que se pre-procesa según un cierto reglamento y
|
||||
se escribe en un backend. Este reglamento determina lo que se audita
|
||||
y los backends persisten los registros. Las implementaciones actuales de backend
|
||||
incluyen los archivos de logs y los webhooks.
|
||||
|
||||
Cada petición puede grabarse junto con una "etapa" asociada. Las etapas conocidas son:
|
||||
|
||||
- `RequestReceived` - La etapa para aquellos eventos generados tan pronto como
|
||||
el responsable de la auditoría recibe la petición, pero antes de que sea delegada al
|
||||
siguiente responsable en la cadena.
|
||||
- `ResponseStarted` - Una vez que las cabeceras de la respuesta se han enviado,
|
||||
pero antes de que el cuerpo de la respuesta se envíe. Esta etapa sólo se genera
|
||||
en peticiones de larga duración (ej. watch).
|
||||
- `ResponseComplete` - El cuerpo de la respuesta se ha completado y no se enviarán más bytes.
|
||||
- `Panic` - Eventos que se generan cuando ocurre una situación de pánico.
|
||||
|
||||
{{< note >}}
|
||||
La característica de registro de auditoría incrementa el consumo de memoria del servidor API
|
||||
porque requiere de contexto adicional para lo que se audita en cada petición.
|
||||
De forma adicional, el consumo de memoria depende de la configuración misma del registro.
|
||||
{{< /note >}}
|
||||
|
||||
## Reglamento de Auditoría
|
||||
|
||||
El reglamento de auditoría define las reglas acerca de los eventos que deberían registrarse y
|
||||
los datos que deberían incluir. La estructura del objeto de reglas de auditoría se define
|
||||
en el [`audit.k8s.io` grupo de API][auditing-api]. Cuando se procesa un evento, se compara
|
||||
con la lista de reglas en orden. La primera regla coincidente establece el "nivel de auditoría"
|
||||
del evento. Los niveles de auditoría conocidos son:
|
||||
|
||||
- `None` - no se registra eventos que disparan esta regla.
|
||||
- `Metadata` - se registra los metadatos de la petición (usuario que la realiza, marca de fecha y hora, recurso,
|
||||
verbo, etc.), pero no la petición ni el cuerpo de la respuesta.
|
||||
- `Request` - se registra los metadatos del evento y el cuerpo de la petición, pero no el cuerpo de la respuesta.
|
||||
Esto no aplica para las peticiones que no son de recurso.
|
||||
- `RequestResponse` - se registra los metadatos del evento, y los cuerpos de la petición y la respuesta.
|
||||
Esto no aplica para las peticiones que no son de recurso.
|
||||
|
||||
Es posible indicar un archivo al definir el reglamento en el [kube-apiserver][kube-apiserver]
|
||||
usando el parámetro `--audit-policy-file`. Si dicho parámetros se omite, no se registra ningún evento.
|
||||
Nótese que el campo `rules` __debe__ proporcionarse en el archivo del reglamento de auditoría.
|
||||
Un reglamento sin (0) reglas se considera ilegal.
|
||||
|
||||
Abajo se presenta un ejemplo de un archivo de reglamento de auditoría:
|
||||
|
||||
{{< codenew file="audit/audit-policy.yaml" >}}
|
||||
|
||||
Puedes usar un archivo mínimo de reglamento de auditoría para registrar todas las peticiones al nivel `Metadata` de la siguiente forma:
|
||||
|
||||
```yaml
|
||||
# Log all requests at the Metadata level.
|
||||
apiVersion: audit.k8s.io/v1
|
||||
kind: Policy
|
||||
rules:
|
||||
- level: Metadata
|
||||
```
|
||||
|
||||
El [perfil de auditoría utilizado por GCE][gce-audit-profile] debería servir como referencia para
|
||||
que los administradores construyeran sus propios perfiles de auditoría.
|
||||
|
||||
## Backends de auditoría
|
||||
|
||||
Los backends de auditoría persisten los eventos de auditoría en un almacenamiento externo.
|
||||
El [Kube-apiserver][kube-apiserver] por defecto proporciona tres backends:
|
||||
|
||||
- Backend de logs, que escribe los eventos en disco
|
||||
- Backend de webhook, que envía los eventos a una API externa
|
||||
- Backend dinámico, que configura backends de webhook a través de objetos de la API AuditSink.
|
||||
|
||||
En todos los casos, la estructura de los eventos de auditoría se define por la API del grupo
|
||||
`audit.k8s.io`. La versión actual de la API es
|
||||
[`v1`][auditing-api].
|
||||
|
||||
{{< note >}}
|
||||
En el caso de parches, el cuerpo de la petición es una matriz JSON con operaciones de parcheado, en vez
|
||||
de un objeto JSON que incluya el objeto de la API de Kubernetes apropiado. Por ejemplo,
|
||||
el siguiente cuerpo de mensaje es una petición de parcheado válida para
|
||||
`/apis/batch/v1/namespaces/some-namespace/jobs/some-job-name`.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/spec/parallelism",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"op": "remove",
|
||||
"path": "/spec/template/spec/containers/0/terminationMessagePolicy"
|
||||
}
|
||||
]
|
||||
```
|
||||
{{< /note >}}
|
||||
|
||||
### Backend de Logs
|
||||
|
||||
El backend de logs escribe los eventos de auditoría a un archivo en formato JSON.
|
||||
Puedes configurar el backend de logs de auditoría usando el siguiente
|
||||
parámetro de [kube-apiserver][kube-apiserver] flags:
|
||||
|
||||
- `--audit-log-path` especifica la ruta al archivo de log que el backend utiliza para
|
||||
escribir los eventos de auditoría. Si no se especifica, se deshabilita el backend de logs. `-` significa salida estándar
|
||||
- `--audit-log-maxage` define el máximo número de días a retener los archivos de log
|
||||
- `--audit-log-maxbackup` define el máximo número de archivos de log a retener
|
||||
- `--audit-log-maxsize` define el tamaño máximo en megabytes del archivo de logs antes de ser rotado
|
||||
|
||||
### Backend de Webhook
|
||||
|
||||
El backend de Webhook envía eventos de auditoría a una API remota, que se supone es la misma API
|
||||
que expone el [kube-apiserver][kube-apiserver]. Puedes configurar el backend de webhook de auditoría usando
|
||||
los siguientes parámetros de kube-apiserver:
|
||||
|
||||
- `--audit-webhook-config-file` especifica la ruta a un archivo con configuración del webhook.
|
||||
La configuración del webhook es, de hecho, un archivo [kubeconfig][kubeconfig].
|
||||
- `--audit-webhook-initial-backoff` especifica la cantidad de tiempo a esperar tras una petición fallida
|
||||
antes de volver a intentarla. Los reintentos posteriores se ejecutan con retraso exponencial.
|
||||
|
||||
El archivo de configuración del webhook usa el formato kubeconfig para especificar la dirección remota
|
||||
del servicio y las credenciales para conectarse al mismo.
|
||||
|
||||
En la versión 1.13, los backends de webhook pueden configurarse [dinámicamente](#dynamic-backend).
|
||||
|
||||
### Procesamiento por lotes
|
||||
|
||||
Tanto el backend de logs como el de webhook permiten procesamiento por lotes. Si usamos el webhook como ejemplo,
|
||||
aquí se muestra la lista de parámetros disponibles. Para aplicar el mismo parámetro al backend de logs,
|
||||
simplemente sustituye `webhook` por `log` en el nombre del parámetro. Por defecto,
|
||||
el procesimiento por lotes está habilitado en `webhook` y deshabilitado en `log`. De forma similar,
|
||||
por defecto la regulación (throttling) está habilitada en `webhook` y deshabilitada en `log`.
|
||||
|
||||
- `--audit-webhook-mode` define la estrategia de memoria intermedia (búfer), que puede ser una de las siguientes:
|
||||
- `batch` - almacenar eventos y procesarlos de forma asíncrona en lotes. Esta es la estrategia por defecto.
|
||||
- `blocking` - bloquear todas las respuestas del servidor API al procesar cada evento de forma individual.
|
||||
- `blocking-strict` - igual que blocking, pero si ocurre un error durante el registro de la audtoría en la etapa RequestReceived, la petición completa al apiserver fallará.
|
||||
|
||||
Los siguientes parámetros se usan únicamente en el modo `batch`:
|
||||
|
||||
- `--audit-webhook-batch-buffer-size` define el número de eventos a almacenar de forma intermedia antes de procesar por lotes.
|
||||
Si el ritmo de eventos entrantes desborda la memoria intermedia, dichos eventos se descartan.
|
||||
- `--audit-webhook-batch-max-size` define el número máximo de eventos en un único proceso por lotes.
|
||||
- `--audit-webhook-batch-max-wait` define la cantidad máxima de tiempo a esperar de forma incondicional antes de procesar los eventos de la cola.
|
||||
- `--audit-webhook-batch-throttle-qps` define el promedio máximo de procesos por lote generados por segundo.
|
||||
- `--audit-webhook-batch-throttle-burst` define el número máximo de procesos por lote generados al mismo tiempo si el QPS permitido no fue usado en su totalidad anteriormente.
|
||||
|
||||
#### Ajuste de parámetros
|
||||
|
||||
Los parámetros deberían ajustarse a la carga del apiserver.
|
||||
|
||||
Por ejemplo, si kube-apiserver recibe 100 peticiones por segundo, y para cada petición se audita
|
||||
las etapas `ResponseStarted` y `ResponseComplete`, deberías esperar unos ~200
|
||||
eventos de auditoría generados por segundo. Asumiendo que hay hasta 100 eventos en un lote,
|
||||
deberías establecer el nivel de regulación (throttling) por lo menos a 2 QPS. Además, asumiendo
|
||||
que el backend puede tardar hasta 5 segundos en escribir eventos, deberías configurar el tamaño de la memoria intermedia para almacenar hasta 5 segundos de eventos, esto es,
|
||||
10 lotes, o sea, 1000 eventos.
|
||||
|
||||
En la mayoría de los casos, sin embargo, los valores por defecto de los parámetros
|
||||
deberían ser suficientes y no deberías preocuparte de ajustarlos manualmente.
|
||||
Puedes echar un vistazo a la siguientes métricas de Prometheus que expone kube-apiserver
|
||||
y también los logs para monitorizar el estado del subsistema de auditoría:
|
||||
|
||||
- `apiserver_audit_event_total` métrica que contiene el número total de eventos de auditoría exportados.
|
||||
- `apiserver_audit_error_total` métrica que contiene el número total de eventos descartados debido a un error durante su exportación.
|
||||
|
||||
### Truncado
|
||||
|
||||
Tanto el backend de logs como el de webhook permiten truncado. Como ejemplo, aquí se indica la
|
||||
lista de parámetros disponible para el backend de logs:
|
||||
|
||||
- `audit-log-truncate-enabled` indica si el truncado de eventos y por lotes está habilitado.
|
||||
- `audit-log-truncate-max-batch-size` indica el tamaño máximo en bytes del lote enviado al backend correspondiente.
|
||||
- `audit-log-truncate-max-event-size` indica el tamaño máximo en bytes del evento de auditoría enviado al backend correspondiente.
|
||||
|
||||
Por defecto, el truncado está deshabilitado tanto en `webhook` como en `log`; un administrador del clúster debe configurar bien el parámetro `audit-log-truncate-enabled` o `audit-webhook-truncate-enabled` para habilitar esta característica.
|
||||
|
||||
### Backend dinámico
|
||||
|
||||
{{< feature-state for_k8s_version="v1.13" state="alpha" >}}
|
||||
|
||||
En la versión 1.13 de Kubernetes, puedes configurar de forma dinámica los backends de auditoría usando objetos de la API AuditSink.
|
||||
|
||||
Para habilitar la auditoría dinámica, debes configurar los siguientes parámetros de apiserver:
|
||||
|
||||
- `--audit-dynamic-configuration`: el interruptor principal. Cuando esta característica sea GA, el único parámetro necesario.
|
||||
- `--feature-gates=DynamicAuditing=true`: en evaluación en alpha y beta.
|
||||
- `--runtime-config=auditregistration.k8s.io/v1alpha1=true`: habilitar la API.
|
||||
|
||||
Cuando se habilita, un objeto AuditSink se provisiona de la siguiente forma:
|
||||
|
||||
```yaml
|
||||
apiVersion: auditregistration.k8s.io/v1alpha1
|
||||
kind: AuditSink
|
||||
metadata:
|
||||
name: mysink
|
||||
spec:
|
||||
policy:
|
||||
level: Metadata
|
||||
stages:
|
||||
- ResponseComplete
|
||||
webhook:
|
||||
throttle:
|
||||
qps: 10
|
||||
burst: 15
|
||||
clientConfig:
|
||||
url: "https://audit.app"
|
||||
```
|
||||
|
||||
Para una definición completa de la API, ver [AuditSink](/docs/reference/generated/kubernetes-api/v1.13/#auditsink-v1alpha1-auditregistration). Múltiples objetos existirán como soluciones independientes.
|
||||
|
||||
Aquellos backends estáticos que se configuran con parámetros en tiempo de ejecución no se ven impactados por esta característica.
|
||||
Sin embargo, estos backends dinámicos comparten las opciones de truncado del webhook estático, de forma que si dichas opciones se configura con parámetros en tiempo de ejecución, entonces se aplican a todos los backends dinámicos.
|
||||
|
||||
#### Reglamento
|
||||
|
||||
El reglamento de AuditSink es diferente del de la auditoría en tiempo de ejecución. Esto es debido a que el objeto de la API sirve para casos de uso diferentes. El reglamento continuará
|
||||
evolucionando para dar cabida a más casos de uso.
|
||||
|
||||
El campo `level` establece el nivel de auditoría indicado a todas las peticiones. El campo `stages` es actualmente una lista de las etapas que se permite registrar.
|
||||
|
||||
#### Seguridad
|
||||
|
||||
Los administradores deberían tener en cuenta que permitir el acceso en modo escritura de esta característica otorga el modo de acceso de lectura
|
||||
a toda la información del clúster. Así, el acceso debería gestionarse como un privilegio de nivel `cluster-admin`.
|
||||
|
||||
#### Rendimiento
|
||||
|
||||
Actualmente, esta característica tiene implicaciones en el apiserver en forma de incrementos en el uso de la CPU y la memoria.
|
||||
Aunque debería ser nominal cuando se trata de un número pequeño de destinos, se realizarán pruebas adicionales de rendimiento para entender su impacto real antes de que esta API pase a beta.
|
||||
|
||||
## Configuración multi-clúster
|
||||
|
||||
Si estás extendiendo la API de Kubernetes mediante la [capa de agregación][kube-aggregator], puedes también
|
||||
configurar el registro de auditoría para el apiserver agregado. Para ello, pasa las opciones
|
||||
de configuración en el mismo formato que se describe arriba al apiserver agregado
|
||||
y configura el mecanismo de ingestión de logs para que recolecte los logs de auditoría.
|
||||
Cada uno de los apiservers puede tener configuraciones de auditoría diferentes con
|
||||
diferentes reglamentos de auditoría.
|
||||
|
||||
## Ejemplos de recolectores de Logs
|
||||
|
||||
### Uso de fluentd para recolectar y distribuir eventos de auditoría a partir de un archivo de logs
|
||||
|
||||
[Fluentd][fluentd] es un recolector de datos de libre distribución que proporciona una capa unificada de registros.
|
||||
En este ejemplo, usaremos fluentd para separar los eventos de auditoría por nombres de espacio:
|
||||
|
||||
1. Instala [fluentd][fluentd_install_doc], fluent-plugin-forest y fluent-plugin-rewrite-tag-filter en el nodo donde corre kube-apiserver
|
||||
{{< note >}}
|
||||
Fluent-plugin-forest y fluent-plugin-rewrite-tag-filter son plugins de fluentd. Puedes obtener detalles de la instalación de estos plugins en el documento [fluentd plugin-management][fluentd_plugin_management_doc].
|
||||
{{< /note >}}
|
||||
|
||||
1. Crea un archivo de configuración para fluentd:
|
||||
|
||||
```
|
||||
cat <<'EOF' > /etc/fluentd/config
|
||||
# fluentd conf runs in the same host with kube-apiserver
|
||||
<source>
|
||||
@type tail
|
||||
# audit log path of kube-apiserver
|
||||
path /var/log/kube-audit
|
||||
pos_file /var/log/audit.pos
|
||||
format json
|
||||
time_key time
|
||||
time_format %Y-%m-%dT%H:%M:%S.%N%z
|
||||
tag audit
|
||||
</source>
|
||||
|
||||
<filter audit>
|
||||
#https://github.com/fluent/fluent-plugin-rewrite-tag-filter/issues/13
|
||||
@type record_transformer
|
||||
enable_ruby
|
||||
<record>
|
||||
namespace ${record["objectRef"].nil? ? "none":(record["objectRef"]["namespace"].nil? ? "none":record["objectRef"]["namespace"])}
|
||||
</record>
|
||||
</filter>
|
||||
|
||||
<match audit>
|
||||
# route audit according to namespace element in context
|
||||
@type rewrite_tag_filter
|
||||
<rule>
|
||||
key namespace
|
||||
pattern /^(.+)/
|
||||
tag ${tag}.$1
|
||||
</rule>
|
||||
</match>
|
||||
|
||||
<filter audit.**>
|
||||
@type record_transformer
|
||||
remove_keys namespace
|
||||
</filter>
|
||||
|
||||
<match audit.**>
|
||||
@type forest
|
||||
subtype file
|
||||
remove_prefix audit
|
||||
<template>
|
||||
time_slice_format %Y%m%d%H
|
||||
compress gz
|
||||
path /var/log/audit-${tag}.*.log
|
||||
format json
|
||||
include_time_key true
|
||||
</template>
|
||||
</match>
|
||||
EOF
|
||||
```
|
||||
|
||||
1. Arranca fluentd:
|
||||
|
||||
```shell
|
||||
fluentd -c /etc/fluentd/config -vv
|
||||
```
|
||||
|
||||
1. Arranca el componente kube-apiserver con las siguientes opciones:
|
||||
|
||||
```shell
|
||||
--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-path=/var/log/kube-audit --audit-log-format=json
|
||||
```
|
||||
|
||||
1. Comprueba las auditorías de los distintos espacios de nombres en `/var/log/audit-*.log`
|
||||
|
||||
### Uso de logstash para recolectar y distribuir eventos de auditoría desde un backend de webhook
|
||||
|
||||
[Logstash][logstash] es una herramienta de libre distribución de procesamiento de datos en servidor.
|
||||
En este ejemplo, vamos a usar logstash para recolectar eventos de auditoría a partir de un backend de webhook,
|
||||
y grabar los eventos de usuarios diferentes en archivos distintos.
|
||||
|
||||
1. Instala [logstash][logstash_install_doc]
|
||||
|
||||
1. Crea un archivo de configuración para logstash:
|
||||
|
||||
```
|
||||
cat <<EOF > /etc/logstash/config
|
||||
input{
|
||||
http{
|
||||
#TODO, figure out a way to use kubeconfig file to authenticate to logstash
|
||||
#https://www.elastic.co/guide/en/logstash/current/plugins-inputs-http.html#plugins-inputs-http-ssl
|
||||
port=>8888
|
||||
}
|
||||
}
|
||||
filter{
|
||||
split{
|
||||
# Webhook audit backend sends several events together with EventList
|
||||
# split each event here.
|
||||
field=>[items]
|
||||
# We only need event subelement, remove others.
|
||||
remove_field=>[headers, metadata, apiVersion, "@timestamp", kind, "@version", host]
|
||||
}
|
||||
mutate{
|
||||
rename => {items=>event}
|
||||
}
|
||||
}
|
||||
output{
|
||||
file{
|
||||
# Audit events from different users will be saved into different files.
|
||||
path=>"/var/log/kube-audit-%{[event][user][username]}/audit"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
1. Arranca logstash:
|
||||
|
||||
```shell
|
||||
bin/logstash -f /etc/logstash/config --path.settings /etc/logstash/
|
||||
```
|
||||
|
||||
1. Crea un [archivo kubeconfig](/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/) para el webhook del backend de auditoría de kube-apiserver:
|
||||
|
||||
cat <<EOF > /etc/kubernetes/audit-webhook-kubeconfig
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
server: http://<ip_of_logstash>:8888
|
||||
name: logstash
|
||||
contexts:
|
||||
- context:
|
||||
cluster: logstash
|
||||
user: ""
|
||||
name: default-context
|
||||
current-context: default-context
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users: []
|
||||
EOF
|
||||
|
||||
1. Arranca kube-apiserver con las siguientes opciones:
|
||||
|
||||
```shell
|
||||
--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-webhook-config-file=/etc/kubernetes/audit-webhook-kubeconfig
|
||||
```
|
||||
|
||||
1. Comprueba las auditorías en los directorios `/var/log/kube-audit-*/audit` de los nodos de logstash
|
||||
|
||||
Nótese que además del plugin para salida en archivos, logstash ofrece una variedad de salidas adicionales
|
||||
que permiten a los usuarios enviar la información donde necesiten. Por ejemplo, se puede enviar los eventos de auditoría
|
||||
al plugin de elasticsearch que soporta búsquedas avanzadas y analíticas.
|
||||
|
||||
[kube-apiserver]: /docs/admin/kube-apiserver
|
||||
[auditing-proposal]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/auditing.md
|
||||
[auditing-api]: https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/staging/src/k8s.io/apiserver/pkg/apis/audit/v1/types.go
|
||||
[gce-audit-profile]: https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/cluster/gce/gci/configure-helper.sh#L735
|
||||
[kubeconfig]: /docs/tasks/access-application-cluster/configure-access-multiple-clusters/
|
||||
[fluentd]: http://www.fluentd.org/
|
||||
[fluentd_install_doc]: https://docs.fluentd.org/v1.0/articles/quickstart#step-1:-installing-fluentd
|
||||
[fluentd_plugin_management_doc]: https://docs.fluentd.org/v1.0/articles/plugin-management
|
||||
[logstash]: https://www.elastic.co/products/logstash
|
||||
[logstash_install_doc]: https://www.elastic.co/guide/en/logstash/current/installing-logstash.html
|
||||
[kube-aggregator]: /docs/concepts/api-extension/apiserver-aggregation
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: Depurar Contenedores de Inicialización
|
||||
content_template: templates/task
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
Esta página muestra cómo investigar problemas relacionados con la ejecución
|
||||
de los contenedores de inicialización (init containers). Las líneas de comando del ejemplo de abajo
|
||||
se refieren al Pod como `<pod-name>` y a los Init Containers como `<init-container-1>` e
|
||||
`<init-container-2>` respectivamente.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
* Deberías estar familizarizado con el concepto de [Init Containers](/docs/concepts/abstractions/init-containers/).
|
||||
* Deberías conocer la [Configuración de un Init Container](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container/).
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## Comprobar el estado de los Init Containers
|
||||
|
||||
Muestra el estado de tu pod:
|
||||
|
||||
```shell
|
||||
kubectl get pod <pod-name>
|
||||
```
|
||||
|
||||
Por ejemplo, un estado de `Init:1/2` indica que uno de los Init Containers
|
||||
se ha ejecutado satisfactoriamente:
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
<pod-name> 0/1 Init:1/2 0 7s
|
||||
```
|
||||
|
||||
Echa un vistazo a [Comprender el estado de un Pod](#understanding-pod-status) para más ejemplos
|
||||
de valores de estado y sus significados.
|
||||
|
||||
## Obtener detalles acerca de los Init Containers
|
||||
|
||||
Para ver información detallada acerca de la ejecución de un Init Container:
|
||||
|
||||
```shell
|
||||
kubectl describe pod <pod-name>
|
||||
```
|
||||
|
||||
Por ejemplo, un Pod con dos Init Containers podría mostrar lo siguiente:
|
||||
|
||||
```
|
||||
Init Containers:
|
||||
<init-container-1>:
|
||||
Container ID: ...
|
||||
...
|
||||
State: Terminated
|
||||
Reason: Completed
|
||||
Exit Code: 0
|
||||
Started: ...
|
||||
Finished: ...
|
||||
Ready: True
|
||||
Restart Count: 0
|
||||
...
|
||||
<init-container-2>:
|
||||
Container ID: ...
|
||||
...
|
||||
State: Waiting
|
||||
Reason: CrashLoopBackOff
|
||||
Last State: Terminated
|
||||
Reason: Error
|
||||
Exit Code: 1
|
||||
Started: ...
|
||||
Finished: ...
|
||||
Ready: False
|
||||
Restart Count: 3
|
||||
...
|
||||
```
|
||||
|
||||
También puedes acceder al estado del Init Container de forma programática mediante
|
||||
la lectura del campo `status.initContainerStatuses` dentro del Pod Spec:
|
||||
|
||||
|
||||
```shell
|
||||
kubectl get pod nginx --template '{{.status.initContainerStatuses}}'
|
||||
```
|
||||
|
||||
|
||||
Este comando devolverá la misma información que arriba en formato JSON.
|
||||
|
||||
## Acceder a los logs de los Init Containers
|
||||
|
||||
Indica el nombre del Init Container así como el nombre del Pod para
|
||||
acceder a sus logs.
|
||||
|
||||
```shell
|
||||
kubectl logs <pod-name> -c <init-container-2>
|
||||
```
|
||||
|
||||
Los Init Containers que ejecutan secuencias de línea de comandos muestran los comandos
|
||||
conforme se van ejecutando. Por ejemplo, puedes hacer lo siguiente en Bash
|
||||
indicando `set -x` al principio de la secuencia.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture discussion %}}
|
||||
|
||||
## Comprender el estado de un Pod
|
||||
|
||||
Un estado de un Pod que comienza con `Init:` especifica el estado de la ejecución de
|
||||
un Init Container. La tabla a continuación muestra algunos valores de estado de ejemplo
|
||||
que puedes encontrar al depurar Init Containers.
|
||||
|
||||
Estado | Significado
|
||||
------ | -------
|
||||
`Init:N/M` | El Pod tiene `M` Init Containers, y por el momento se han completado `N`.
|
||||
`Init:Error` | Ha fallado la ejecución de un Init Container.
|
||||
`Init:CrashLoopBackOff` | Un Init Container ha fallado de forma repetida.
|
||||
`Pending` | El Pod todavía no ha comenzado a ejecutar sus Init Containers.
|
||||
`PodInitializing` o `Running` | El Pod ya ha terminado de ejecutar sus Init Containers.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
---
|
||||
content_template: templates/concept
|
||||
title: Escribiendo Logs con Elasticsearch y Kibana
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
En la plataforma Google Compute Engine (GCE), por defecto da soporte a la escritura de logs haciendo uso de
|
||||
[Stackdriver Logging](https://cloud.google.com/logging/), el cual se describe en detalle en [Logging con Stackdriver Logging](/docs/user-guide/logging/stackdriver).
|
||||
|
||||
Este artículo describe cómo configurar un clúster para la ingesta de logs en
|
||||
[Elasticsearch](https://www.elastic.co/products/elasticsearch) y su posterior visualización
|
||||
con [Kibana](https://www.elastic.co/products/kibana), a modo de alternativa a
|
||||
Stackdriver Logging cuando se utiliza la plataforma GCE.
|
||||
|
||||
{{< note >}}
|
||||
No se puede desplegar de forma automática Elasticsearch o Kibana en un clúster alojado en Google Kubernetes Engine. Hay que desplegarlos de forma manual.
|
||||
{{< /note >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
Para utilizar Elasticsearch y Kibana para escritura de logs del clúster, deberías configurar
|
||||
la siguiente variable de entorno que se muestra a continuación como parte de la creación
|
||||
del clúster con kube-up.sh:
|
||||
|
||||
```shell
|
||||
KUBE_LOGGING_DESTINATION=elasticsearch
|
||||
```
|
||||
|
||||
También deberías asegurar que `KUBE_ENABLE_NODE_LOGGING=true` (que es el valor por defecto en la plataforma GCE).
|
||||
|
||||
Así, cuando crees un clúster, un mensaje te indicará que la recolección de logs de los daemons de Fluentd
|
||||
que corren en cada nodo enviará dichos logs a Elasticsearch:
|
||||
|
||||
```shell
|
||||
cluster/kube-up.sh
|
||||
```
|
||||
```
|
||||
...
|
||||
Project: kubernetes-satnam
|
||||
Zone: us-central1-b
|
||||
... calling kube-up
|
||||
Project: kubernetes-satnam
|
||||
Zone: us-central1-b
|
||||
+++ Staging server tars to Google Storage: gs://kubernetes-staging-e6d0e81793/devel
|
||||
+++ kubernetes-server-linux-amd64.tar.gz uploaded (sha1 = 6987c098277871b6d69623141276924ab687f89d)
|
||||
+++ kubernetes-salt.tar.gz uploaded (sha1 = bdfc83ed6b60fa9e3bff9004b542cfc643464cd0)
|
||||
Looking for already existing resources
|
||||
Starting master and configuring firewalls
|
||||
Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/zones/us-central1-b/disks/kubernetes-master-pd].
|
||||
NAME ZONE SIZE_GB TYPE STATUS
|
||||
kubernetes-master-pd us-central1-b 20 pd-ssd READY
|
||||
Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/regions/us-central1/addresses/kubernetes-master-ip].
|
||||
+++ Logging using Fluentd to elasticsearch
|
||||
```
|
||||
|
||||
Tanto los pods por nodo de Fluentd, como los pods de Elasticsearch, y los pods de Kibana
|
||||
deberían ejecutarse en el namespace de kube-system inmediatamente después
|
||||
de que el clúster esté disponible.
|
||||
|
||||
```shell
|
||||
kubectl get pods --namespace=kube-system
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
elasticsearch-logging-v1-78nog 1/1 Running 0 2h
|
||||
elasticsearch-logging-v1-nj2nb 1/1 Running 0 2h
|
||||
fluentd-elasticsearch-kubernetes-node-5oq0 1/1 Running 0 2h
|
||||
fluentd-elasticsearch-kubernetes-node-6896 1/1 Running 0 2h
|
||||
fluentd-elasticsearch-kubernetes-node-l1ds 1/1 Running 0 2h
|
||||
fluentd-elasticsearch-kubernetes-node-lz9j 1/1 Running 0 2h
|
||||
kibana-logging-v1-bhpo8 1/1 Running 0 2h
|
||||
kube-dns-v3-7r1l9 3/3 Running 0 2h
|
||||
monitoring-heapster-v4-yl332 1/1 Running 1 2h
|
||||
monitoring-influx-grafana-v1-o79xf 2/2 Running 0 2h
|
||||
```
|
||||
|
||||
Los pods de `fluentd-elasticsearch` recogen los logs de cada nodo y los envían a los
|
||||
pods de `elasticsearch-logging`, que son parte de un [servicio](/docs/concepts/services-networking/service/) llamado `elasticsearch-logging`.
|
||||
Estos pods de Elasticsearch almacenan los logs y los exponen via una API REST.
|
||||
El pod de `kibana-logging` proporciona una UI via web donde leer los logs almacenados en
|
||||
Elasticsearch, y es parte de un servicio denominado `kibana-logging`.
|
||||
|
||||
Los servicios de Elasticsearch y Kibana ambos están en el namespace `kube-system`
|
||||
y no se exponen de forma directa mediante una IP accesible públicamente. Para poder acceder a dichos logs,
|
||||
sigue las instrucciones acerca de cómo [Acceder a servicios corriendo en un clúster](/docs/concepts/cluster-administration/access-clusater/#accessing-services-running-on-the-cluster).
|
||||
|
||||
Si tratas de acceder al servicio de `elasticsearch-logging` desde tu navegador,
|
||||
verás una página de estado que se parece a la siguiente:
|
||||
|
||||

|
||||
|
||||
A partir de ese momento, puedes introducir consultas de Elasticsearch directamente en el navegador, si lo necesitas.
|
||||
Echa un vistazo a la [documentación de Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html)
|
||||
para más detalles acerca de cómo hacerlo.
|
||||
|
||||
De forma alternativa, puedes ver los logs de tu clúster en Kibana (de nuevo usando las
|
||||
[instrucciones para acceder a un servicio corriendo en un clúster](/docs/user-guide/accessing-the-cluster/#accessing-services-running-on-the-cluster)).
|
||||
La primera vez que visitas la URL de Kibana se te presentará una página que te pedirá
|
||||
que configures una vista de los logs. Selecciona la opción de valores de serie temporal
|
||||
y luego `@timestamp`. En la página siguiente selecciona la pestaña de `Discover`
|
||||
y entonces deberías ver todos los logs. Puedes establecer el intervalo de actualización
|
||||
en 5 segundos para refrescar los logs de forma regular.
|
||||
|
||||
Aquí se muestra una vista típica de logs desde el visor de Kibana:
|
||||
|
||||

|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
¡Kibana te permite todo tipo de potentes opciones para explorar tus logs! Puedes encontrar
|
||||
algunas ideas para profundizar en el tema en la [documentación de Kibana](https://www.elastic.co/guide/en/kibana/current/discover.html).
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -0,0 +1,366 @@
|
||||
---
|
||||
title: Escribiendo Logs con Stackdriver
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
Antes de seguir leyendo esta página, deberías familiarizarte con el
|
||||
[resumen de escritura de logs en Kubernetes](/docs/concepts/cluster-administration/logging).
|
||||
|
||||
{{< note >}}
|
||||
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](/docs/concepts/cluster-administration/logging#sidecar-container-with-a-logging-agent)
|
||||
en el resumen de escritura de logs en Kubernetes.
|
||||
{{< /note >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 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:
|
||||
|
||||
1. Configura la variable de entorno `KUBE_LOGGING_DESTINATION` con el valor `gcp`.
|
||||
1. **Si no estás trabajando en GCE**, incluye `beta.kubernetes.io/fluentd-ds-ready=true`
|
||||
en la variable `KUBE_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.
|
||||
|
||||
{{< warning >}}
|
||||
El proceso de Stackdriver Logging reporta problemas conocidos en plataformas distintas
|
||||
a Google Kubernetes Engine. Úsalo bajo tu propio riesgo.
|
||||
{{< /warning >}}
|
||||
|
||||
### Desplegar a un clúster existente
|
||||
|
||||
1. 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 comando `kubectl label` como se indica:
|
||||
|
||||
```
|
||||
kubectl label node $NODE_NAME beta.kubernetes.io/fluentd-ds-ready=true
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
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.
|
||||
{{< /note >}}
|
||||
|
||||
1. 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 nombres `default`. Puedes descargar el archivo
|
||||
manualmente y cambiarlo antes de crear el objeto `ConfigMap`.
|
||||
|
||||
1. 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:
|
||||
|
||||
```shell
|
||||
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](/examples/debug/counter-pod.yaml):
|
||||
|
||||
{{< codenew file="debug/counter-pod.yaml" >}}
|
||||
|
||||
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.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml
|
||||
```
|
||||
|
||||
Puedes observar el pod corriendo:
|
||||
|
||||
```shell
|
||||
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.
|
||||
|
||||
```shell
|
||||
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:
|
||||
|
||||
```shell
|
||||
kubectl delete pod counter
|
||||
```
|
||||
```
|
||||
pod "counter" deleted
|
||||
```
|
||||
|
||||
y su posterior re-creación:
|
||||
|
||||
```shell
|
||||
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:
|
||||
|
||||
```shell
|
||||
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](https://cloud.google.com/logging/docs/view/logs_viewer).
|
||||
|
||||
Uno de los posibles modos de ver los logs es usando el comando de línea de interfaz
|
||||
[`gcloud logging`](https://cloud.google.com/logging/docs/api/gcloud-logging)
|
||||
del [SDK de Google Cloud](https://cloud.google.com/sdk/).
|
||||
Este comando usa la [sintaxis de filtrado](https://cloud.google.com/logging/docs/view/advanced_filters) de StackDriver Logging
|
||||
para consultar logs específicos. Por ejemplo, puedes ejecutar el siguiente comando:
|
||||
|
||||
```none
|
||||
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](https://cloud.google.com/storage/)
|
||||
o a [BigQuery](https://cloud.google.com/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](https://cloud.google.com/logging/docs/export/configure_export_v2) 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.
|
||||
|
||||
{{< note >}}
|
||||
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.
|
||||
{{< /note >}}
|
||||
|
||||
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](#deploying).
|
||||
|
||||
### 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:
|
||||
|
||||
```shell
|
||||
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:
|
||||
|
||||
```shell
|
||||
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](http://docs.fluentd.org).
|
||||
|
||||
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:
|
||||
|
||||
```shell
|
||||
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`.
|
||||
|
||||
{{< note >}}
|
||||
El orden es importante.
|
||||
{{< /note >}}
|
||||
|
||||
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](#changing-daemonset-parameters).
|
||||
|
||||
### Añadir plugins de fluentd
|
||||
|
||||
Fluentd está desarrollado en Ruby y permite extender sus capacidades mediante el uso de
|
||||
[plugins](http://www.fluentd.org/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](https://git.k8s.io/contrib/fluentd/fluentd-gcp-image)
|
||||
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.
|
||||
|
||||
{{% /capture %}}
|
||||
Reference in New Issue
Block a user