1. Descripción general
Docker es una plataforma abierta para desarrollar, enviar y ejecutar aplicaciones. Permite separar las aplicaciones de la infraestructura y tratar a la infraestructura como una aplicación administrada. Docker ayuda a enviar, implementar y probar código más rápido y a acortar el ciclo entre su escritura y ejecución.
Para esto, combina las funciones de creación de contenedores de kernel con flujos de trabajo y herramientas que ayudan a implementar y administrar aplicaciones.
Los contenedores de Docker pueden usarse directamente en Kubernetes, lo que permite ejecutarlos de manera sencilla en Kubernetes Engine. Después de aprender los aspectos esenciales de Docker, contarás con las habilidades para empezar a desarrollar aplicaciones de Kubernetes y alojadas en contenedores.
Qué aprenderás
En este lab, aprenderás a realizar las siguientes tareas:
- Crea un Dockerfile para una aplicación de ejemplo
- Compila una imagen
- Ejecuta la imagen como un contenedor de manera local
- Cambia el comportamiento del contenedor
- Envía la imagen a Artifact Registry
Requisitos previos
Este es un lab de nivel introductorio. Parte de la suposición de que la experiencia en Docker y contenedores que tiene el alumno es escasa o nula. Contar con conocimientos de Cloud Shell y la línea de comandos es recomendable, pero no es obligatorio.
Configuración del entorno de autoaprendizaje
- Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.
- El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una string de caracteres que no se utiliza en las API de Google y se puede actualizar en cualquier momento.
- El ID del proyecto debe ser único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). Cloud Console genera automáticamente una string única, que, por lo general, no importa cuál sea. En la mayoría de los codelabs, debes hacer referencia al ID del proyecto (suele ser
PROJECT_ID
). Por lo tanto, si no te gusta, genera otro aleatorio o prueba con uno propio y comprueba si está disponible. Después de crear el proyecto, este ID se “congela” y no se puede cambiar. - Además, hay un tercer valor, el Número de proyecto, que usan algunas API. Obtén más información sobre estos tres valores en la documentación.
- A continuación, deberás habilitar la facturación en Cloud Console para usar las API o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Si quieres cerrar los recursos para no se te facture más allá de este instructivo, sigue las instrucciones de “limpieza” que se encuentran al final del codelab. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.
2. Aplicación de muestra
Se proporcionó una aplicación de ejemplo para facilitar este lab. En esta sección, recuperarás el código fuente y compilarás la aplicación en su forma nativa antes de pasar al proceso de creación de contenedores.
Código fuente
El código fuente de este lab está disponible en el repositorio GoogleCloudPlatform/container-developer-workshop, junto con la documentación de la aplicación de muestra.
Configurar Git
git config --global user.name ${USER}
git config --global user.email ${USER}@qwiklabs.net
Clona la aplicación de ejemplo Cloud Source Repository
gcloud source repos clone sample-app ${HOME}/sample-app &&
cd ${HOME}/sample-app &&
git checkout main
Salida
Cloning into '/home/student_03_49720296e995/sample-app'... remote: Finding sources: 100% (16/16) remote: Total 16 (delta 0), reused 16 (delta 0) Receiving objects: 100% (16/16), 47.23 KiB | 681.00 KiB/s, done. warning: remote HEAD refers to nonexistent ref, unable to checkout. Project [qwiklabs-gcp-02-4327c4e03d82] repository [sample-app] was cloned to [/home/student_03_49720296e995/sample-app]. Branch 'main' set up to track remote branch 'main' from 'origin'. Switched to a new branch 'main'
Compila la aplicación de ejemplo
cd ${HOME}/sample-app
./mvnw compile
Salida
[INFO] Scanning for projects... ... [INFO] Compiling 1 source file to /home/student_03_49720296e995/sample-app/target/classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 10.080 s [INFO] Finished at: 2022-02-23T17:14:30Z [INFO] ------------------------------------------------------------------------
Ejecuta la aplicación de ejemplo
cd ${HOME}/sample-app
./mvnw exec:java
Salida
[INFO] Scanning for projects... ... Listening at http://localhost:8080
Obtén una vista previa de la aplicación en ejecución
- Haz clic en el botón Vista previa en la Web de Cloud Shell
- Haz clic en Vista previa en el puerto 8080
Cuando finalices, haz lo siguiente:
- Presiona CTRL + C en Cloud Shell para detener la aplicación en ejecución.
3. Dockerfile
Aloja la aplicación en contenedores con un Dockerfile
Un método para empaquetar una aplicación en un contenedor es usar un Dockerfile. El Dockerfile es similar a una secuencia de comandos que le indica al daemon cómo ensamblar la imagen del contenedor. Consulta la documentación de referencia de Dockerfile) para obtener más información.
Crear un Dockerfile vacío en el repositorio de la aplicación de ejemplo
touch ${HOME}/sample-app/Dockerfile
Abre el Dockerfile en el editor que prefieras.
vi ${HOME}/sample-app/Dockerfile
Elige una imagen de inicio
Usar el método de Dockerfile para compilar un contenedor requiere conocimiento directo sobre la aplicación para ensamblar el contenedor. El primer paso para crear un Dockerfile es seleccionar una imagen que se utilizará como la base de tu imagen.Esta imagen debe ser una imagen superior o base que una fuente de confianza, como la empresa, mantiene y publica.
La instrucción FROM
inicializa una nueva etapa de compilación y establece la imagen base para los comandos secuenciales posteriores. Por lo tanto, la instrucción FROM
suele ser la primera instrucción en un Dockerfile y solo puede estar precedida por una instrucción ARG opcional para admitir variables.
Sintaxis: FROM <image>[:<tag> | @<digest>] [AS <name>]
El formato de una imagen es <image>:<tag>
o <image>@<digest>
. Si no se especifica una etiqueta o un resumen, el valor predeterminado es la etiqueta :latest
. El formato de <image>
varía según el registro que se usó para almacenar la imagen. Para Artifact Registry, el formato de <image>
es <region>-docker.pkg.dev/<project ID>/<repository name>/<image name>:<image tag>
.
Para este lab, usamos la imagen pública openjdk:11.0-jdk
. Agrega la siguiente línea a tu Dockerfile.
FROM openjdk:11.0-jdk
Configura el directorio de trabajo
La instrucción WORKDIR
configura el directorio de trabajo para cualquier instrucción secuencial que siga en el Dockerfile. Para obtener más información, consulta la sección WORKDIR de la documentación de referencia de Dockerfile.
Sintaxis: WORKDIR <path>
Para este lab, usaremos el directorio /app
como WORKDIR
. Agrega la siguiente línea al final del Dockerfile.
WORKDIR /app
Copia los archivos de la aplicación
La instrucción COPY
copia directorios o archivos de la ubicación <source>
en la ruta <destination>
del sistema de archivos de imágenes. Se pueden especificar varios recursos <source>
, y todos están relacionados con el contexto de compilación. El contexto de compilación se analizará con más detalle en la sección Compilación. Para obtener más información, consulta la sección COPIA de la documentación de referencia de Dockerfile.
Sintaxis: COPY <source>... <destination>
Para este lab, copiaremos todos los archivos del repositorio en el sistema de archivos de imágenes. Agregue la siguiente línea al final de su Dockerfile
COPY . /app
Compila la aplicación
La instrucción RUN
ejecuta comandos en una nueva capa de imagen sobre la imagen actual y confirma los resultados. La imagen confirmada resultante se usará para los pasos secuenciales en el Dockerfile. Para obtener más información, consulta la sección EJECUTAR de la documentación de referencia de Dockerfile.
Sintaxis: RUN <command>
En este lab, usaremos Maven para compilar la aplicación en un archivo JAR. Para ello, agregaremos la siguiente línea al final de tu Dockerfile
RUN ./mvnw compile assembly:single
Inicia la aplicación
La instrucción CMD
proporciona el comando predeterminado para un contenedor en ejecución. Solo puede haber una instrucción de CMD en un Dockerfile. Si se especifica más de un CMD, solo se aplicará el último CMD. Hay funciones más avanzadas disponibles con las instrucciones de CMD y ENTRYPOINT, pero eso no se aborda en este lab. Para obtener más información, consulta la sección CMD de la documentación de referencia de Dockerfile.
Sintaxis: CMD ["executable","param1","param2"]
Para este lab, ejecutamos el archivo JAR que compilamos. Agrega la siguiente línea al final de tu Dockerfile
CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]
Dockerfile final
El último Dockerfile se
FROM openjdk:11.0-jdk
WORKDIR /app
COPY . /app
RUN ./mvnw compile assembly:single
CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]
Confirma el Dockerfile de manera local
cd ${HOME}/sample-app
git add Dockerfile
git commit -m "Added Dockerfile"
4. Compilación
Ahora, compilaremos la imagen desde el Dockerfile con el comando docker build
. Este comando le indica al daemon de Docker que compile la imagen con las instrucciones de nuestro Dockerfile. Consulta la documentación de referencia de compilación de Docker para obtener más información.
Compila la imagen
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker build --tag sample-app:${IMAGE_TAG} .
Salida
Sending build context to Docker daemon 221.2kB Step 1/4 : FROM openjdk:11.0-jdk 11.0-jdk: Pulling from library/openjdk 0c6b8ff8c37e: Pull complete 412caad352a3: Pull complete e6d3e61f7a50: Pull complete 461bb1d8c517: Pull complete e442ee9d8dd9: Pull complete 542c9fe4a7ba: Pull complete 41de18d1833d: Pull complete Digest: sha256:d72b1b9e94e07278649d91c635e34737ae8f181c191b771bde6816f9bb4bd08a Status: Downloaded newer image for openjdk:11.0-jdk ---> 2924126f1829 Step 2/4 : WORKDIR /app ---> Running in ea037abb273d Removing intermediate container ea037abb273d ---> bd9b6d078082 Step 3/4 : COPY . /app ---> b9aec2b5de51 Step 4/4 : RUN ./mvnw compile jar:jar ---> Running in 3f5ff737b7fd [INFO] Scanning for projects... ... [INFO] Building jar: /app/target/sample-app-1.0.0.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 22.952 s [INFO] Finished at: 2022-02-23T18:09:08Z [INFO] ------------------------------------------------------------------------ Removing intermediate container 331443caebd3 ---> 152f65cc441e Step 5/5 : CMD ["java", "-jar", "/app/target/sample-app-1.0.0.jar"] ---> Running in 3d595a72231c Removing intermediate container 3d595a72231c ---> 0e40d7548cab Successfully built 0e40d7548cab Successfully tagged sample-app:aaa8895
5. Ejecutar
Después de compilar correctamente la imagen de contenedor, podemos ejecutar la aplicación y asegurarnos de que se comporte como se espera con el comando docker run. Este comando iniciará el contenedor en primer plano en el símbolo del sistema para pruebas o depuración. Consulta la documentación de referencia de la ejecución de Docker para obtener más información.
Ejecuta un contenedor con la imagen
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-p 8080:8080 \
sample-app:${IMAGE_TAG}
Salida
Listening at http://localhost:8080
Obtén una vista previa de la aplicación que se ejecuta en un contenedor
- Haz clic en el botón Vista previa en la Web de Cloud Shell
- Haz clic en Vista previa en el puerto 8080
- Presiona CTRL + c en Cloud Shell para detener los contenedores
Cambia el comportamiento de los contenedores
Cuando se ejecuta Docker Run, se usa la configuración predeterminada en el Dockerfile. Se pueden agregar instrucciones y parámetros adicionales para modificar este comportamiento.
Habilitar el registro de TRACE
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-p 8080:8080 \
sample-app:${IMAGE_TAG} \
java -Dorg.slf4j.simpleLogger.defaultLogLevel=trace -jar /app/target/sample-app-1.0.0-jar-with-dependencies.jar
Obtén una vista previa de la aplicación que se ejecuta en un contenedor
- Haz clic en el botón Vista previa en la Web de Cloud Shell
- Haz clic en Vista previa en el puerto 8080
- Cambia a la pestaña de Cloud Shell para ver el registro adicional
- Presiona CTRL + c en Cloud Shell para detener el contenedor
Cambiar puerto
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-e PORT=8081 \
-p 8081:8081 \
sample-app:${IMAGE_TAG}
Obtén una vista previa de la aplicación que se ejecuta en un contenedor
- Haz clic en el botón Vista previa en la Web de Cloud Shell
- Haz clic en Cambiar puerto.
- Ingresar 8081
- Haz clic en Cambiar y obtener vista previa.
- Presiona CTRL + c en Cloud Shell para detener el contenedor
6. Envío
Una vez que estamos seguros de que la imagen del contenedor se está ejecutando correctamente y queremos que este contenedor esté disponible para que se ejecute en otros entornos o que otros usuarios lo ejecuten, debemos enviar la imagen a un repositorio compartido. Esto debería ocurrir como parte de una canalización de compilación automatizada, pero en nuestro entorno de pruebas ya tenemos un repositorio configurado y podemos enviar la imagen de forma manual.
Envía la confirmación de Dockerfile al repositorio sample-app
cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
git push
Etiqueta la imagen para Artifact Registry
docker tag sample-app:${IMAGE_TAG} \
us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}
Configura tus credenciales para Artifact Registry
gcloud auth configure-docker us-central1-docker.pkg.dev
Cuando se te solicite Do you want to continue (Y/n)?
, responde y
y presiona Enter
Envía la imagen a Artifact Registry
docker push us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}
Salida
The push refers to repository [us-central1-docker.pkg.dev/qwiklabs-gcp-04-b47ced695a3c/apps/sample-app] 453b97f86449: Pushed e86791aa0382: Pushed d404c7ee0850: Pushed fe4f44af763d: Pushed 7c072cee6a29: Pushed 1e5fdc3d671c: Pushed 613ab28cf833: Pushed bed676ceab7a: Pushed 6398d5cccd2c: Pushed 0b0f2f2f5279: Pushed aaa8895: digest: sha256:459de00f86f159cc63f98687f7c9563fd65a2eb9bcc71c23dda3351baf13607a size: 2424
7. ¡Felicitaciones!
¡Felicitaciones! Completaste el codelab.
Temas abordados
- Crear un Dockerfile para una aplicación de muestra
- Compila una imagen
- Ejecutaste la imagen como un contenedor de manera local
- Cambio en el comportamiento del contenedor
- Se envió la imagen a Artifact Registry