StudyToCert

CKAD / Lecciones · English

Certified Kubernetes Application Developer CKAD (Kubernetes v1.35 curriculum)

Escribir Dockerfiles: imágenes base, capas, builds multietapa, ENTRYPOINT vs CMD

Una imagen de contenedor es un sistema de archivos empaquetado más metadatos que indican cómo iniciar tu aplicación. Un Dockerfile es la receta para construirla: un archivo de texto con instrucciones que el builder ejecuta de arriba hacia abajo. El examen CKAD espera que sepas leer, corregir y escribir Dockerfiles cortos, así que necesitas saber qué hace cada instrucción común y cómo se almacena el resultado.

Todo Dockerfile parte de una imagen base con FROM, por ejemplo FROM python:3.12-slim o FROM alpine. La base aporta los archivos del sistema operativo y, a menudo, un runtime de lenguaje. Las bases más pequeñas, como las imágenes slim, alpine o distroless, implican descargas más rápidas y menos paquetes que podrían contener vulnerabilidades. Después de FROM normalmente usas WORKDIR para fijar el directorio de trabajo, COPY para traer los archivos fuente, RUN para ejecutar comandos de build como instalar dependencias, ENV para definir variables de entorno, EXPOSE para documentar un puerto de escucha y USER para dejar de ejecutar como root.

Las instrucciones que modifican el sistema de archivos (principalmente RUN, COPY y ADD) crean cada una una nueva capa de solo lectura. Las capas se guardan en caché: si una instrucción y todo lo anterior no han cambiado, el builder reutiliza la capa en caché en lugar de ejecutarla de nuevo. Por eso copias el manifiesto de dependencias (como requirements.txt o package.json) e instalas las dependencias antes de copiar el resto del código fuente. Así, editar un archivo fuente solo invalida las capas posteriores y los rebuilds son rápidos. Borrar un archivo en una capa posterior no reduce el tamaño de la imagen, porque la capa anterior todavía lo contiene.

Un build multietapa usa más de un FROM en el mismo archivo. La primera etapa tiene compiladores y herramientas de build; la etapa final parte de una imagen de runtime pequeña y copia solo el artefacto terminado con COPY --from=build. Las herramientas de build nunca llegan a la imagen que distribuyes, lo que la hace más pequeña y reduce su superficie de ataque.

FROM golang:1.22 AS build
WORKDIR /src
COPY go.mod ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app

FROM alpine
COPY --from=build /app /app
USER 1000
ENTRYPOINT ["/app"]
CMD ["--port", "8080"]

ENTRYPOINT y CMD juntos definen el comando de inicio. ENTRYPOINT es el ejecutable que siempre corre; CMD aporta argumentos por defecto que son fáciles de sobrescribir. Cuando ambos están presentes, el contenedor ejecuta ENTRYPOINT seguido de CMD, así que el ejemplo anterior ejecuta /app --port 8080. Si ejecutas la imagen con argumentos adicionales, estos reemplazan a CMD pero mantienen ENTRYPOINT. Si solo está definido CMD, es el comando completo y cualquier argumento que pases lo reemplaza por completo.

Prefiere la forma exec, un arreglo JSON como ["/app"], en lugar de la forma shell ENTRYPOINT /app. La forma exec ejecuta tu programa directamente como proceso 1, así que recibe señales como SIGTERM cuando Kubernetes detiene el Pod. La forma shell lo envuelve en /bin/sh -c, y el shell puede no reenviar las señales, lo que provoca apagados lentos y forzados.

Términos clave

Base image (imagen base)
La imagen indicada en FROM que aporta el sistema de archivos inicial y el runtime para tu build.
Layer (capa)
Un cambio de sistema de archivos de solo lectura y en caché, producido por una instrucción como RUN o COPY.
Multi-stage build (build multietapa)
Un Dockerfile con varias etapas FROM en el que solo se copian artefactos seleccionados a la imagen final.
ENTRYPOINT
El ejecutable fijo que el contenedor ejecuta al iniciar.
CMD
Argumentos por defecto (o un comando por defecto si no hay ENTRYPOINT) que se reemplazan con los argumentos dados en tiempo de ejecución.
Ejemplo real

La imagen de Python de un equipo tardaba cuatro minutos en reconstruirse tras cada cambio de código. Movieron COPY requirements.txt . y RUN pip install -r requirements.txt por encima de COPY . ., de modo que la capa de dependencias quedó en caché y los rebuilds bajaron a segundos. Pasar a un build multietapa también redujo el tamaño de la imagen final a menos de la mitad.

Consejo para el examen: Recuerda la regla de combinación: ENTRYPOINT más CMD se ejecutan juntos, y los argumentos en tiempo de ejecución reemplazan solo a CMD. Las preguntas suelen pedir qué comando ejecuta realmente un contenedor.

Comprueba lo que sabes

¿Por qué deberías copiar el archivo de dependencias e instalar los paquetes antes de copiar el resto del código fuente?

Porque las capas se guardan en caché en orden; así, los cambios de código solo invalidan las capas posteriores y la lenta instalación de dependencias se reutiliza desde la caché.

Una imagen tiene ENTRYPOINT ["ping"] y CMD ["localhost"]. ¿Qué se ejecuta si la inicias con el argumento example.com?

ping example.com, porque los argumentos en tiempo de ejecución reemplazan a CMD mientras ENTRYPOINT se mantiene.

¿Qué logra un build multietapa?

Mantiene las herramientas de build y los archivos intermedios fuera de la imagen final, haciéndola más pequeña y reduciendo la superficie de ataque.

Estudia CKAD gratis
Plan semana a semana con lecciones, cuestionarios, simulaciones de examen y práctica, en español.
Abrir el plan de estudio