diff --git a/content/es/docs/concepts/workloads/pods/init-containers.md b/content/es/docs/concepts/workloads/pods/init-containers.md new file mode 100644 index 0000000000..223d69214f --- /dev/null +++ b/content/es/docs/concepts/workloads/pods/init-containers.md @@ -0,0 +1,341 @@ +--- +title: Contenedores de Inicialización +content_type: concept +weight: 40 +--- + + +Esta página proporciona una descripción general de los contenedores de inicialización: contenedores especializados que se ejecutan +antes de los contenedores de aplicación en un {{< glossary_tooltip text="Pod" term_id="pod" >}}. +Los contenedores de inicialización pueden contener utilidades o scripts de instalación no presentes en una imagen de aplicación. + +Tú puedes especificar contenedores de inicialización en la especificación del Pod junto con el array `containers` +(el cual describe los contenedores de aplicación). + + +## Entendiendo los contenedores de inicialización + +Un {{< glossary_tooltip text="Pod" term_id="pod" >}} puede tener múltiples contenedores +ejecutando applicaciones dentro de él, pero también puede tener uno o más contenedores de inicialización +que se ejecutan antes de que se inicien los contenedores de aplicación. + +Los contenedores de inicialización son exactamente iguales a los contenedores regulares excepto por: + +* Los contenedores de inicialización siempre se ejecutan hasta su finalización. +* Cada contenedor de inicialiación debe completarse correctamente antes de que comience el siguiente. + +Si el contenedor de inicialización de un Pod falla, kubelet reinicia repetidamente ese contenedor de inicialización hasta que tenga éxito. +Sin embargo, si el Pod tiene una `restartPolicy` de `Never` y un contenedor de inicialización falla durante el inicio de ese Pod, Kubernetes trata en general al Pod como fallido. + +Para especificar un contenedor de inicialización para un Pod, agrega el campo `initContainers` en +la [especificación del Pod](/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec), +como un array de elementos `container` (similar al campo `containers` de aplicación y su contenido). +Consulta [Container](/docs/reference/kubernetes-api/workload-resources/pod-v1/#Container) en la +referencia de API para más detalles. + +El estado de los contenedores de inicialización se devuelve en el campo `.status.initContainerStatuses` +como un array de los estados del contenedor (similar al campo `.status.containerStatuses`). + +### Diferencias con los contenedores regulares + +Los contenedores de inicialización admiten todos los campos y características de los contenedores de aplicaciones, +incluidos los límites de recursos, los volúmenes y la configuración de seguridad. Sin embargo, las +solicitudes de recursos y los límites para un contenedor de inicialización se manejan de manera diferente, +como se documenta en [Recursos](#resources). + +Además, los contenedores de inicialización no admiten `lifecycle`, `livenessProbe`, `readinessProbe` o +`startupProbe` porque deben de ejecutarse hasta su finalización antes de que el Pod pueda estar listo. + +Si especificas varios contenedores de inicialización para un Pod, kubelet ejecuta cada contenedor +de inicialización secuencialmente. Cada contenedor de inicialización debe tener éxito antes de que se pueda ejecutar el siguiente. +Cuando todos los contenedores de inicialización se hayan ejecutado hasta su finalización, kubelet inicializa +los contenedores de aplicación para el Pod y los ejecuta como de costumbre. + +### Usando contenedores de inicialización + +Dado que los contenedores de inicialización tienen imágenes separadas de los contenedores de aplicaciones, estos +tienen algunas ventajas sobre el código relacionado de inicio: + +* Los contenedores de inicialización pueden contener utilidades o código personalizado para la configuración que no están presentes en una + imagen de aplicación. Por ejemplo, no hay necesidad de hacer una imagen `FROM` de otra imagen solo para usar una herramienta como + `sed`, `awk`, `python` o `dig` durante la instalación. +* Los roles de constructor e implementador de imágenes de aplicación pueden funcionar de forma independiente sin + la necesidad de construir conjuntamente una sola imagen de aplicación. +* Los contenedores de inicialización pueden ejecutarse con una vista diferente al sistema de archivos que los contenedores de aplicaciones en + el mismo Pod. En consecuencia, se les puede dar acceso a + {{}} a los que los contenedores de aplicaciones no pueden acceder. +* Debido a que los contenedores de inicialización se ejecutan hasta su finalización antes de que se inicien los contenedores de aplicaciones, los contenedores de inicialización ofrecen + un mecanismo para bloquear o retrasar el inicio del contenedor de aplicación hasta que se cumplan una serie de condiciones previas. Una vez + que las condiciones previas se cumplen, todos los contenedores de aplicaciones de un Pod pueden iniciarse en paralelo. +* Los contenedores de inicialización pueden ejecutar de forma segura utilidades o código personalizado que de otro modo harían a una imagen de aplicación + de contenedor menos segura. Si mantiene separadas herramientas innecesarias, puede limitar la superficie de ataque + a la imagen del contenedor de aplicación. + +### Ejemplos + +A continuación, se muestran algunas ideas sobre cómo utilizar los contenedores de inicialización: + +* Esperar a que se cree un {{< glossary_tooltip text="Service" term_id="service">}} + usando un comando de una línea de shell: + + ```shell + for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1 + ``` + +* Registrar este Pod con un servidor remoto desde la downward API con un comando como: + + ```shell + curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$()&ip=$()' + ``` + +* Esperar algo de tiempo antes de iniciar el contenedor de aplicación con un comando como: + + ```shell + sleep 60 + ``` + +* Clonar un repositorio de Git en un {{< glossary_tooltip text="Volume" term_id="volume" >}} + +* Colocar valores en un archivo de configuración y ejecutar una herramienta de plantilla para generar + dinámicamente un archivo de configuración para el contenedor de aplicación principal. Por ejemplo, + colocar el valor `POD_IP` en una configuración y generar el archivo de configuración + de la aplicación principal usando Jinja. + +#### Contenedores de inicialización en uso + +Este ejemplo define un simple Pod que tiene dos contenedores de inicialización. +El primero espera por `myservice` y el segundo espera por `mydb`. Una vez que ambos +contenedores de inicialización se completen, el Pod ejecuta el contenedor de aplicación desde su sección `spec`. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: myapp-pod + labels: + app: myapp +spec: + containers: + - name: myapp-container + image: busybox:1.28 + command: ['sh', '-c', 'echo ¡La aplicación se está ejecutando! && sleep 3600'] + initContainers: + - name: init-myservice + image: busybox:1.28 + command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo esperando a myservice; sleep 2; done"] + - name: init-mydb + image: busybox:1.28 + command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo esperando a mydb; sleep 2; done"] +``` + +Puedes iniciar este Pod ejecutando: + +```shell +kubectl apply -f myapp.yaml +``` + +El resultado es similar a esto: + +```shell +pod/myapp-pod created +``` + +Y verificar su estado con: + +```shell +kubectl get -f myapp.yaml +``` + +El resultado es similar a esto: + +```shell +NAME READY STATUS RESTARTS AGE +myapp-pod 0/1 Init:0/2 0 6m +``` + +o para más detalles: + +```shell +kubectl describe -f myapp.yaml +``` + +El resultado es similar a esto: + +```shell +Name: myapp-pod +Namespace: default +[...] +Labels: app=myapp +Status: Pending +[...] +Init Containers: + init-myservice: +[...] + State: Running +[...] + init-mydb: +[...] + State: Waiting + Reason: PodInitializing + Ready: False +[...] +Containers: + myapp-container: +[...] + State: Waiting + Reason: PodInitializing + Ready: False +[...] +Events: + FirstSeen LastSeen Count From SubObjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 16s 16s 1 {default-scheduler } Normal Scheduled Successfully assigned myapp-pod to 172.17.4.201 + 16s 16s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulling pulling image "busybox" + 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox" + 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined] + 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634 +``` + +Para ver los logs de los contenedores de inicialización en este Pod ejecuta: + +```shell +kubectl logs myapp-pod -c init-myservice # Inspecciona el primer contenedor de inicialización +kubectl logs myapp-pod -c init-mydb # Inspecciona el segundo contenedor de inicialización +``` + +En este punto, estos contenedores de inicialización estarán esperando para descubrir los Servicios denominados +`mydb` y `myservice`. + +Aquí hay una configuración que puedes usar para que aparezcan esos Servicios: + +```yaml +--- +apiVersion: v1 +kind: Service +metadata: + name: myservice +spec: + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +--- +apiVersion: v1 +kind: Service +metadata: + name: mydb +spec: + ports: + - protocol: TCP + port: 80 + targetPort: 9377 +``` + +Para crear los servicios de `mydb` y `myservice`: + +```shell +kubectl apply -f services.yaml +``` + +El resultado es similar a esto: + +```shell +service/myservice created +service/mydb created +``` + +Luego verás que esos contenedores de inicialización se completan y que el Pod `myapp-pod` +pasa al estado `Running`: + +```shell +kubectl get -f myapp.yaml +``` + +El resultado es similar a esto: + +```shell +NAME READY STATUS RESTARTS AGE +myapp-pod 1/1 Running 0 9m +``` + +Este sencillo ejemplo debería servirte de inspiración para crear tus propios +contenedores de inicialización. [What's next](#what-s-next) contiene un enlace a un ejemplo más detallado. + +## Comportamiento detallado + +Durante el inicio del Pod, kubelet retrasa la ejecución de contenedores de inicialización hasta que la red +y el almacenamiento estén listos. Después, kubelet ejecuta los contenedores de inicialización del Pod en el orden que +aparecen en la especificación del Pod. + +Cada contenedor de inicialización debe salir correctamente antes de que +comience el siguiente contenedor. Si un contenedor falla en iniciar debido al tiempo de ejecución o +sale con una falla, se vuelve a intentar de acuerdo con el `restartPolicy` del Pod. Sin embargo, +si el `restartPolicy` del Pod se establece en `Always`, los contenedores de inicialización usan +el `restartPolicy` como `OnFailure`. + +Un Pod no puede estar `Ready` sino hasta que todos los contenedores de inicialización hayan tenido éxito. Los puertos en un +contenedor de inicialización no se agregan a un Servicio. Un Pod que se está inicializando, +está en el estado de `Pending`, pero debe tener una condición `Initialized` configurada como falsa. + +Si el Pod [se reinicia](#pod-restart-reasons) o es reiniciado, todos los contenedores de inicialización +deben ejecutarse de nuevo. + +Los cambios en la especificación del contenedor de inicialización se limitan al campo de la imagen del contenedor. +Alterar un campo de la imagen del contenedor de inicialización equivale a reiniciar el Pod. + +Debido a que los contenedores de inicialización se pueden reiniciar, reintentar o volverse a ejecutar, el código del contenedor de inicialización +debe ser idempotente. En particular, el código que escribe en archivos en `EmptyDirs` +debe estar preparado para la posibilidad de que ya exista un archivo de salida. + +Los contenedores de inicialización tienen todos los campos de un contenedor de aplicaciones. Sin embargo, Kubernetes +prohíbe el uso de `readinessProbe` porque los contenedores de inicialización no pueden +definir el `readiness` distinto de la finalización. Esto se aplica durante la validación. + +Usa `activeDeadlineSeconds` en el Pod para prevenir que los contenedores de inicialización fallen por siempre. +La fecha límite incluye contenedores de inicialización. +Sin embargo, se recomienda utilizar `activeDeadlineSeconds` si el usuario implementa su aplicación +como un `Job` porque `activeDeadlineSeconds` tiene un efecto incluso después de que `initContainer` finaliza. +El Pod que ya se está ejecutando correctamente sería eliminado por `activeDeadlineSeconds` si lo estableces. + +El nombre de cada aplicación y contenedor de inicialización en un Pod debe ser único; un +error de validación es arrojado para cualquier contenedor que comparta un nombre con otro. + +### Recursos + +Dado el orden y la ejecución de los contenedores de inicialización, las siguientes reglas +para el uso de recursos se aplican: + +* La más alta de cualquier solicitud particular de recurso o límite definido en todos los contenedores + de inicialización es la *solicitud/límite de inicialización efectiva*. Si algún recurso no tiene un + límite de recursos especificado éste se considera como el límite más alto. +* La *solicitud/límite efectiva* para un recurso es la más alta entre: + * la suma de todas las solicitudes/límites de los contenedores de aplicación, y + * la solicitud/límite de inicialización efectiva para un recurso +* La planificación es hecha con base en las solicitudes/límites efectivos, lo que significa + que los contenedores de inicialización pueden reservar recursos para la inicialización que no se utilizan + durante la vida del Pod. +* El nivel de `QoS` (calidad de servicio) del *nivel de `QoS` efectivo* del Pod es el + nivel de `QoS` tanto para los contenedores de inicialización como para los contenedores de aplicación. + +La cuota y los límites son aplicados con base en la solicitud y límite efectivos de Pod. + +Los grupos de control de nivel de Pod (cgroups) se basan en la solicitud y el límite de Pod efectivos, al igual que el scheduler. + +### Razones de reinicio del Pod + +Un Pod puede reiniciarse, provocando la re-ejecución de los contenedores de inicialización por las siguientes razones: + +* Se reinicia el contenedor de infraestructura del Pod. Esto es poco común y debería hacerlo alguien con acceso de root a los nodos. +* Todos los contenedores en un Pod son terminados mientras `restartPolicy` esté configurado en `Always`, + forzando un reinicio y el registro de finalización del contenedor de inicialización se ha perdido debido a + la recolección de basura. + +El Pod no se reiniciará cuando se cambie la imagen del contenedor de inicialización o cuando +se pierda el registro de finalización del contenedor de inicialización debido a la recolección de basura. Esto +se aplica a Kubernetes v1.20 y posteriores. Si estás utilizando una versión anterior de +Kubernetes, consulta la documentación de la versión que estás utilizando. + +## {{% heading "whatsnext" %}} + +* Lee acerca sobre [creando un Pod que tiene un contenedor de inicialización](/docs/tasks/configure-pod-container/configure-pod-initialization/#create-a-pod-that-has-an-init-container) +* Aprende cómo [depurar contenedores de inicialización](/docs/tasks/debug-application-cluster/debug-init-containers/)