Construire des images Docker avec Ansible
Publié le :
Ansible-bender ↗ est une application développée par Tomas Tomecek ↗ qui permet de construire des images de container à partir de playbooks ansible plutôt que des fichiers Dockerfile. Ansible-bender s’appuie sur le moteur de container Podman plutôt que docker.
Podman et Buildah
Podman est une solution de containérisation comme l’est Docker développée par RedHat. Il utilise le même interpréteur de ligne de commande que Docker et donc les principales commandes de Docker fonctionne avec Podman. Podman fonctionne sans daemon comme instance de gestion pour gérer ses pods. Cela permet d’accéder aux différentes applications virtualisées sans droits root. Podman est devenu le moteur de conteneur par défaut sous RHEL8.
Buildah est un outil complémentaire à Podman qui permet de créer des images au format Open Container Initiative (OCI). Ces images sont compatibles avec la plupart des runtimes de containers, ceux compatible avec la norme OCI: docker, containerd, runc, … et donc kubernetes. Il utilise aussi les fichiers Dockerfile pour décrire les images.
Installation d’Ansible-bender et de ses prérequis
Provisionnement d’une VM avec vagrant
Je vais utiliser une machine provisionnée avec vagrant pour faire mes tests en prenant une box oracle8.
# -*- mode: ruby -*-# vi: set ft=ruby :
Vagrant.configure("2") do |config| config.vm.box = "generic/oracle8" config.vm.provider "libvirt" do |hv| hv.cpus = "2" hv.memory = "2048" end config.vm.synced_folder '.', '/vagrant', disabled: true
config.vm.define "bender" do |bender| bender.vm.network :private_network, ip: "192.168.3.11" bender.vm.hostname = "bender" bender.vm.provision "ansible" do |a| a.verbose = "v" a.playbook = "provision-playbook.yml" end endend
Comme vous pouvez le remarquer, il fait appel à playbook ansible pour configurer la vm produite, qui permet surtout de lancer des playbooks sans à spécifier le user vagrant et d’installer podman, buildah et ansible-bender. Pour ceux qui ne connaissent pas l’écriture de playbooks ansible je vous renvoie sur mon billet.
N’oubliez pas de changer le chemin de votre clé ssh !
---- hosts: all gather_facts: no become: true tasks: - name: Install packages package: name: - python3-pip - podman - buildah
- name: Install ansible-bender and ansible pip: name: - ansible-bender - ansible
- name: Replace a localhost entry with our own lineinfile: path: /etc/hosts regexp: '^127\.0\.0\.1' line: 127.0.0.1 localhost owner: root group: root mode: '0644'
- name: Allow password authentication lineinfile: path: /etc/ssh/sshd_config regexp: "^PasswordAuthentication" line: "PasswordAuthentication yes" state: present notify: restart sshd
- name: Set authorized key took from file authorized_key: user: vagrant state: present key: "{{ lookup('file', '/home/vagrant/.ssh/id_ed25519.pub') }}"
handlers: - name: restart sshd service: name: sshd state: restarted
Pour se connecter à notre vm il suffit de :
ssh 192.168.3.11[vagrant@bender ~]$
Construction d’une image docker avec ansible-bender
Le fonctionnement est assez simple. On utilise un playbook classique auquel on ajoute une variable ansible-bender pour indiquer :
- l’image de base
- le nom de l’image (tag) produit
- les volumes
- …
La seule contrainte est d’utiliser des images sources contenant déja python3.6 au minimun (ex: python:3-alpine)
Par exemple:
---- name: Demonstration of ansible-bender functionality hosts: all vars: ansible_bender: base_image: python:3-alpine
working_container: volumes: - '{{ playbook_dir }}:/src'
target_image: name: a-very-nice-image working_dir: /src labels: built-by: '{{ ansible_user }}' environment: FILE_TO_PROCESS: README.md tasks: - name: Run a sample command command: 'ls -lha /src' - name: Stat a file stat: path: "{{ lookup('env','FILE_TO_PROCESS') }}"
Construction de notre propre image
Je vais créer une image installant apache2 et affichant un simple fichier. Créer les deux fichiers suivant dans votre vm.
Le fichier file.html :
<h1>hello world!</h1>
Le fichier playbook.yml
---- name: Serve file using apache hosts: all vars: ansible_bender: base_image: "docker.io/library/python:3-alpine" target_image: name: test:0.1 cmd: httpd -DFOREGROUND ports: ["80"] squash: true
- name: Serve our file using httpd hosts: all tasks: - name: Install httpd package: name: - apache2 - libxml2-dev - apache2-utils state: installed - name: Copy copy: src: file.html dest: /var/www/html/
Vous remarquez que j’ai ajouté quelques variables à ansible-bender permettant d’exposer le port 80 (un tableau de string), la commande du container et squash qui permet d’aplatir l’image produite à un seul layer. La liste des toutes ces options se trouve ici ↗
Lançons la construction de l’image:
ansible-bender build playbook.yml
Qui retourne :
PLAY [Serve file using apache] *************************************************
TASK [Gathering Facts] *********************************************************ok: [test-0-1-20210415-073450224792-cont]
PLAY [Serve our file using httpd] **********************************************
TASK [Gathering Facts] *********************************************************ok: [test-0-1-20210415-073450224792-cont]
TASK [Install httpd] ***********************************************************loaded from cache: 'c4211dd45723cd1caafaa3037aed2325666d8159dbbfc207a8bbf806c62a4530'skipping: [test-0-1-20210415-073450224792-cont]
TASK [Copy] ********************************************************************changed: [test-0-1-20210415-073450224792-cont]
PLAY RECAP *********************************************************************test-0-1-20210415-073450224792-cont : ok=3 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Getting image source signaturesCopying blob sha256:5d0c4fd59dd60a3b05d6fd9c099f6791ca4358e2c1685929da8f4ab23774da61Copying config sha256:fca2397b32294275d3c86dde9e1fbf7873febd63b9a541e1cb78d641516669ffWriting manifest to image destinationStoring signaturesfca2397b32294275d3c86dde9e1fbf7873febd63b9a541e1cb78d641516669ffImage 'test:0.1' was built successfully \o/[vagrant@bender ~]$ podman imagesREPOSITORY TAG IMAGE ID CREATED SIZElocalhost/test 0.1 fca2397b3229 11 seconds ago 62.9 MB
Lançons l’image construite :
podman run -p 80:80 -d test:0.1
Vérifions qu’elle fonctionne :
curl http://localhost:8080<html><body><h1>It works!</h1></body></html>
Mais combien a t’elle de layers ?
podman image inspect test:0.1
...
"RootFS": { "Type": "layers", "Layers": [ "sha256:5d0c4fd59dd60a3b05d6fd9c099f6791ca4358e2c1685929da8f4ab23774da61" ] },...
Un seul comme demandé.
Conclusion
Je trouve ansible-bender plutôt sexy et je pense même l’intégrer dans un runner gitlab pour construire quelques-unes de mes images. Un beau couple ansible docker !