-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Enrique Medina Montenegro
authored and
Enrique Medina Montenegro
committed
Oct 7, 2019
1 parent
abde921
commit 92890f6
Showing
3 changed files
with
341 additions
and
0 deletions.
There are no files selected for viewing
61 changes: 61 additions & 0 deletions
61
content/es/docs/concepts/workloads/controllers/cron-jobs.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
title: CronJob | ||
content_template: templates/concept | ||
weight: 80 | ||
--- | ||
|
||
{{% capture overview %}} | ||
|
||
Un _Cron Job_ ejecuta tareas, [Jobs](/docs/concepts/workloads/controllers/jobs-run-to-completion/), a intervalos regulares. | ||
|
||
Un objeto CronJob es como una línea de un archivo _crontab_ (tabla cron). Ejecuta un trabajo de forma periódica | ||
según un horario programado escrito en formato [Cron](https://en.wikipedia.org/wiki/Cron). | ||
|
||
{{< note >}} | ||
Todos los `horarios` **CronJob** se basan en la zona horaria del máster donde se inicia el trabajo. | ||
{{< /note >}} | ||
|
||
Para instrucciones sobre cómo crear y trabajar con trabajos programados, | ||
incluyendo definiciones de ejemplo, | ||
puedes consultar [Ejecutar tareas automatizadas con trabajos programados](/docs/tasks/job/automated-tasks-with-cron-jobs). | ||
|
||
{{% /capture %}} | ||
|
||
|
||
{{% capture body %}} | ||
|
||
## Limitaciones de las tareas programados | ||
|
||
Un trabajo programado crea un objeto job _como mínimo_ una vez por cada ejecución de su programación. Decimos "como mínimo" porque | ||
hay determinadas circunstancias bajo las cuales dos trabajos pueden crearse, o ninguno de ellos se crea. Se intenta que estos casos sean residuales, | ||
pero no pueden evitarse completamente. Por lo tanto, los trabajos deberían ser _idempotentes_, es decir, que se pueden ejecutar más de una vez con el mismo resultado. | ||
|
||
Si el valor de `startingDeadlineSeconds` se establece a un valor grande o se deja sin especificar (por defecto) | ||
y si el valor de `concurrencyPolicy` se establece a `Allow`, los trabajos siempre se ejecutarán por lo menos una vez. | ||
|
||
Para cada CronJob, el controlador de CronJob verifica cuántas programaciones se han perdido desde la última programación hasta el momento actual. | ||
Si hay más de 100 programaciones perdidas, entonces ya no vuelve a ejecutar el trabajo y registra el error: | ||
|
||
```` | ||
Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew. | ||
```` | ||
|
||
Es importante destacar que si el campo `startingDeadlineSeconds` está configurado, es decir, no es nulo (`nil`), el controlador cuenta cuántos trabajos perdidos se produjeron desde el valor de `startingDeadlineSeconds` | ||
hasta el momento actual, en vez de la última programación. Por ejemplo, si `startingDeadlineSeconds` es `200`, el controlador cuenta cuántos trabajos perdidos se produjeron en los últimos 200 segundos. | ||
|
||
Se cuenta un CronJob como perdido si no se ha podido crear a la hora programada. Por ejemplo, si establecemos el valor de `concurrencyPolicy` a `Forbid` y se intentó programar | ||
un CronJob cuando otro previamente programado estaba todavía ejecutándose, entonces contará como perdido. | ||
|
||
Por ejemplo, imagina que un CronJob se configura para programar un nuevo Job cada minuto a partir de las `08:30:00`, y su campo | ||
`startingDeadlineSeconds` no se configura. Si el controlador del CronJob no estuviera disponible de `08:29:00` a `10:21:00`, | ||
el trabajo no comenzaría porque el número de trabajos perdidos que se habría perdido en su programación sería superior a 100. | ||
|
||
Para ilustrar este concepto mejor, vamos a suponer que programamos un CronJob para que ejecute un nuevo Job cada minuto comenzando a las `08:30:00`, y establecemos el valor del campo | ||
`startingDeadlineSeconds` a 200 segundos. Si el controlador del CronJob no se encuentra disponible | ||
durante el mismo período que en el ejemplo anterior (`08:29:00` a `10:21:00`,) aún así el Job comenzará a las 10:22:00. | ||
Esto ocurre porque el controlador en este caso comprueba cuántas programaciones perdidas ha habido en los últimos 200 segundos (esto es, 3 programaciones que no se han ejecutado), en vez de comprobarlo a partir de la última programación hasta el momento actual. | ||
|
||
El CronJob es únicamente responsable de crear los Jobs que coinciden con su programación, y | ||
el Job por otro lado es el responsable de gestionar los Pods que representa. | ||
|
||
{{% /capture %}} |
238 changes: 238 additions & 0 deletions
238
content/es/docs/concepts/workloads/controllers/daemonset.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
--- | ||
title: DaemonSet | ||
content_template: templates/concept | ||
weight: 50 | ||
--- | ||
|
||
{{% capture overview %}} | ||
|
||
Un _DaemonSet_ garantiza que todos (o algunos) de los nodos ejecuten una copia de un Pod. Conforme se añade más nodos | ||
al clúster, nuevos Pods son añadidos a los mismos. Conforme se elimina nodos del clúster, dichos Pods se destruyen. | ||
Al eliminar un DaemonSet se limpian todos los Pods que han sido creados. | ||
|
||
Algunos casos de uso típicos de un DaemonSet son: | ||
|
||
- ejecutar un proceso de almacenamiento en el clúster, como `glusterd`, `ceph`, en cada nodo. | ||
- ejecutar un proceso de recolección de logs en cada nodo, como `fluentd` o `logstash`. | ||
- ejecutar un proceso de monitorización de nodos en cada nodo, como [Prometheus Node Exporter]( | ||
https://github.com/prometheus/node_exporter), [Sysdig Agent] (https://sysdigdocs.atlassian.net/wiki/spaces/Platform), `collectd`, | ||
[Dynatrace OneAgent](https://www.dynatrace.com/technologies/kubernetes-monitoring/), | ||
[AppDynamics Agent](https://docs.appdynamics.com/display/CLOUD/Container+Visibility+with+Kubernetes), | ||
[Datadog agent](https://docs.datadoghq.com/agent/kubernetes/daemonset_setup/), | ||
[New Relic agent](https://docs.newrelic.com/docs/integrations/kubernetes-integration/installation/kubernetes-installation-configuration), | ||
Ganglia `gmond` o un agente de Instana. | ||
|
||
De forma básica, se debería usar un DaemonSet, cubriendo todos los nodos, por cada tipo de proceso. | ||
En configuraciones más complejas se podría usar múltiples DaemonSets para un único tipo de proceso, | ||
pero con diferentes parámetros y/o diferentes peticiones de CPU y memoria según el tipo de hardware. | ||
|
||
{{% /capture %}} | ||
|
||
|
||
{{% capture body %}} | ||
|
||
## Escribir una especificación de DaemonSet | ||
|
||
### Crear un DaemonSet | ||
|
||
Un DaemonSet se describe por medio de un archivo YAML. Por ejemplo, el archivo `daemonset.yaml` de abajo describe un DaemonSet que ejecuta la imagen Docker de fluentd-elasticsearch: | ||
|
||
{{< codenew file="controllers/daemonset.yaml" >}} | ||
|
||
* Crear un DaemonSet basado en el archivo YAML: | ||
``` | ||
kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml | ||
``` | ||
|
||
### Campos requeridos | ||
|
||
Como con cualquier otra configuración de Kubernetes, un DaemonSet requiere los campos `apiVersion`, `kind`, y `metadata`. | ||
Para información general acerca de cómo trabajar con ficheros de configuración, ver los documentos [desplegar aplicaciones](/docs/user-guide/deploying-applications/), | ||
[configurar contenedores](/docs/tasks/), y [gestión de objetos usando kubectl](/docs/concepts/overview/object-management-kubectl/overview/). | ||
|
||
Un DaemonSet también necesita un sección [`.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status). | ||
|
||
### Plantilla Pod | ||
|
||
El campo `.spec.template` es uno de los campos obligatorios de la sección `.spec`. | ||
|
||
El campo `.spec.template` es una [plantilla Pod](/docs/concepts/workloads/pods/pod-overview/#pod-templates). Tiene exactamente el mismo esquema que un [Pod](/docs/concepts/workloads/pods/pod/), | ||
excepto por el hecho de que está anidado y no tiene los campos `apiVersion` o `kind`. | ||
|
||
Además de los campos obligatorios de un Pod, la plantilla Pod para un DaemonSet debe especificar | ||
las etiquetas apropiadas (ver [selector de pod](#pod-selector)). | ||
|
||
Una plantilla Pod para un DaemonSet debe tener una [`RestartPolicy`](/docs/user-guide/pod-states) | ||
igual a `Always`, o no indicarse, lo cual asume por defecto el valor `Always`. | ||
|
||
### Selector de Pod | ||
|
||
El campo `.spec.selector` es un selector de pod. Funciona igual que el campo `.spec.selector` | ||
de un [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/). | ||
|
||
A partir de Kubernetes 1.8, se debe configurar un selector de pod que coincida con las | ||
etiquetas definidas en el `.spec.template`. Así, el selector de pod ya no asume valores por defecto cuando no se indica. | ||
Dichos valores por defecto no eran compatibles con `kubectl apply`. Además, una vez que se ha creado el DaemonSet, | ||
su campo `.spec.selector` no puede alterarse porque, si fuera el caso, ello podría resultar | ||
en Pods huérfanos, lo cual confundiría a los usuarios. | ||
|
||
El campo `.spec.selector` es un objeto que, a su vez, consiste en dos campos: | ||
|
||
* `matchLabels` - funciona igual que el campo `.spec.selector` de un [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/). | ||
* `matchExpressions` - permite construir selectores más sofisticados indicando la clave, | ||
la lista de valores y un operador para relacionar la clave y los valores. | ||
|
||
Cuando se configura ambos campos, el resultado es conjuntivo (AND). | ||
|
||
Si se especifica el campo `.spec.selector`, entonces debe coincidir con el campo `.spec.template.metadata.labels`. Aquellas configuraciones que no coinciden, son rechazadas por la API. | ||
|
||
Además, normalmente no se debería crear ningún Pod con etiquetas que coincidan con el selector, bien sea de forma directa, via otro | ||
DaemonSet, o via otro controlador como un ReplicaSet. De ser así, el controlador del DaemonSet | ||
pensará que dichos Pods fueron en realidad creados por él mismo. Kubernetes, en cualquier caso, no te impide realizar esta | ||
operación. Un caso donde puede que necesites hacer esto es cuando quieres crear manualmente un Pod con un valor diferente en un nodo para pruebas. | ||
|
||
### Ejecutar Pods sólo en algunos Nodos | ||
|
||
Si se configura un `.spec.template.spec.nodeSelector`, entonces el controlador del DaemonSet | ||
creará los Pods en aquellos nodos que coincidan con el [selector de nodo](/docs/concepts/configuration/assign-pod-node/) indicado. | ||
De forma similar, si se configura una `.spec.template.spec.affinity`, | ||
entonces el controlador del DaemonSet creará los Pods en aquellos nodos que coincidan con la [afinidad de nodo](/docs/concepts/configuration/assign-pod-node/) indicada. | ||
Si no se configura ninguno de los dos, entonces el controlador del DaemonSet creará los Pods en todos los nodos. | ||
|
||
## Cómo se planifican los Pods procesos | ||
|
||
### Planificados por el controlador del DaemonSet (deshabilitado por defecto a partir de 1.12) | ||
|
||
Normalmente, el planificador de Kubernetes determina la máquina donde se ejecuta un Pod. Sin embargo, los Pods | ||
creados por el controlador del DaemonSet ya tienen la máquina seleccionada (puesto que cuando se crea el Pod, | ||
se indica el campo `.spec.nodeName`, y por ello el planificador los ignora). Por lo tanto: | ||
|
||
- El controlador del DaemonSet no tiene en cuenta el campo [`unschedulable`](/docs/admin/node/#manual-node-administration) de un nodo. | ||
- El controlador del DaemonSet puede crear Pods incluso cuando el planificador no ha arrancado, lo cual puede ayudar en el arranque del propio clúster. | ||
|
||
|
||
### Planificados por el planificador por defecto de Kubernetes (habilitado por defecto desde 1.12) | ||
|
||
{{< feature-state state="beta" for-kubernetes-version="1.12" >}} | ||
|
||
Un DaemonSet garantiza que todos los nodos elegibles ejecuten una copia de un Pod. | ||
Normalmente, es el planificador de Kubernetes quien determina el nodo donde se ejecuta un Pod. Sin embargo, | ||
los pods del DaemonSet son creados y planificados por el mismo controlador del DaemonSet. | ||
Esto introduce los siguientes inconvenientes: | ||
|
||
* Comportamiento inconsistente de los Pods: Los Pods normales que están esperando | ||
a ser creados, se encuentran en estado `Pending`, pero los pods del DaemonSet no pasan por el estado `Pending`. | ||
Esto confunde a los usuarios. | ||
* La [prioridad y el comportamiento de apropiación de Pods](/docs/concepts/configuration/pod-priority-preemption/) | ||
se maneja por el planificador por defecto. Cuando se habilita la contaminación, el controlador del DaemonSet | ||
tomará la decisiones de planificación sin considerar ni la prioridad ni la contaminación del pod. | ||
|
||
`ScheduleDaemonSetPods` permite planificar DaemonSets usando el planificador por defecto | ||
en vez del controlador del DaemonSet, añadiendo la condición `NodeAffinity` | ||
a los pods del DaemonSet, en vez de la condición `.spec.nodeName`. El planificador por defecto | ||
se usa entonces para asociar el pod a su servidor destino. Si la afinidad de nodo del | ||
pod del DaemonSet ya existe, se sustituye. El controlador del DaemonSet sólo realiza | ||
estas operaciones cuando crea o modifica los pods del DaemonSet, y no se realizan cambios | ||
al `spec.template` del DaemonSet. | ||
|
||
```yaml | ||
nodeAffinity: | ||
requiredDuringSchedulingIgnoredDuringExecution: | ||
nodeSelectorTerms: | ||
- matchFields: | ||
- key: metadata.name | ||
operator: In | ||
values: | ||
- target-host-name | ||
``` | ||
Adicionalmente, se añade de forma automática la tolerancia `node.kubernetes.io/unschedulable:NoSchedule` | ||
a los Pods del DaemonSet. Así, el planificador por defecto ignora los nodos | ||
`unschedulable` cuando planifica los Pods del DaemonSet. | ||
|
||
|
||
### Contaminaciones (taints) y Tolerancias (tolerations) | ||
|
||
A pesar de que los Pods de proceso respetan las | ||
[contaminaciones y tolerancias](/docs/concepts/configuration/taint-and-toleration), | ||
la siguientes tolerancias son añadidas a los Pods del DaemonSet de forma automática | ||
según las siguientes características: | ||
|
||
| Clave de tolerancia | Efecto | Versión | Descripción | | ||
| ---------------------------------------- | ---------- | ------- | ------------------------------------------------------------ | | ||
| `node.kubernetes.io/not-ready` | NoExecute | 1.13+ | Los pods del DaemonSet no son expulsados cuando hay problemas de nodo como una partición de red. | | ||
| `node.kubernetes.io/unreachable` | NoExecute | 1.13+ | Los pods del DaemonSet no son expulsados cuando hay problemas de nodo como una partición de red. | | ||
| `node.kubernetes.io/disk-pressure` | NoSchedule | 1.8+ | Los pods del DaemonSet no son expulsados cuando hay problemas de nodo como la falta de espacio en disco. | | ||
| `node.kubernetes.io/memory-pressure` | NoSchedule | 1.8+ | Los pods del DaemonSet no son expulsados cuando hay problemas de nodo como la falta de memoria. | | ||
| `node.kubernetes.io/unschedulable` | NoSchedule | 1.12+ | Los pods del DaemonSet toleran los atributos unschedulable del planificador por defecto. | | ||
| `node.kubernetes.io/network-unavailable` | NoSchedule | 1.12+ | Los pods del DaemonSet, que usan la red del servidor anfitrión, toleran los atributos network-unavailable del planificador por defecto. | | ||
|
||
|
||
## Comunicarse con los Pods de los DaemonSets | ||
|
||
Algunos patrones posibles para la comunicación con los Pods de un DaemonSet son: | ||
|
||
- **Push**: Los Pods del DaemonSet se configuran para enviar actualizaciones a otro servicio, | ||
como una base de datos de estadísticas. No tienen clientes. | ||
- **NodeIP y Known Port**: Los Pods del DaemonSet pueden usar un `hostPort`, de forma que se les puede alcanzar via las IPs del nodo. Los clientes conocen la lista de IPs del nodo de algún modo, | ||
y conocen el puerto acordado. | ||
- **DNS**: Se crea un [servicio headless](/docs/concepts/services-networking/service/#headless-services) con el mismo selector de pod, | ||
y entonces se descubre a los DaemonSets usando los recursos `endpoints` o mediante múltiples registros de tipo A en el DNS. | ||
- **Service**: Se crea un servicio con el mismo selector de Pod, y se usa el servicio para llegar al proceso de uno de los nodos. (No hay forma de determinar el nodo exacto.) | ||
|
||
## Actualizar un DaemonSet | ||
|
||
Si se cambian las etiquetas de nodo, el DaemonSet comenzará de forma inmediata a añadir Pods a los nuevos nodos que coincidan y a eliminar | ||
los Pods de aquellos nuevos nodos donde no coincidan. | ||
|
||
Puedes modificar los Pods que crea un DaemonSet. Sin embargo, no se permite actualizar todos los campos de los Pods. | ||
Además, el controlador del DaemonSet utilizará la plantilla original la próxima vez que se cree un nodo (incluso con el mismo nombre). | ||
|
||
Puedes eliminar un DaemonSet. Si indicas el parámetro `--cascade=false` al usar `kubectl`, | ||
entonces los Pods continuarán ejecutándose en los nodos. Así, puedes crear entonces un nuevo DaemonSet con una plantilla diferente. | ||
El nuevo DaemonSet con la plantilla diferente reconocerá a todos los Pods existentes que tengan etiquetas coincidentes y | ||
no modificará o eliminará ningún Pod aunque la plantilla no coincida con los Pods desplegados. | ||
Entonces, deberás forzar la creación del nuevo Pod eliminando el Pod mismo o el nodo. | ||
|
||
A partir de las versión 1.6 de Kubernetes, puedes [llevar a cabo una actualización continua](/docs/tasks/manage-daemon/update-daemon-set/) en un DaemonSet. | ||
|
||
## Alternativas al DaemonSet | ||
|
||
### Secuencias de comandos de inicialización | ||
|
||
Aunque es perfectamente posible ejecutar procesos arrancándolos directamente en un nodo (ej. usando | ||
`init`, `upstartd`, o `systemd`), existen numerosas ventajas si se realiza via un DaemonSet: | ||
|
||
- Capacidad de monitorizar y gestionar los logs de los procesos del mismo modo que para las aplicaciones. | ||
- Mismo lenguaje y herramientas de configuración (ej. plantillas de Pod, `kubectl`) tanto para los procesos como para las aplicaciones. | ||
- Los procesos que se ejecutan en contenedores con límitaciones de recursos aumentan el aislamiento entre dichos procesos y el resto de contenedores de aplicaciones. | ||
Sin embargo, esto también se podría conseguir ejecutando los procesos en un contenedor en vez de un Pod | ||
(ej. arrancarlos directamente via Docker). | ||
|
||
### Pods individuales | ||
|
||
Es posible crear Pods directamente sin indicar el nodo donde ejecutarse. Sin embargo, | ||
la ventaja del DaemonSet es que sustituye los Pods que se eliminan o terminan por cualquier razón, como en el caso | ||
de un fallo del nodo o una intervención disruptiva de mantenimiento del nodo, como la actualización del kernel. | ||
Por esta razón, deberías siempre utilizar un DaemonSet en vez de crear Pods individuales. | ||
|
||
### Pods estáticos | ||
|
||
Es posible crear Pods a partir de archivos en el directorio donde está escuchando el proceso Kubelet. | ||
Este tipo de Pods se denomina [pods estáticos](/docs/concepts/cluster-administration/static-pod/). | ||
A diferencia del DaemonSet, los Pods estáticos no se pueden gestionar con kubectl | ||
o cualquier otro cliente de la API de Kubernetes. Los Pods estáticos no dependen del apiserver, lo cual los hace | ||
convenientes para el arranque inicial del clúster. Además, puede que los Pods estáticos se deprecien en el futuro. | ||
|
||
### Deployments | ||
|
||
Los DaemonSets son similares a los [Deployments](/docs/concepts/workloads/controllers/deployment/) en el sentido que | ||
ambos crean Pods, y que dichos Pods tienen procesos que no se espera que terminen (ej. servidores web, | ||
servidores de almacenamiento). | ||
|
||
Utiliza un Deployment para definir servicios sin estado, como las interfaces de usuario, donde el escalado vertical y horizontal | ||
del número de réplicas y las actualizaciones continuas son mucho más importantes que el control exacto del servidor donde se ejecuta el Pod. | ||
Utiliza un DaemonSet cuando es importante que una copia de un Pod siempre se ejecute en cada uno de los nodos, | ||
y cuando se necesite que arranque antes que el resto de Pods. | ||
|
||
{{% /capture %}} |
Oops, something went wrong.