Spanish Translation
parent
944ab0d67d
commit
edad9d9e8d
|
@ -0,0 +1,457 @@
|
|||
---
|
||||
title: Jobs - Ejecución hasta el final
|
||||
content_template: templates/concept
|
||||
feature:
|
||||
title: Ejecución en lotes
|
||||
description: >
|
||||
Además de los servicios, Kubernetes puede gestionar tus trabajos por lotes y CI, sustituyendo los contenedores que fallen, si así se desea.
|
||||
weight: 70
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
Un Job crea uno o más Pods y se asegura de que un número específico de ellos termina de forma satisfactoria.
|
||||
Conforme los pods terminan satisfactoriamente, el Job realiza el seguimiento de las ejecuciones satisfactorias.
|
||||
Cuando se alcanza un número específico de ejecuciones satisfactorias, la tarea (esto es, el Job) se completa.
|
||||
Al eliminar un Job se eliminan los Pods que haya creado.
|
||||
|
||||
Un caso simple de uso es crear un objeto Job para que se ejecute un Pod de manera fiable hasta el final.
|
||||
El objeto Job arrancará un nuevo Pod si el primer Pod falla o se elimina (por ejemplo
|
||||
como consecuencia de un fallo de hardware o un reinicio en un nodo).
|
||||
|
||||
También se puede usar un Job para ejecutar múltiples Pods en paralelo.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Ejecutar un Job de ejemplo
|
||||
|
||||
Aquí se muestra un ejemplo de configuración de Job. Este ejemplo calcula los primeros 2000 decimales de π y los imprime por pantalla.
|
||||
Tarda unos 10s en completarse.
|
||||
|
||||
{{< codenew file="controllers/job.yaml" >}}
|
||||
|
||||
Puedes ejecutar el ejemplo con este comando:
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/job.yaml
|
||||
```
|
||||
```
|
||||
job "pi" created
|
||||
```
|
||||
|
||||
Comprueba el estado del Job con `kubectl`:
|
||||
|
||||
```shell
|
||||
kubectl describe jobs/pi
|
||||
```
|
||||
```
|
||||
Name: pi
|
||||
Namespace: default
|
||||
Selector: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495
|
||||
Labels: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495
|
||||
job-name=pi
|
||||
Annotations: <none>
|
||||
Parallelism: 1
|
||||
Completions: 1
|
||||
Start Time: Tue, 07 Jun 2016 10:56:16 +0200
|
||||
Pods Statuses: 0 Running / 1 Succeeded / 0 Failed
|
||||
Pod Template:
|
||||
Labels: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495
|
||||
job-name=pi
|
||||
Containers:
|
||||
pi:
|
||||
Image: perl
|
||||
Port:
|
||||
Command:
|
||||
perl
|
||||
-Mbignum=bpi
|
||||
-wle
|
||||
print bpi(2000)
|
||||
Environment: <none>
|
||||
Mounts: <none>
|
||||
Volumes: <none>
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: pi-dtn4q
|
||||
```
|
||||
|
||||
Para ver los Pods de un Job que se han completado, usa `kubectl get pods`.
|
||||
|
||||
Para listar todos los Pods que pertenecen a un Job de forma que sea legible, puedes usar un comando como:
|
||||
|
||||
```shell
|
||||
pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}')
|
||||
echo $pods
|
||||
```
|
||||
```
|
||||
pi-aiw0a
|
||||
```
|
||||
|
||||
En este caso, el selector es el mismo que el selector del Job. La opción `--output=jsonpath` indica un expresión
|
||||
que simplemente obtiene el nombre de cada Pod en la lista devuelta.
|
||||
|
||||
Mira la salida estándar de uno de los Pods:
|
||||
|
||||
```shell
|
||||
$ kubectl logs $pods
|
||||
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901
|
||||
```
|
||||
|
||||
## Escribir una especificación de Job
|
||||
|
||||
Como con el resto de configuraciones de Kubernetes, un Job necesita los campos `apiVersion`, `kind`, y `metadata`.
|
||||
|
||||
Un Job también necesita la [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 el único campo obligatorio de `.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/user-guide/pods),
|
||||
excepto por el hecho de que está anidado y no tiene el campo `apiVersion` o `kind`.
|
||||
|
||||
Además de los campos olbigatorios de un Pod, una plantilla Pod de un Job debe indicar las etiquetas apropiadas
|
||||
(ver [selector de pod](#pod-selector)) y una regla de reinicio apropiada.
|
||||
|
||||
Sólo se permite los valores `Never` o `OnFailure` para [`RestartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy).
|
||||
|
||||
### Selector de Pod
|
||||
|
||||
El campo `.spec.selector` es opcional. En la práctica mayoría de los casos no deberías configurarlo.
|
||||
Mira la sección sobre [configurar tu propio selector de pod](#specifying-your-own-pod-selector).
|
||||
|
||||
|
||||
### Jobs en paralelo
|
||||
|
||||
Hay tres tipos principales de tarea aptos para ejecutarse como un Job:
|
||||
|
||||
1. Jobs no paralelos
|
||||
- normalmente, sólo se arranca un Pod, a menos que el Pod falle.
|
||||
- el Job se completa tan pronto como su Pod termine de forma satisfactoria.
|
||||
1. Jobs en paralelo con un *cupo fijo de terminación*:
|
||||
- se configura un valor positivo distinto de cero para el campo `.spec.completions`.
|
||||
- el Job representa la tarea en general, y se completa cuando hay una ejecución satisfactoria de un Pod por cada valor dentro del rango de 1 a `.spec.completions`.
|
||||
- **no implementado todavía:** A cada Pod se le pasa un índice diferenente dentro del rango de 1 a `.spec.completions`.
|
||||
1. Jobs en paralelo con una *cola de trabajo*:
|
||||
- no se especifica el campo `.spec.completions`, por defecto `.spec.parallelism`.
|
||||
- los Pods deben coordinarse entre ellos mismos o a través de un servicio externo que determine quién debe trabajar en qué.
|
||||
Por ejemplo, un Pod podría ir a buscar un lote de hasta N ítems de una cola de trabajo.
|
||||
- cada Pod es capaz de forma independiente de determinar si sus compañeros han terminado o no, y como consecuencia el Job entero ha terminado.
|
||||
- cuando _cualquier_ Pod del Job termina con éxito, no se crean nuevos Pods.
|
||||
- una vez que al menos uno de los Pods ha terminado con éxito y todos los Pods han terminado, entonces el Job termina con éxito.
|
||||
- una vez que cualquier Pod ha terminado con éxito, ningún otro Pod debería continuar trabajando en la misma tarea o escribiendo ningún resultado. Todos ellos deberían estar en proceso de terminarse.
|
||||
|
||||
En un Job _no paralelo_, no debes indicar el valor de `.spec.completions` ni `.spec.parallelism`. Cuando ambos se dejan
|
||||
sin valor, ambos se predeterminan a 1.
|
||||
|
||||
En un Job con _cupo fijo de terminación_, deberías poner el valor de `.spec.completions` al número de terminaciones que se necesiten.
|
||||
Puedes dar un valor a `.spec.parallelism`, o dejarlo sin valor, en cuyo caso se predetermina a 1.
|
||||
|
||||
En un Job con _cola de trabajo_, no debes indicar el valor de `.spec.completions`, y poner el valor de `.spec.parallelism` a
|
||||
un entero no negativo.
|
||||
|
||||
Para más información acerca de cómo usar los distintos tipos de Job, ver la sección de [patrones de job](#job-patterns).
|
||||
|
||||
|
||||
#### Controlar el paralelismo
|
||||
|
||||
El paralelismo solicitado (`.spec.parallelism`) puede usar cualquier valor no negativo.
|
||||
Si no se indica, se predeterminad a 1.
|
||||
Si se indica como 0, entonces el Job se pausa de forma efectiva hasta que se incremente.
|
||||
|
||||
El paralelismo actual (número de pods ejecutándose en cada momento) puede que sea mayor o menor que el solicitado,
|
||||
por los siguientes motivos:
|
||||
|
||||
- Para los Jobs con _cupo fijo de terminaciones_, el número actual de pods ejecutándose en paralelo no excede el número de terminaciones pendientes.
|
||||
Los valores superiores de `.spec.parallelism` se ignoran.
|
||||
- Para los Jobs con _cola de trabajo_, no se arranca nuevos Pods después de que cualquier Pod se haya completado -- sin embargo, se permite que se completen los Pods pendientes.
|
||||
- Cuando el controlador no ha tenido tiempo para reaccionar.
|
||||
- Cuando el controlador no pudo crear los Pods por el motivo que fuera (falta de `ResourceQuota`, falta de permisos, etc.),
|
||||
entonces puede que haya menos pods que los solicitados.
|
||||
- El controlador puede que regule la creación de nuevos Pods debido al excesivo número de fallos anteriores en el mismo Job.
|
||||
- Cuando un Pod se para de forma controlada, lleva tiempo pararlo.
|
||||
|
||||
## Gestionar Fallos de Pod y Contenedor
|
||||
|
||||
Un contenedor de un Pod puede fallar por cualquier motivo, como porque el proceso que se estaba ejecutando termina con un código de salida distinto de cero,
|
||||
o porque se mató el contenedor por exceder un límite de memoria, etc. Si esto ocurre, y se tiene
|
||||
`.spec.template.spec.restartPolicy = "OnFailure"`, entonces el Pod permance en el nodo,
|
||||
pero el contenedor se vuelve a ejecutar. Por lo tanto, tu aplicación debe poder gestionar el caso en que se reinicia de forma local,
|
||||
o bien especificar `.spec.template.spec.restartPolicy = "Never"`.
|
||||
Ver el [ciclo de vida de un pod](/docs/concepts/workloads/pods/pod-lifecycle/#example-states) para más información sobre `restartPolicy`.
|
||||
|
||||
Un Pod entero puede también fallar por cualquier motivo, como cuando se expulsa al Pod del nodo
|
||||
(porque el nodo se actualiza, reinicia, elimina, etc.), o si un contenedor del Pod falla
|
||||
cuando `.spec.template.spec.restartPolicy = "Never"`. Cuando un Pod falla, entonces el controlador del Job
|
||||
arranca un nuevo Pod. Esto quiere decir que tu aplicación debe ser capaz de gestionar el caso en que se reinicia en un nuevo pod.
|
||||
En particular, debe ser capaz de gestionar los ficheros temporales, los bloqueos, los resultados incompletos, y cualquier otra dependencia
|
||||
de ejecuciones previas.
|
||||
|
||||
Nótese que incluso si se configura `.spec.parallelism = 1` y `.spec.completions = 1` y
|
||||
`.spec.template.spec.restartPolicy = "Never"`, el mismo programa puede arrancarse dos veces.
|
||||
|
||||
Si se especifica `.spec.parallelism` y `.spec.completions` con valores mayores que 1,
|
||||
entonces puede que haya múltiples pods ejecutándose a la vez. Por ello, tus pods deben tolerar la concurrencia.
|
||||
|
||||
### Regla de retroceso de Pod por fallo
|
||||
|
||||
Hay situaciones en que quieres que el Job falle después de intentar ejecutarlo unas cuantas veces debido
|
||||
a un error lógico en la configuración, etc.
|
||||
Para hacerlo, pon el valor de `.spec.backoffLimit` al número de reintentos que quieres
|
||||
antes de considerar el Job como fallido. El límite de retroceso se predetermina a 6.
|
||||
Los Pods fallidos asociados al Job son recreados por el controlador del Job con un
|
||||
retroceso exponencial (10s, 20s, 40s ...) limitado a seis minutos. El contador
|
||||
de retroceso se resetea si no aparecen Pods fallidos antes del siguiente chequeo de estado del Job.
|
||||
|
||||
{{< note >}}
|
||||
El problema [#54870](https://github.com/kubernetes/kubernetes/issues/54870) todavía existe en las versiones de Kubernetes anteriores a la versión 1.12
|
||||
{{< /note >}}
|
||||
|
||||
## Terminación y Limpieza de un Job
|
||||
|
||||
Cuando un Job se completa, ya no se crea ningún Pod, pero tampoco se elimina los Pods. Guardarlos permite
|
||||
ver todavía los logs de los pods acabados para comprobar errores, avisos, o cualquier otro resultado de diagnóstico.
|
||||
El objeto job también se conserva una vez que se ha completado para que se pueda ver su estado. Es decisión del usuario si elimina
|
||||
los viejos jobs después de comprobar su estado. Eliminar el job con el comando `kubectl` (ej. `kubectl delete jobs/pi` o `kubectl delete -f ./job.yaml`).
|
||||
Cuando eliminas un job usando el comando `kubectl`, todos los pods que creó se eliminan también.
|
||||
|
||||
Por defecto, un Job se ejecutará de forma ininterrumpida a menos que uno de los Pods falle, en cuyo caso el Job se fija en el valor de
|
||||
`.spec.backoffLimit` descrito arriba. Otra forma de acabar un Job es poniéndole un vencimiento activo.
|
||||
Haz esto poniendo el valor del campo `.spec.activeDeadlineSeconds` del Job a un número de segundos.
|
||||
|
||||
El campo `activeDeadlineSeconds` se aplica a la duración del job, independientemente de cuántos Pods se hayan creado.
|
||||
Una vez que el Job alcanza `activeDeadlineSeconds`, se terminan todos sus Pods y el estado del Job se pone como `type: Failed` con `reason: DeadlineExceeded`.
|
||||
|
||||
Fíjate que el campo `.spec.activeDeadlineSeconds` de un Job tiene precedencia sobre el campo `.spec.backoffLimit`.
|
||||
Por lo tanto, un Job que está reintentando uno o más Pods fallidos no desplegará nuevos Pods una vez que alcance el límite de tiempo especificado por `activeDeadlineSeconds`,
|
||||
incluso si todavía no se ha alcanzado el `backoffLimit`.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: pi-with-timeout
|
||||
spec:
|
||||
backoffLimit: 5
|
||||
activeDeadlineSeconds: 100
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: pi
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
Fíjate que tanto la especificación del Job como la [especificación de la plantilla Pod](/docs/concepts/workloads/pods/init-containers/#detailed-behavior)
|
||||
dentro del Job tienen un campo `activeDeadlineSeconds`. Asegúrate que pones el valor de este campo de forma adecuada.
|
||||
|
||||
## Limpiar los Jobs terminados automáticamente
|
||||
|
||||
Normalmente, los Jobs que han terminado ya no se necesitan en el sistema. Conservarlos sólo añade
|
||||
más presión al servidor API. Si dichos Jobs no se gestionan de forma directa por un controlador de más alto nivel,
|
||||
como los [CronJobs](/docs/concepts/workloads/controllers/cron-jobs/), los Jobs pueden
|
||||
limpiarse por medio de CronJobs en base a la regla de limpieza basada en capacidad que se haya especificado.
|
||||
|
||||
### Mecanismo TTL para Jobs terminados
|
||||
|
||||
{{< feature-state for_k8s_version="v1.12" state="alpha" >}}
|
||||
|
||||
Otra forma de limpiar los Jobs terminados (bien `Complete` o `Failed`)
|
||||
de forma automática es usando un mecanismo TTL proporcionado por un
|
||||
[controlador TTL](/docs/concepts/workloads/controllers/ttlafterfinished/) de recursos finalizados,
|
||||
indicando el valor `.spec.ttlSecondsAfterFinished` del Job.
|
||||
|
||||
Cuando el controlador TTL limpia el Job, lo eliminará en cascada,
|
||||
esto es, eliminará sus objetos subordinados, como Pods, junto con el Job. Nótese
|
||||
que cuando se elimina el Job, sus garantías de ciclo de vida, como los finalizadores,
|
||||
se tendrán en cuenta.
|
||||
|
||||
Por ejemplo:
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: pi-with-ttl
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 100
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: pi
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
Aquí el Job `pi-with-ttl` será candidato a ser automáticamente eliminado, `100`
|
||||
segundos después de que termine.
|
||||
|
||||
Si el campo se pone a `0`, el Job será candidato a ser automáticamente eliminado
|
||||
inmediatamente después de haber terminado. Si no se pone valor al campo, este Job no será eliminado
|
||||
por el controlador TTL una vez concluya.
|
||||
|
||||
Nótese que este mecanismo TTL está todavía en alpha, a través de la característica denominada `TTLAfterFinished`.
|
||||
Para más información, ver la documentación del [controlador TTL](/docs/concepts/workloads/controllers/ttlafterfinished/) para
|
||||
recursos terminados.
|
||||
|
||||
## Patrones de Job
|
||||
|
||||
El objeto Job puede usarse para dar soporte a la ejecución fiable de Pods en paralelo. El objeto Job
|
||||
no se diseñó para dar soporte a procesos paralelos estrechamente comunicados, como los que comúnmente
|
||||
se encuentran en la computación científica. Eso sí, permite el proceso paralelo de un conjunto de *ítems de trabajo* independientes, pero relacionados entre sí.
|
||||
Estos pueden ser correos a enviar, marcos a renderizar, archivos a codificar, rangos de claves en una base de datos NoSQL a escanear, y demás.
|
||||
|
||||
En un sistema complejo, puede haber múltiples diferentes conjuntos de ítems de trabajo. Aquí sólo se está
|
||||
considerando un conjunto de ítems de trabajo que el usuario quiere gestionar de forma conjunta — un *proceso por lotes*.
|
||||
|
||||
Hay varios patrones diferentes para computación en paralelo, cada uno con sus fortalezas y sus debilidades.
|
||||
Los sacrificios a tener en cuenta son:
|
||||
|
||||
- Un objeto Job para cada ítem de trabajo vs. un objeto Job simple para todos los ítems de trabajo. El último es mejor
|
||||
para grandes números de ítems de trabajo. El primero añade sobrecarga para el usuario y para el sistema
|
||||
al tener que gestionar grandes números de objetos Job.
|
||||
- El número de pods creados es igual al número de ítems de trabajo vs. cada Pod puede procesar múltiplese ítems de trabajo.
|
||||
El primero típicamente requiere menos modificaciones al código existente y a los contenedores.
|
||||
El último es mejor cuanto mayor sea el número de ítems de trabajo, por las mismas razones que antes..
|
||||
- Varios enfoques usan una cola de trabajo. Ello requiere ejecutar un servicio de colas,
|
||||
y modificaciones a las aplicaciones o contenedores existentes para que hagan uso de la cola de trabajo.
|
||||
Otras estrategias son más fáciles de adaptar a una aplicación ya usando contenedores.
|
||||
|
||||
|
||||
Los sacrificios a tener en cuenta se indican a continuación, donde las columnas 2 a 4 representan los sacrificios de arriba.
|
||||
Los nombres de los patrones son también enlaces a ejemplos e información más detallada.
|
||||
|
||||
| Patrón | Objeto Job simple | ¿Menos pods que ítems de trabajo? | ¿No modificar la aplicación? | ¿Funciona en Kube 1.1? |
|
||||
| -------------------------------------------------------------------- |:-----------------:|:---------------------------:|:-------------------:|:-------------------:|
|
||||
| [Extensión de la Plantilla Job](/docs/tasks/job/parallel-processing-expansion/) | | | ✓ | ✓ |
|
||||
| [Cola con Pod por Ítem de Trabajo](/docs/tasks/job/coarse-parallel-processing-work-queue/) | ✓ | | a veces | ✓ |
|
||||
| [Cola con Cuenta Variable de Pods](/docs/tasks/job/fine-parallel-processing-work-queue/) | ✓ | ✓ | | ✓ |
|
||||
| Job simple con Asignación Estática de Trabajo | ✓ | | ✓ | |
|
||||
|
||||
Cuando se especifican terminaciones con `.spec.completions`, cada Pod creado por el controlado del Job
|
||||
tiene un [`spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)idéntico.
|
||||
Esto significa que todos los pods de una tarea tendrán la misma línea de comandos y la
|
||||
misma imagne, los mismo volúmenes, y (casi) las mismas variables de entorno.
|
||||
Estos patrones otorgan diferentes formas de organizar los pods para que trabajen en cosas distintas.
|
||||
|
||||
Esta tabla muestra la configuración necesaria para `.spec.parallelism` y `.spec.completions` para cada uno de los patrones.
|
||||
Aquí, `T` es el número de ítems de trabajo.
|
||||
|
||||
| Patrón | `.spec.completions` | `.spec.parallelism` |
|
||||
| -------------------------------------------------------------------- |:-------------------:|:--------------------:|
|
||||
| [Extensión de la Plantilla Job](/docs/tasks/job/parallel-processing-expansion/) | 1 | debería ser 1 |
|
||||
| [Cola con Pod por Ítem de Trabajo](/docs/tasks/job/coarse-parallel-processing-work-queue/) | T | cualquiera |
|
||||
| [Cola con Cuenta Variable de Pods](/docs/tasks/job/fine-parallel-processing-work-queue/) | 1 | cualquiera |
|
||||
| Job simple con Asignación Estática de Trabajo | T | cualquiera |
|
||||
|
||||
|
||||
## Uso Avanzado
|
||||
|
||||
### Especificar tu propio selector de pod
|
||||
|
||||
Normalmente, cuando creas un objeto Job, no especificas el campo `.spec.selector`.
|
||||
La lógica por defecto del sistema añade este campo cuando se crea el Job.
|
||||
Se elige un valor de selector que no se entremezcle con otras tareas.
|
||||
|
||||
Sin embargo, en algunos casos, puede que necesites sobreescribir este selector que se configura de forma automática.
|
||||
Para ello, puedes indicar el valor de `.spec.selector` en el Job.
|
||||
|
||||
Pero ten mucho cuidado cuando lo hagas. Si configuras un selector de etiquta que no
|
||||
es único para los pods de ese Job, y que selecciona Pods que no tienen que ver,
|
||||
entonces estos últimos pueden ser eliminados, o este Job puede contar los otros
|
||||
Pods para terminarse, o uno o ambos Jobs pueden negarse a crear Pods o ejecutarse hasta el final.
|
||||
Si se elige un selector que no es único, entonces otros controladores (ej. ReplicationController)
|
||||
y sus Pods puede comportarse de forma impredecibles también. Kubernetes no te impide cometer un error
|
||||
especificando el `.spec.selector`.
|
||||
|
||||
Aquí se muestra un ejemplo de un caso en que puede que necesites usar esta característica.
|
||||
|
||||
Digamos que el Job `viejo` todavía está ejeuctándose. Quieres que los Pods existentes
|
||||
sigan corriendo, pero quieres que el resto de los Pods que se creen
|
||||
usen una plantilla pod diferente y que el Job tenga un nombre nuevo.
|
||||
Como no puedes modificar el Job porque esos campos no son modificables, eliminas el Job `old`,
|
||||
pero _dejas sus pods ejecutándose_ mediante el comando `kubectl delete jobs/old --cascade=false`.
|
||||
Antes de eliminarlo, apúntate el selector actual que está usando:
|
||||
|
||||
```
|
||||
kind: Job
|
||||
metadata:
|
||||
name: viejo
|
||||
...
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
job-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
|
||||
...
|
||||
```
|
||||
|
||||
Entonces, creas un nuevo Job con el nombre `nuevo` y le configuras explícitamente el mismo selector.
|
||||
Puesto que los Pods existentes tienen la etiqueta `job-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`,
|
||||
son controlados por el Job `nuevo` igualmente.
|
||||
|
||||
Necesitas configurar `manualSelector: true` en el nuevo Job, ya qye no estás usando
|
||||
el selector que normalmente se genera de forma automática por el sistema.
|
||||
|
||||
```
|
||||
kind: Job
|
||||
metadata:
|
||||
name: nuevo
|
||||
...
|
||||
spec:
|
||||
manualSelector: true
|
||||
selector:
|
||||
matchLabels:
|
||||
job-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
|
||||
...
|
||||
```
|
||||
|
||||
El mismo Job nuevo tendrá un uid distinto a `a8f3d00d-c6d2-11e5-9f87-42010af00002`.
|
||||
Poniendo `manualSelector: true` le dice al sistema que sabes lo que estás haciendo
|
||||
y que te permita hacer este desajuste.
|
||||
|
||||
## Alternativas
|
||||
|
||||
### Pods simples
|
||||
|
||||
Cuando el nodo donde un Pod simple se estaba ejecutando se reinicia o falla, dicho pod se termina
|
||||
y no será reinicado. Sin embargo, un Job creará nuevos Pods para sustituir a los que se han terminando.
|
||||
Por esta razón, se recomienda que se use un Job en vez de un Pod simple, incluso si tu aplicación
|
||||
sólo necesita un único Pod.
|
||||
|
||||
### Replication Controller
|
||||
|
||||
Los Jobs son complementarios a los [Replication Controllers](/docs/user-guide/replication-controller).
|
||||
Un Replication Controller gestiona aquellos Pods que se espera que no terminen (ej. servidores web), y un Job
|
||||
gestiona aquellos Pods que se espera que terminen (ej. tareas por lotes).
|
||||
|
||||
Como se discutió en el [Ciclo de vida de un Pod](/docs/concepts/workloads/pods/pod-lifecycle/), un `Job` *sólo* es apropiado
|
||||
para aquellos pods con `RestartPolicy` igual a `OnFailure` o `Never`.
|
||||
(Nota: Si `RestartPolicy` no se pone, el valor predeterminado es `Always`.)
|
||||
|
||||
### Job simple arranca que arranca un controlador de Pod
|
||||
|
||||
Otro patrón es aquel donde un Job simple crea un Pod que, a su vez, crea otros Pods, actuando como una especie
|
||||
de controlador personalizado para esos Pods. Esto da la máxima flexibilidad, pero puede que
|
||||
cueste un poco más de entender y ofrece menos integración con Kubernetes.
|
||||
|
||||
Un ejemplo de este patrón sería un Job que arranca un Pod que ejecuta una secuencia de comandos que, a su vez,
|
||||
arranca un controlador maestro de Spark (ver el [ejemplo de spark](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/spark/README.md)),
|
||||
ejecuta un manejador de spark, y a continuación lo limpia todo.
|
||||
|
||||
Una ventaja de este enfoque es que el proceso general obtiene la garantía del objeto Job,
|
||||
además del control completo de los Pods que se crean y cómo se les asigna trabajo.
|
||||
|
||||
## Cron Jobs {#cron-jobs}
|
||||
|
||||
Puedes utilizar un [`CronJob`](/docs/concepts/workloads/controllers/cron-jobs/) para crear un Job que se ejecute en una hora/fecha determinadas, de forma similar
|
||||
a la herramienta `cron` de Unix.
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,370 @@
|
|||
---
|
||||
title: ReplicaSet
|
||||
content_template: templates/concept
|
||||
weight: 10
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
El objeto de un ReplicaSet es el de mantener un conjunto estable de réplicas de Pods ejecutándose
|
||||
en todo momento. Así, se usa en numerosas ocasiones para garantizar la disponibilidad de un
|
||||
número específico de Pods idénticos.
|
||||
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Cómo funciona un ReplicaSet
|
||||
|
||||
Un ReplicaSet se define con campos, incluyendo un selector que indica cómo identificar a los Pods que puede adquirir,
|
||||
un número de réplicas indicando cuántos Pods debería gestionar, y una plantilla pod especificando los datos de los nuevos Pods
|
||||
que debería crear para conseguir el número de réplicas esperado. Un ReplicaSet alcanza entonces su propósito
|
||||
mediante la creación y eliminación de los Pods que sea necesario para alcanzar el número esperado.
|
||||
Cuando un ReplicaSet necesita crear nuevos Pods, utiliza su plantilla Pod.
|
||||
|
||||
El enlace que un ReplicaSet tiene hacia sus Pods es a través del campo del Pod denominado [metadata.ownerReferences](/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents),
|
||||
el cual indica qué recurso es el propietario del objeto actual. Todos los Pods adquiridos por un ReplicaSet tienen su propia
|
||||
información de identificación del ReplicaSet en su campo ownerReferences. Y es a través de este enlace
|
||||
cómo el ReplicaSet conoce el estado de los Pods que está gestionando y actúa en consecuencia.
|
||||
|
||||
Un ReplicaSet identifica los nuevos Pods a adquirir usando su selector. Si hay un Pod que no tiene OwnerReference
|
||||
o donde OwnerReference no es un controlador, pero coincide con el selector del ReplicaSet,
|
||||
este será inmediatamente adquirido por dicho ReplicaSet.
|
||||
|
||||
## Cuándo usar un ReplicaSet
|
||||
|
||||
Un ReplicaSet garantiza que un número específico de réplicas de un pod se está ejeuctando en todo momento.
|
||||
Sin embargo, un Deployment es un concepto de más alto nivel que gestiona ReplicaSets y
|
||||
proporciona actualizaciones de forma declarativa de los Pods junto con muchas otras características útiles.
|
||||
Por lo tanto, se recomienda el uso de Deployments en vez del uso directo de ReplicaSets, a no ser
|
||||
que se necesite una orquestración personalizada de actualización o no se necesite las actualizaciones en absoluto.
|
||||
|
||||
En realidad, esto quiere decir que puede que nunca necesites manipular los objetos ReplicaSet:
|
||||
en vez de ello, usa un Deployment, y define tu aplicación en la sección spec.
|
||||
|
||||
## Ejemplo
|
||||
|
||||
{{< codenew file="controllers/frontend.yaml" >}}
|
||||
|
||||
Si guardas este manifiesto en un archivo llamado `frontend.yaml` y lo lanzas en un clúster de Kubernetes,
|
||||
se creará el ReplicaSet definido y los Pods que maneja.
|
||||
|
||||
```shell
|
||||
kubectl apply -f http://k8s.io/examples/controllers/frontend.yaml
|
||||
```
|
||||
|
||||
Puedes ver los ReplicaSets actuales desplegados:
|
||||
```shell
|
||||
kubectl get rs
|
||||
```
|
||||
|
||||
Y ver el frontend que has creado:
|
||||
```shell
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
frontend 3 3 3 6s
|
||||
```
|
||||
|
||||
También puedes comprobar el estado del replicaset:
|
||||
```shell
|
||||
kubectl describe rs/frontend
|
||||
```
|
||||
|
||||
Y verás una salida parecida a la siguiente:
|
||||
```shell
|
||||
Name: frontend
|
||||
Namespace: default
|
||||
Selector: tier=frontend,tier in (frontend)
|
||||
Labels: app=guestbook
|
||||
tier=frontend
|
||||
Annotations: <none>
|
||||
Replicas: 3 current / 3 desired
|
||||
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
|
||||
Pod Template:
|
||||
Labels: app=guestbook
|
||||
tier=frontend
|
||||
Containers:
|
||||
php-redis:
|
||||
Image: gcr.io/google_samples/gb-frontend:v3
|
||||
Port: 80/TCP
|
||||
Requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
Environment:
|
||||
GET_HOSTS_FROM: dns
|
||||
Mounts: <none>
|
||||
Volumes: <none>
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-qhloh
|
||||
1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-dnjpy
|
||||
1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-9si5l
|
||||
```
|
||||
|
||||
Y por último, puedes comprobar los Pods que ha arrancado:
|
||||
```shell
|
||||
kubectl get Pods
|
||||
```
|
||||
|
||||
Deberías ver la información de cada Pod similar a:
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
frontend-9si5l 1/1 Running 0 1m
|
||||
frontend-dnjpy 1/1 Running 0 1m
|
||||
frontend-qhloh 1/1 Running 0 1m
|
||||
```
|
||||
|
||||
También puedes verificar que la referencia de propietario de dichos pods está puesta al ReplicaSet frontend.
|
||||
Para ello, obtén el yaml de uno de los Pods ejecutándose:
|
||||
```shell
|
||||
kubectl get pods frontend-9si5l -o yaml
|
||||
```
|
||||
|
||||
La salida será parecida a esta, donde la información sobre el ReplicaSet aparece en el campo ownerReferences de los metadatos:
|
||||
```shell
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
creationTimestamp: 2019-01-31T17:20:41Z
|
||||
generateName: frontend-
|
||||
labels:
|
||||
tier: frontend
|
||||
name: frontend-9si5l
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: extensions/v1beta1
|
||||
blockOwnerDeletion: true
|
||||
controller: true
|
||||
kind: ReplicaSet
|
||||
name: frontend
|
||||
uid: 892a2330-257c-11e9-aecd-025000000001
|
||||
...
|
||||
```
|
||||
|
||||
## Adquisiciones de Pods fuera de la plantilla
|
||||
|
||||
Aunque puedes crear Pods simples sin problemas, se recomienda encarecidamente asegurarse de que dichos Pods no tienen
|
||||
etiquetas que puedan coincidir con el selector de alguno de tus ReplicaSets.
|
||||
La razón de esta recomendación es que un ReplicaSet no se limita a poseer los Pods
|
||||
especificados en su plantilla -- sino que puede adquirir otros Pods como se explicó en secciones anteriores.
|
||||
|
||||
Toma el ejemplo anterior del ReplicaSet frontend, y los Pods especificados en el siguiente manifiesto:
|
||||
|
||||
{{< codenew file="pods/pod-rs.yaml" >}}
|
||||
|
||||
Como estos Pods no tienen un Controlador (o cualquier otro objeto) como referencia de propietario
|
||||
y como además su selector coincide con el del ReplicaSet frontend, este último los terminará adquiriendo de forma inmediata.
|
||||
|
||||
Supón que creas los Pods después de que el ReplicaSet frontend haya desplegado los suyos
|
||||
para satisfacer su requisito de cuenta de réplicas:
|
||||
|
||||
```shell
|
||||
kubectl apply -f http://k8s.io/examples/pods/pod-rs.yaml
|
||||
```
|
||||
|
||||
Los nuevos Pods serán adquiridos por el ReplicaSet, e inmediatamente terminados ya que
|
||||
el ReplicaSet estaría por encima del número deseado.
|
||||
|
||||
Obtener los Pods:
|
||||
```shell
|
||||
kubectl get Pods
|
||||
```
|
||||
|
||||
La salida muestra que los nuevos Pods se han terminado, o están en el proceso de terminarse:
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
frontend-9si5l 1/1 Running 0 1m
|
||||
frontend-dnjpy 1/1 Running 0 1m
|
||||
frontend-qhloh 1/1 Running 0 1m
|
||||
pod2 0/1 Terminating 0 4s
|
||||
```
|
||||
|
||||
Si creas primero los Pods:
|
||||
```shell
|
||||
kubectl apply -f http://k8s.io/examples/pods/pod-rs.yaml
|
||||
```
|
||||
|
||||
Y entonces creas el ReplicaSet:
|
||||
```shell
|
||||
kubectl apply -f http://k8s.io/examples/controllers/frontend.yaml
|
||||
```
|
||||
|
||||
Verás que el ReplicaSet ha adquirido dichos Pods y simplemente ha creado tantos nuevos
|
||||
como necesarios para cumplir con su especificación hasta que el número de
|
||||
sus nuevos Pods y los originales coincidan con la cuenta deseado. Al obtener los Pods:
|
||||
```shell
|
||||
kubectl get Pods
|
||||
```
|
||||
|
||||
Veremos su salida:
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
frontend-pxj4r 1/1 Running 0 5s
|
||||
pod1 1/1 Running 0 13s
|
||||
pod2 1/1 Running 0 13s
|
||||
```
|
||||
|
||||
De esta forma, un ReplicaSet puede poseer un conjunto no homogéneo de Pods
|
||||
|
||||
## Escribir un manifiesto de ReplicaSet
|
||||
|
||||
Al igual que con el esto de los objeto de la API de Kubernetes, un ReplicaSet necesita los campos
|
||||
`apiVersion`, `kind`, y `metadata`. Para los ReplicaSets, el tipo es siempre ReplicaSet.
|
||||
En la versión 1.9 de Kubernetes, la versión `apps/v1` de la API en un tipo ReplicaSet es la versión actual y está habilitada por defecto.
|
||||
La versión `apps/v1beta2` de la API se ha desaprobado.
|
||||
Consulta las primeras líneas del ejemplo `frontend.yaml` como guía.
|
||||
|
||||
Un ReplicaSet también necesita una [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 una [plantilla pod](/docs/concepts/workloads/Pods/pod-overview/#pod-templates) que es
|
||||
también necesita obligatoriamente tener etiquetas definidas. En nuestro ejemplo `frontend.yaml` teníamos una etiqueta: `tier: frontend`.
|
||||
Lleva cuidado de que no se entremezcle con los selectores de otros controladores, no sea que traten de adquirir este Pod.
|
||||
|
||||
Para el campo de [regla de reinicio](/docs/concepts/workloads/Pods/pod-lifecycle/#restart-policy) de la plantilla,
|
||||
`.spec.template.spec.restartPolicy`, el único valor permitido es `Always`, que es el valor predeterminado.
|
||||
|
||||
### Selector de Pod
|
||||
|
||||
El campo `.spec.selector` es un [selector de etiqueta](/docs/concepts/overview/working-with-objects/labels/).
|
||||
Como se explicó [anteriormente](#how-a-replicaset-works), estas son las etiquetas que se usan para
|
||||
identificar los Pods potenciales a adquirir. En nuestro ejemplo `frontend.yaml`, el selector era:
|
||||
```shell
|
||||
matchLabels:
|
||||
tier: frontend
|
||||
```
|
||||
|
||||
El el ReplicaSet, `.spec.template.metadata.labels` debe coincidir con `spec.selector`, o será
|
||||
rechazado por la API.
|
||||
|
||||
{{< note >}}
|
||||
Cuando 2 ReplicaSets especifican el mismo campo `.spec.selector`, pero los campos
|
||||
`.spec.template.metadata.labels` y `.spec.template.spec` diferentes, cada ReplicaSet
|
||||
ignora los Pods creados por el otro ReplicaSet.
|
||||
{{< /note >}}
|
||||
|
||||
### Réplicas
|
||||
|
||||
Puedes configurar cuántos Pods deberían ejecutarse de forma concurrente indicando el campo `.spec.replicas`.
|
||||
El ReplicaSet creará/eliminará sus Pods para alcanzar este número.
|
||||
|
||||
Si no indicas el valor del campo `.spec.replicas`, entonces por defecto se inicializa a 1.
|
||||
|
||||
## Trabajar con ReplicaSets
|
||||
|
||||
### Eliminar un ReplicaSet y sus Pods
|
||||
|
||||
Para eliminar un ReplicaSet y todos sus Pods, utiliza el comando [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete).
|
||||
El [Recolector de basura](/docs/concepts/workloads/controllers/garbage-collection/) eliminará automáticamente
|
||||
todos los Pods subordinados por defecto.
|
||||
|
||||
Cuando se usa la API REST o la librería `client-go`, se debe poner el valor de `propagationPolicy` a `Background` o
|
||||
`Foreground` en la opción -d.
|
||||
Por ejemplo:
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
|
||||
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
|
||||
> -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
### Eliminar sólo un ReplicaSet
|
||||
|
||||
Se puede eliminar un ReplicaSet sin afectar a ninguno de sus Pods usando el comando [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) con la opción `--cascade=false`.
|
||||
Cuando se usa la API REST o la librería `client-go`, se debe poner `propagationPolicy` a `Orphan`.
|
||||
Por ejemplo:
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
|
||||
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
|
||||
> -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
Una vez que se ha eliminado el original, se puede crear un nuevo ReplicaSet para sustituirlo.
|
||||
Mientras el viejo y el nuevo `.spec.selector` sean el mismo, el nuevo adoptará a los viejos Pods.
|
||||
Sin embargo, no se esforzará en conseguir que los Pods existentes coincidan con una plantilla pod nueva, diferente.
|
||||
Para actualizar dichos Pods a la nueva especificación de forma controlada,
|
||||
usa una [actualización en línea](#rolling-updates).
|
||||
|
||||
### Aislar Pods de un ReplicaSet
|
||||
|
||||
Es posible aislar Pods de un ReplicaSet cambiando sus etiquetas. Esta técnica puede usarse
|
||||
para eliminar Pods de un servicio para poder depurar, recuperar datos, etc. Los Pods
|
||||
que se eliminar de esta forma serán sustituidos de forma automática (siempre que el
|
||||
número de réplicas no haya cambiado).
|
||||
|
||||
### Escalar un ReplicaSet
|
||||
|
||||
Se puede aumentar o reducir fácilmente un ReplicaSet simplemente actualizando el campo `.spec.replicas`.
|
||||
El controlador del ReplicaSet se asegura de que el número deseado de Pods con un selector
|
||||
de etiquetas coincidente está disponible y operacional.
|
||||
|
||||
### ReplicaSet como blanco de un Horizontal Pod Autoscaler
|
||||
|
||||
Un ReplicaSet puede también ser el blanco de un
|
||||
[Horizontal Pod Autoscalers (HPA)](/docs/tasks/run-application/horizontal-pod-autoscale/). Esto es,
|
||||
un ReplicaSet puede auto-escalarse mediante un HPA. Aquí se muestra un ejemplo de HPA dirigido
|
||||
al ReplicaSet que creamos en el ejemplo anterior.
|
||||
|
||||
{{< codenew file="controllers/hpa-rs.yaml" >}}
|
||||
|
||||
Si guardas este manifiesto en un archivo `hpa-rs.yaml` y lo lanzas contra el clúster de Kubernetes,
|
||||
debería crear el HPA definido que auto-escala el ReplicaSet destino dependiendo del uso
|
||||
de CPU de los Pods replicados.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/hpa-rs.yaml
|
||||
```
|
||||
|
||||
Alternativamente, puedes usar el comando `kubectl autoscale` para conseguir el mismo objetivo
|
||||
(¡y mucho más fácil!)
|
||||
|
||||
```shell
|
||||
kubectl autoscale rs frontend --max=10
|
||||
```
|
||||
|
||||
## Alternativas al ReplicaSet
|
||||
|
||||
### Deployment (recomendado)
|
||||
|
||||
Un[`Deployment`](/docs/concepts/workloads/controllers/deployment/) es un objeto que puede poseer ReplicaSets
|
||||
y actualizar a estos y a sus Pods mediante actualizaciones en línea declarativas en el servidor.
|
||||
Aunque que los ReplicaSets puede usarse independientemente, hoy en día se usan principalmente a través de los Deployments
|
||||
como el mecanismo para orquestrar la creación, eliminación y actualización de los Pods.
|
||||
Cuando usas Deployments no tienes que preocuparte de gestionar los ReplicaSets que crean.
|
||||
Los Deployments poseen y gestionan sus ReplicaSets.
|
||||
Por tanto, se recomienda que se use Deployments cuando se quiera ReplicaSets.
|
||||
|
||||
### Pods simples
|
||||
|
||||
A diferencia del caso en que un usuario creaba Pods de forma directa, un ReplicaSet sustituye los Pods que se eliminan
|
||||
o se terminan por la razón que sea, como en el caso de un fallo de un nodo o
|
||||
una intervención disruptiva de mantenimiento, como una actualización de kernel.
|
||||
Por esta razón, se recomienda que se use un ReplicaSet incluso cuando la aplicación
|
||||
sólo necesita un único Pod. Entiéndelo de forma similar a un proceso supervisor,
|
||||
donde se supervisa múltiples Pods entre múltiples nodos en vez de procesos individuales
|
||||
en un único nodo. Un ReplicaSet delega los reinicios del contenedor local a algún agente
|
||||
del nodo (por ejemplo, Kubelet o Docker).
|
||||
|
||||
### Job
|
||||
|
||||
Usa un [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) en vez de un ReplicaSet para
|
||||
aquellos Pods que se esperan que terminen por ellos mismos (esto es, trabajos por lotes).
|
||||
|
||||
### DaemonSet
|
||||
|
||||
Usa un [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) en vez de un ReplicaSet para aquellos
|
||||
Pods que proporcionan funcionalidad a nivel de servidor, como monitorización de servidor o
|
||||
logging de servidor. Estos Pods tienen un ciclo de vida asociado al del servidor mismo:
|
||||
el Pod necesita ejecutarse en el servidor antes de que los otros Pods comiencen, y es seguro
|
||||
que terminen cuando el servidor esté listo para ser reiniciado/apagado.
|
||||
|
||||
### ReplicationController
|
||||
Los ReplicaSets son los sucesores de los [_ReplicationControllers_](/docs/concepts/workloads/controllers/replicationcontroller/).
|
||||
Los dos sirven al mismo propósito, y se comportan de forma similar, excepto porque un ReplicationController
|
||||
no soporta los requisitos del selector basado en conjunto, como se describe en la [guía de usuario de etiquetas](/docs/concepts/overview/working-with-objects/labels/#label-selectors).
|
||||
Por ello, se prefiere los ReplicaSets a los ReplicationControllers.
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,21 @@
|
|||
apiVersion: apps/v1
|
||||
kind: ReplicaSet
|
||||
metadata:
|
||||
name: frontend
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
spec:
|
||||
# modifica las réplicas según tu caso de uso
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
tier: frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
tier: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: php-redis
|
||||
image: gcr.io/google_samples/gb-frontend:v3
|
|
@ -0,0 +1,11 @@
|
|||
apiVersion: autoscaling/v1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: frontend-scaler
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
kind: ReplicaSet
|
||||
name: frontend
|
||||
minReplicas: 3
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 50
|
|
@ -0,0 +1,14 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: pi
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: pi
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
restartPolicy: Never
|
||||
backoffLimit: 4
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod1
|
||||
labels:
|
||||
tier: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: hello1
|
||||
image: gcr.io/google-samples/hello-app:2.0
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod2
|
||||
labels:
|
||||
tier: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: hello2
|
||||
image: gcr.io/google-samples/hello-app:1.0
|
Loading…
Reference in New Issue