Cómo usar el comando docker service create para desplegar y gestionar servicios

DockerDockerBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, adquirirá experiencia práctica utilizando el comando docker service create para desplegar y gestionar servicios dentro de un clúster (swarm) de Docker. Aprenderá cómo crear e inspeccionar diferentes tipos de servicios, incluyendo servicios replicados simples para alta disponibilidad y escalabilidad, y servicios globales que se ejecutan en cada nodo.

Además, explorará configuraciones avanzadas de servicios, como la implementación de políticas de actualización gradual (rolling update) para desplegar sin interrupciones, el uso de montajes de enlace (bind mounts) y variables de entorno para la persistencia de datos y la configuración, y la aplicación de restricciones y preferencias de ubicación para controlar dónde se ejecutan las tareas de su servicio dentro del clúster. Al completar estos pasos, desarrollará una comprensión sólida de cómo gestionar eficazmente aplicaciones contenerizadas en un entorno de clúster de Docker.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ls("List Containers") docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/ContainerOperationsGroup -.-> docker/create("Create Container") docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") subgraph Lab Skills docker/run -.-> lab-555224{{"Cómo usar el comando docker service create para desplegar y gestionar servicios"}} docker/ls -.-> lab-555224{{"Cómo usar el comando docker service create para desplegar y gestionar servicios"}} docker/ps -.-> lab-555224{{"Cómo usar el comando docker service create para desplegar y gestionar servicios"}} docker/exec -.-> lab-555224{{"Cómo usar el comando docker service create para desplegar y gestionar servicios"}} docker/inspect -.-> lab-555224{{"Cómo usar el comando docker service create para desplegar y gestionar servicios"}} docker/create -.-> lab-555224{{"Cómo usar el comando docker service create para desplegar y gestionar servicios"}} docker/pull -.-> lab-555224{{"Cómo usar el comando docker service create para desplegar y gestionar servicios"}} end

Crear un servicio replicado simple

En este paso, aprenderá cómo crear un servicio replicado simple en un clúster (swarm) de Docker. Un servicio replicado es un servicio que ejecuta múltiples tareas idénticas en todo el clúster. Esto proporciona alta disponibilidad y escalabilidad.

Primero, asegúrese de que Docker esté en ejecución y de que se encuentre en el directorio correcto.

docker version
pwd

Debería ver una salida que indique la versión de Docker y su directorio actual como /home/labex/project.

Antes de crear un servicio, necesitamos descargar la imagen de Docker necesaria. Utilizaremos la imagen nginx para este ejemplo.

docker pull nginx:latest

Este comando descarga la última versión de la imagen nginx desde Docker Hub.

Ahora, creemos un servicio replicado simple llamado my-nginx-service con 3 réplicas.

docker service create --name my-nginx-service --replicas 3 nginx:latest

Este comando crea un nuevo servicio llamado my-nginx-service utilizando la imagen nginx:latest y establece el número de réplicas deseadas en 3. Luego, el clúster de Docker distribuirá estas 3 tareas entre los nodos disponibles en el clúster.

Para verificar el estado del servicio y sus tareas, puede utilizar los comandos docker service ls y docker service ps.

docker service ls
docker service ps my-nginx-service

El comando docker service ls enumera todos los servicios que se ejecutan en el clúster, mostrando su ID, nombre, modo, réplicas e imagen. El comando docker service ps my-nginx-service muestra las tareas asociadas con el my-nginx-service, incluyendo su estado (por ejemplo, En ejecución, Apagado), el estado deseado y el nodo en el que se están ejecutando. Debería ver 3 tareas en estado "En ejecución".

Crear un servicio global e inspeccionar sus tareas

En este paso, aprenderá cómo crear un servicio global en un clúster (swarm) de Docker. A diferencia de los servicios replicados, que ejecutan un número especificado de tareas, un servicio global ejecuta exactamente una tarea en cada nodo del clúster que cumpla con las restricciones del servicio. Esto es útil para servicios como agentes de monitoreo o recolectores de registros que necesitan ejecutarse en cada nodo.

Utilizaremos la imagen busybox para este ejemplo. Primero, descarguemos la imagen.

docker pull busybox:latest

Este comando descarga la última versión de la imagen busybox.

Ahora, creemos un servicio global llamado my-global-service.

docker service create --name my-global-service --mode global busybox:latest sleep infinity

Este comando crea un nuevo servicio llamado my-global-service utilizando la imagen busybox:latest. La opción --mode global especifica que este es un servicio global. El comando sleep infinity se utiliza para mantener el contenedor en ejecución indefinidamente.

Para inspeccionar las tareas del servicio global, puede utilizar el comando docker service ps.

docker service ps my-global-service

Este comando mostrará las tareas asociadas con my-global-service. Dado que este es un servicio global, debería ver una tarea en ejecución para cada nodo en su clúster. En este entorno de Lab, probablemente verá solo una tarea ya que solo hay un nodo. La salida mostrará el estado de la tarea, el estado deseado y el nodo en el que se está ejecutando.

También puede inspeccionar la configuración del servicio utilizando el comando docker service inspect.

docker service inspect my-global-service

Este comando proporciona información detallada sobre el servicio, incluyendo su modo, réplicas (que será 0 para un servicio global en la lista de servicios, pero docker service ps mostrará tareas por nodo) y otros detalles de configuración.

Crear un servicio con réplicas y una política de actualización gradual

En este paso, aprenderá cómo crear un servicio replicado y configurar su política de actualización gradual. Las actualizaciones graduales le permiten actualizar su servicio a una nueva versión sin tiempo de inactividad reemplazando gradualmente las tareas con la nueva versión.

Seguiremos utilizando la imagen nginx. Creemos un servicio replicado llamado my-nginx-update-service con 5 réplicas y una política de actualización gradual.

docker service create \
  --name my-nginx-update-service \
  --replicas 5 \
  --update-delay 10s \
  --update-parallelism 2 \
  nginx:latest

Este comando crea un servicio con las siguientes configuraciones:

  • --name my-nginx-update-service: Establece el nombre del servicio.
  • --replicas 5: Establece el número deseado de réplicas en 5.
  • --update-delay 10s: Establece el retraso entre la actualización de cada grupo de tareas en 10 segundos.
  • --update-parallelism 2: Establece el número de tareas a actualizar simultáneamente en 2.

Estos parámetros de actualización definen cómo se actualizará el servicio cuando implemente una nueva versión de la imagen. Docker Swarm actualizará 2 tareas a la vez, esperando 10 segundos antes de actualizar el siguiente lote.

Puede verificar el estado del servicio y sus tareas utilizando los comandos docker service ls y docker service ps.

docker service ls
docker service ps my-nginx-update-service

Debería ver my-nginx-update-service en la lista con 5/5 réplicas y las tareas en estado "En ejecución".

Ahora, simulemos una actualización cambiando la imagen a una versión diferente. Utilizaremos la imagen nginx:1.21. Primero, descarguemos la imagen.

docker pull nginx:1.21

Ahora, actualicemos el servicio para que utilice la imagen nginx:1.21.

docker service update --image nginx:1.21 my-nginx-update-service

Este comando inicia una actualización gradual. Docker Swarm comenzará a reemplazar las tareas de nginx:latest con tareas de nginx:1.21 de acuerdo con la configuración de --update-parallelism y --update-delay que configuró anteriormente.

Puede observar el proceso de actualización gradual ejecutando repetidamente docker service ps my-nginx-update-service.

docker service ps my-nginx-update-service

Verá cómo las tareas pasan de "En ejecución" con la imagen antigua a "Apagado" y luego nuevas tareas se inician con la nueva imagen y entran en el estado "En ejecución". La actualización se realizará en lotes de 2 tareas con un retraso de 10 segundos entre lotes.

Crear un servicio con montajes de enlace (bind mounts) y variables de entorno

En este paso, aprenderá cómo crear un servicio que utiliza montajes de enlace (bind mounts) para persistir datos y variables de entorno para configurar la aplicación dentro del contenedor. Los montajes de enlace permiten montar un archivo o directorio desde la máquina host en un contenedor, lo que hace que los datos sean accesibles para el contenedor y persistentes incluso si el contenedor se elimina. Las variables de entorno son una forma común de pasar información de configuración a las aplicaciones.

Primero, creemos un directorio en la máquina host que montaremos en el contenedor.

mkdir -p ~/project/html

Este comando crea un directorio llamado html dentro de su directorio ~/project.

Ahora, creemos un archivo HTML simple dentro de este directorio.

echo "<h1>Hello from Bind Mount!</h1>" > ~/project/html/index.html

Este comando crea un archivo llamado index.html en el directorio ~/project/html con el contenido "

Hello from Bind Mount!

".

Volveremos a utilizar la imagen nginx. Creemos un servicio replicado llamado my-nginx-volume-service con 1 réplica, montando el directorio ~/project/html en el directorio raíz web predeterminado de Nginx dentro del contenedor (/usr/share/nginx/html) y estableciendo una variable de entorno.

docker service create \
  --name my-nginx-volume-service \
  --replicas 1 \
  --publish published=8080,target=80 \
  --mount type=bind,source=/home/labex/project/html,target=/usr/share/nginx/html \
  --env MY_VARIABLE=hello \
  nginx:latest

Desglosemos las nuevas opciones:

  • --publish published=8080,target=80: Esto mapea el puerto 8080 en la máquina host al puerto 80 dentro del contenedor, lo que le permite acceder al servidor web Nginx desde su máquina host.
  • --mount type=bind,source=/home/labex/project/html,target=/usr/share/nginx/html: Esto crea un montaje de enlace. type=bind especifica el tipo de montaje. source=/home/labex/project/html es la ruta en la máquina host. target=/usr/share/nginx/html es la ruta dentro del contenedor donde se montará el directorio de la máquina host.
  • --env MY_VARIABLE=hello: Esto establece una variable de entorno llamada MY_VARIABLE con el valor hello dentro del contenedor.

Verifique el estado del servicio y las tareas:

docker service ls
docker service ps my-nginx-volume-service

Espere a que la tarea esté en estado "En ejecución".

Ahora, puede acceder al servidor web Nginx que se ejecuta en el contenedor visitando http://localhost:8080 en un navegador web o utilizando curl.

curl http://localhost:8080

Debería ver el contenido del archivo index.html que creó: <h1>Hello from Bind Mount!</h1>. Esto confirma que el montaje de enlace está funcionando correctamente.

Para verificar la variable de entorno, puede ejecutar un comando dentro del contenedor en ejecución. Primero, encuentre el ID de la tarea del servicio en ejecución.

docker service ps my-nginx-volume-service

Anote el ID de la tarea de la salida. Luego, use docker exec para ejecutar un comando dentro del contenedor. Reemplace <task_id> con el ID real de la tarea.

docker exec < task_id > env | grep MY_VARIABLE

Este comando ejecuta el comando env dentro del contenedor asociado con el ID de la tarea y canaliza la salida a grep MY_VARIABLE para encontrar la variable de entorno. Debería ver MY_VARIABLE=hello en la salida.

Crear un servicio con restricciones y preferencias de ubicación

En este paso, aprenderá cómo utilizar restricciones y preferencias de ubicación para controlar dónde se despliegan las tareas de su servicio dentro de Docker Swarm. Las restricciones de ubicación son requisitos estrictos que un nodo debe cumplir para que se programe una tarea en él. Las preferencias de ubicación son requisitos flexibles que influyen en la programación, pero no impiden que se programe una tarea si ningún nodo cumple con la preferencia.

Primero, inspeccionemos el nodo actual para ver sus etiquetas (labels). Las etiquetas son pares clave-valor que se pueden adjuntar a los nodos para proporcionar metadatos.

docker node inspect self --format '{{ .Spec.Labels }}'

Este comando inspecciona el nodo actual (identificado por self) y formatea la salida para mostrar sus etiquetas. Por defecto, es posible que no haya ninguna etiqueta personalizada.

Agreguemos una etiqueta al nodo actual. Agregaremos la etiqueta node_type=app.

docker node update --label-add node_type=app self

Este comando actualiza el nodo actual y agrega la etiqueta node_type=app.

Ahora, verifiquemos que se haya agregado la etiqueta.

docker node inspect self --format '{{ .Spec.Labels }}'

Debería ver map[node_type:app] en la salida, lo que indica que la etiqueta se ha agregado correctamente.

Ahora, creemos un servicio replicado llamado my-constrained-service con una restricción de ubicación que requiere que el nodo tenga la etiqueta node_type=app. Utilizaremos la imagen nginx.

docker service create \
  --name my-constrained-service \
  --replicas 1 \
  --constraint 'node.labels.node_type == app' \
  nginx:latest

Este comando crea un servicio con una restricción. --constraint 'node.labels.node_type == app' especifica que las tareas de este servicio solo se pueden programar en nodos donde la etiqueta node_type sea igual a app. Dado que agregamos esta etiqueta al nodo actual, la tarea debería programarse aquí.

Verifique el estado del servicio y las tareas:

docker service ls
docker service ps my-constrained-service

Debería ver my-constrained-service en la lista y su tarea en ejecución en el nodo actual.

Ahora, creemos otro servicio con una preferencia de ubicación. Las preferencias de ubicación se utilizan para guiar al programador, pero no se aplican estrictamente. Utilizaremos la imagen busybox y preferiremos nodos con la etiqueta node_type=database. Dado que nuestro nodo actual no tiene esta etiqueta, la tarea todavía se programará en el nodo actual, pero si hubiera otros nodos con esa etiqueta, el programador los preferiría.

Primero, descarguemos la imagen busybox.

docker pull busybox:latest

Ahora, creemos el servicio con una preferencia de ubicación.

docker service create \
  --name my-preferred-service \
  --replicas 1 \
  --placement-pref 'spread=node.labels.node_type' \
  busybox:latest sleep infinity

La opción --placement-pref 'spread=node.labels.node_type' le dice al programador que distribuya las tareas entre los nodos en función del valor de la etiqueta node_type. En un clúster (swarm) de múltiples nodos con diferentes etiquetas node_type, esto distribuiría las tareas de manera más uniforme. En este entorno de un solo nodo, la tarea simplemente se programará en el nodo disponible.

Verifique el estado del servicio y las tareas:

docker service ls
docker service ps my-preferred-service

Debería ver my-preferred-service en la lista y su tarea en ejecución en el nodo actual.

Resumen

En este laboratorio, aprendimos cómo utilizar el comando docker service create para desplegar y gestionar servicios en Docker Swarm. Comenzamos creando un servicio replicado simple utilizando la imagen nginx, especificando el número deseado de réplicas para alta disponibilidad y escalabilidad. Luego, utilizamos docker service ls y docker service ps para verificar el estado del servicio e inspeccionar sus tareas en ejecución.

Posteriormente, exploramos la creación de un servicio global, comprendiendo su comportamiento de ejecutar una tarea en cada nodo elegible del clúster (swarm). Esto demostró la flexibilidad de Docker Swarm para desplegar servicios según diferentes requisitos.