Cree, guarde y cargue imágenes de contenedores con Ansible

Crear imágenes de contenedor y colocarlas en repositorios ascendentes es una forma común de hacer que sus imágenes estén disponibles para el mundo exterior. Sin embargo, puede encontrar escenarios en los que no desee cargar una imagen de contenedor en un repositorio. Tal vez no quiera cargar su imagen por razones de seguridad, o tal vez su clúster sea lo suficientemente pequeño (por ejemplo, en su laboratorio doméstico) como para no querer lidiar con un repositorio (ya sea externo o autohospedado) .

Si tiene un caso de uso para evitar almacenar las imágenes de su contenedor en un repositorio, ¡está de suerte! Ansible módulo docker_image hace que sea fácil crear, guardar y cargar sus imágenes sin tener que acceder a un repositorio. Este artículo lo guía a través de algunos libros de jugadas simples que puede incorporar a su flujo de trabajo para administrar contenedores con Ansible.

Resumen del medio ambiente

Primero, déjame presentarte la estructura básica de directorios que usaré para este tutorial:

$ ls -lah
total 28K
drwxr-xr-x  2 acritelli acritelli 4.0K May  6 11:24 ./
drwxr-xr-x 29 acritelli acritelli 4.0K May  3 08:26 ../
-rw-rw-r--  1 acritelli acritelli  261 May  2 22:23 save.yml
-rw-rw-r--  1 acritelli acritelli  254 May  2 22:20 build.yml
-rw-rw-r--  1 acritelli acritelli   49 May  2 22:01 Dockerfile
-rw-rw-r--  1 acritelli acritelli   54 May  2 22:45 inventory.ini
-rw-rw-r--  1 acritelli acritelli  403 May  2 22:49 load.yml

Tengo un Dockerfile, un inventario de Ansible y algunos manuales sencillos para trabajar con el módulo de imágenes de Ansible Docker. Los hosts en este entorno se definen en el inventory.ini archivar:

$ cat inventory.ini
[build_host]
docker-build.example.com

[docker_hosts]
docker01.example.com
docker02.example.com

Hay tres hosts con los que trabajo en este artículo:

  • docker-build: este servidor se utiliza para crear contenedores Docker. Luego, las imágenes del contenedor se guardan en este host.
  • docker01 y docker02: estos hosts se utilizan para ejecutar contenedores. Los contenedores build01 se descargan y se ponen a disposición de estos dos hosts.

Los tres hosts del entorno tienen Docker y el SDK de Docker para Python instalado. El SDK es necesario para usar los módulos de Ansible Docker. Puede instalar todos estos desde los repositorios estándar a través de yum:

[[email protected] ~]# yum install docker python-docker-py

construir un contenedor

El primer paso en este flujo de trabajo es crear una imagen de contenedor real. La imagen que uso en este artículo es muy simple: simplemente lanza una netcat escucha en el puerto 8080 y espera las conexiones del cliente, como puede ver en el Dockerfile:

$ cat Dockerfile
FROM alpine:latest
EXPOSE 8080
CMD nc -l -p 8080

Luego, se puede usar un libro de jugadas simple de Ansible para crear una imagen de contenedor basada en este Dockerfile:

$ cat build.yml
---
- hosts: build_host
  gather_facts: no
  tasks:
    - name: create build directory
      file:
        path: /root/demo-dockerfile
        state: directory
        owner: root
        group: root
        mode: '0755'
    - name: copy Dockerfile
      copy:
        src: ./Dockerfile
        dest: /root/demo-dockerfile/Dockerfile
        owner: root
        group: root
        mode: '0644'
    - name: build container image
      docker_image:
        name: democontainer:v1.0
        build:
          path: /root/demo-dockerfile
          source: build
        state: present

Este libro de jugadas crea un directorio de compilación en el servidor de "compilación", copia el Dockerfile en este directorio y luego compila el contenedor utilizando el docker_image Módulo ansible. El parámetro fuente establecido en "construir" le dice al módulo que cree una imagen de contenedor basada en la ruta especificada. En este caso, la ruta apunta al directorio y al Dockerfile que se copiaron en el host de compilación.

La ejecución exitosa de este manual genera la imagen del contenedor:

$ ansible-playbook -i inventory.ini build.yml

PLAY [build_host] ****************************************************************************************************************************************************************************

TASK [create build directory] ****************************************************************************************************************************************************************
changed: [docker-build.example.com]

TASK [copy Dockerfile] ***********************************************************************************************************************************************************************
changed: [docker-build.example.com]

TASK [build container image] *****************************************************************************************************************************************************************
changed: [docker-build.example.com]

PLAY RECAP ***********************************************************************************************************************************************************************************
docker-build.example.com   : ok=3    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Puede conectarse al servidor de compilación después de que finalice el libro de jugadas para ver que el democontainer:v1.0 la imagen se creó con éxito y está disponible para lanzar un contenedor:

[[email protected] ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
democontainer       v1.0                f2d7d737743e        About a minute ago   5.61 MB
docker.io/alpine    latest              f70734b6a266        13 days ago          5.61 MB

Guardar imagen de contenedor

Las imágenes de contenedores se pueden guardar en un tarball usando la herramienta docker save pedido. Tarballs proporciona una forma conveniente de "exportar" las imágenes de su contenedor. El módulo de imágenes de Ansible Docker también incluye soporte para exportar una imagen a un tar archivar:

$ cat save.yml
---
- hosts: build_host
  gather_facts: no
  tasks:
    - name: archive container image as a tarball
      docker_image:
        name: democontainer:v1.0
        archive_path: /root/democontainer_v1_0.tar
        source: pull
        state: present
    - name: fetch archived image
      fetch:
        src: /root/democontainer_v1_0.tar
        dest: ./democontainer_v1_0.tar
        flat: true

Este libro de jugadas primero archiva la imagen usando el docker_image módulo, luego obtiene el archivo del servidor remoto y lo coloca en el directorio local. Después de ejecutar con éxito el libro de jugadas, tiene un tar archivo en su directorio local que contiene el contenido de la imagen:

$ ansible-playbook -i inventory.ini save.yml

PLAY [build_host] ****************************************************************************************************************************************************************************

TASK [archive container image as a tarball] **************************************************************************************************************************************************
changed: [docker-build.example.com]

TASK [fetch archived image] ******************************************************************************************************************************************************************
changed: [docker-build.example.com]

PLAY RECAP ***********************************************************************************************************************************************************************************
docker-build.example.com   : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Note que el democontainer ahora está atascado en el directorio local:

$ ls
ansible.cfg  save.yml  build.yml  democontainer_v1_0.tar  Dockerfile  inventory.ini  load.yml

Cargar una imagen de contenedor

Una vez que la imagen se descarga en su sistema local, puede volver a utilizar el módulo de imágenes de Ansible Docker para descargar el tarball en todos sus hosts de Docker e importarlo. Una vez importada, la imagen del contenedor está disponible para lanzar contenedores.

$ cat load.yml
---
- hosts: docker_hosts
  gather_facts: no
  tasks:
    - name: copy tarball to host
      copy:
        src: ./democontainer_v1_0.tar
        dest: /root/democontainer_v1_0.tar

    - name: load container from tarball
      docker_image:
        name: democontainer:v1.0
        load_path: /root/democontainer_v1_0.tar
        state: present
        source: load

Este libro de jugadas copia el archivo creado en el save.yml libro de jugadas para todos los hosts de Docker. Luego carga la imagen del contenedor para que esté disponible en el futuro. docker run pedidos.

$ ansible-playbook -i inventory.ini load.yml

PLAY [docker_hosts] **************************************************************************************************************************************************************************

TASK [copy tarball to host] ******************************************************************************************************************************************************************
changed: [docker01.example.com]
changed: [docker02.example.com]

TASK [load container from tarball] ***********************************************************************************************************************************************************
changed: [docker01.example.com]
changed: [docker02.example.com]

PLAY RECAP ***********************************************************************************************************************************************************************************
docker01.example.com       : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
docker02.example.com       : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Una vez que el libro de jugadas se ejecuta con éxito, la imagen del contenedor se puede ver al enumerar las imágenes disponibles en uno de los hosts de Docker:

[[email protected] ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
democontainer       v1.0                f2d7d737743e        25 hours ago        5.61 MB
[[email protected] ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
democontainer       v1.0                f2d7d737743e        25 hours ago        5.61 MB

Luego puede lanzar un contenedor en uno de los hosts y ver si funciona.

Inicie el contenedor:

[[email protected] ~]# docker run --rm -it -p 8080:8080 democontainer:v1.0

El siguiente comando se ejecuta en una sesión separada:

[[email protected] ~]# telnet localhost 8080
Trying ::1...
Connected to localhost.
Escape character is '^]'.
hello!

Puede ver que la salida se repite en el contenedor a través de netcat:

[[email protected] ~]# docker run --rm -it -p 8080:8080 democontainer:v1.0
hello!

Si desea evitar tener que copiar la imagen del contenedor en su host local y luego volver a copiarla en los hosts de Docker, puede consultar la Módulo de sincronización de Ansible. Aunque está más allá del alcance de este artículo, puede ganar eficiencia con esta envoltura delgada rsync.

Envoltura

Este artículo lo guió a través del uso del módulo de imágenes de Ansible Docker, que ayuda a administrar imágenes de contenedores en hosts remotos. Aprendió a crear, guardar y cargar una imagen con manuales sencillos de Ansible. Si bien el uso de un repositorio de contenedores es una forma estándar de hacer que una imagen esté disponible en varios hosts, el uso de este módulo de Ansible también puede proporcionar un mecanismo sencillo para compartir sus imágenes en un entorno pequeño.

Artículos de interés

Subir