Dockerisation du service cobbler

Étude d’un système cobbler existant

Un système cobbler comporte plusieurs services:

  • le service cobbler à proprement parlé
  • un service web (apache) pour distribuer les RPMs
  • un service de transfert de fichier basique (tftp) pour distribuer le noyau bootable permettant d’afficher le menu, et tout ce qui va avec.

L’analyse du système existant nous montre

  1. Nous n’avons pas besoin de gérer le DHCP et le DNS, ceux-ci sont déjà gérés sur notre réseau et seul l’adresse du next_server sera mis à jour dans la configuration du DHCP.
  2. On utilise plusieurs snippets additionnels pour configurer la cible dans la phase post-installation (notamment une mise à jour de la distribution, l’installation du dépôt epel, etc…).
  3. Seulement quelques répertoires contiennent des données personnalisées:
    • /var/lib/cobbler: Ce répertoire contient deux types de données:
      • Les Données dynamiques propres à chaque installation et qui doivent être persistantes. Elles seront donc intégrées dans un ou plusieurs volumes de données: /var/lib/cobbler/config (la configuration dynamique) et /var/lib/cobbler/backup (le répertoire des sauvegardes)
      • Les Données semi-statiques. Elles seront intégrées directement dans l’image docker: les modèles de kickstart (définition de l’installation), les snippets (bout de code ré-utilisable), etc…
    • /var/www/cobbler: qui contient le dépôt de paquets RPM des distributions importées. Ces fichiers sont servis par le serveur web et ce répertoire sera intégré dans un volume de données.
    • /var/lib/tftp: qui contient le noyau bootable (pxelinux.0) , le menu d’installation, etc… Ces fichiers sont servis par le serveur tftpd et ce répertoire sera intégré dans un volume de données
    • On aura besoin d’un cinquième point de montage (/mnt sur le conteneur) où les isos des distributions seront montées par le serveur hôte.
      mkdir /mnt/centos
      mount -o ro /path/to/iso/CentOS-7-x86_64-DVD-1804.iso /mnt/centos
    • Et même d’un sixième point de montage, si l’hôte du conteneur a un noyau inférieur à 4.7, à cause du bug concernant les sockets unix sur overlayfs (lien): /var/run/supervisor

Bien entendu, pour ajouter un modèle de kickstart ou un snippet, l’image docker devra être reconstruite. Mais à l’usage, on se rend compte qu’on ajoute/modifie moins de fichiers snippets ou kickstart, que la disponibilité des mises à jour du paquet cobbler.

Démarrage

L’image peut être trouvée sur docker.io

docker pull tartarefr/docker-cobbler

Les variables d’environnement

Le service docker peut être personnalisé via les variables d’environnement suivantes:

  • HOST_IP_ADDR: Cette variable est la seule variable obligatoire car c’est elle qui permet la connexion à l’API cobbler et ne peut pas avoir de valeur par défaut. Elle doit prendre la valeur de l’adresse IP de l’hôte hostname --ip-address | awk '{print $1}'
  • HOST_HTTP_PORT: Port de l’hôte branché sur le port 80 du conteneur. Par défaut c’est 80 (-p 80:80)
  • DEFAULT_ROOT_PASSWD: Mot de passe en clair du compte superutilisateur root qui sera configuré sur les cibles (défaut: cobbler)
  • COBBLER_WEB_USER: Login de cobbler web (défaut: cobbler)
  • COBBLER_WEB_PASSWD: Mot de passe de cobbler web (défaut: cobbler)
  • COBBLER_WEB_REALM: Royaume de cobbler web car c’est de l’authentification digest (défaut: cobbler)
  • COBBLER_LANG: La langue à configurer lors de l’installation des cibles (défaut: fr_FR)
  • COBBLER_KEYBOARD: Le clavier à configurer lors de l’installation des cibles (défaut: fr-latin9)
  • COBBLER_TZ: Le fuseau horaire à configurer lors de l’installation des cibles (défaut: Europe/Paris)

Mise en place avant le premier démarrage

  1. On commence par télécharger l’iso DVD de centos 7
  2. Il va nous falloir construire 5 volumes docker pour un conteneur (même ratio que le pastis)
    docker volume create cobbler_www
    docker volume create cobbler_tftp
    docker volume create cobbler_config
    docker volume create cobbler_backup
    docker volume create cobbler_run
    
  3. On créé le point de montage de notre iso
    sudo mkdir /mnt/centos
  4. On monte notre iso dans /mnt/centos
    sudo mount -o ro /path/to/iso/CentOS-7-x86_64-DVD-1804.iso /mnt/centos
    

Démarrage

Je conseille fortement de modifier la valeur de DEFAULT_ROOT_PASSWD. En effet c’est un des tout premiers mot de passe root essayé par les pirates.

Contrairement à la valeur par défaut, notre serveur web (api et cobbler_web) sera accessible depuis l’hôte sur le port 60080.

docker run -d --privileged \
           -v cobbler_www:/var/www/cobbler:z \
           -v cobbler_tftp:/var/lib/tftp:z \
           -v cobbler_config:/var/lib/cobbler/config:z \
           -v cobbler_backup:/var/lib/cobbler/backup:z \
           -v cobbler_run:/var/run/supervisor:z \
           -v /mnt/centos:/mnt:z \
           -e DEFAULT_ROOT_PASSWD=cobbler \
           -e HOST_IP_ADDR=$(hostname --ip-address | awk '{print $1}') \
           -e HOST_HTTP_PORT=60080 \
           -e COBBLER_WEB_USER=cobbler \
           -e COBBLER_WEB_PASSWD=cobbler \
           -e COBBLER_WEB_REALM=Cobbler \
           -e COBBLER_LANG=fr_FR \
           -e COBBLER_KEYBOARD=fr-latin9 \
           -e COBBLER_TZ=Europe/Paris \
           -p 69:69/udp \
           -p 60080:80 \
           -p 60443:443 \
           -p 25151:25151 \
           --name cobbler \
           tartarefr/docker-cobbler:latest

Initialisation

Une fois à l’intérieur du conteneur, on va ajouter la cible memtest à notre menu d’installation, puis on va importer notre distribution centos 7, ajouter un profile supplémentaire qui permettra d’installer centos 7 avec un environnement graphique et synchroniser le tout.

  1. Immersion dans notre conteneur
    docker exec -ti cobbler /bin/bash
  2. Ajout de la cible memtest. On vérifie au préalable que le fichier /boot/memtest86+-5.01 existe bien (la version peut être modifiée et la ligne suivante doit être adaptée en conséquence)
    cobbler image add --name=memtest86+ --file=/boot/memtest86+-5.01 --image-type=direct
  3. Import de la distribution centos 7
    cobbler import --path=/mnt --name=CentOS-7-x86_64
  4. Ajout du profile pour une installation d’une centos desktop
    cobbler profile add --name=CentOS-7-x86_64-Desktop \
        --distro=CentOS-7-x86_64 \
        --kickstart=/var/lib/cobbler/kickstarts/sample_end.ks \
        --virt-file-size=12 \
        --virt-ram=2048
    
    cobbler profile edit --name CentOS-7-x86_64-Desktop --ksmeta="type=desktop"
    
  5. Synchronisation
    cobbler sync


Malheureusement, le changement de fichier iso (démontage et le montage d’un autre iso sur le même point de montage) sur l’hôte ne met pas à jour le contenu du répertoire /mnt dans le conteneur.
Pour ajouter une autre distribution, il faudra:

  1. stopper le conteneur
  2. détruire le conteneur
  3. démonter l’iso sur l’hôte
  4. monter le nouvel iso
  5. démarrer un nouveau conteneur

Modification de l’image

Pour ajouter un modèle de kickstart ou un snippet, il suffit de placer le fichier dans le répertoire idoine et de modifier le fichier Dockerfile:

  1. Ajouter une instruction docker de copie du fichier dans l’image du conteneur
  2. Si c’est un snippet s’éxecutant dans la phase post-installation, ajouter le nom à la liste des snippets post-installation à l’instruction d’activation (Activate personnal snippets)
  3. Reconstruire l’image
  4. Déployer la nouvelle image

Quelques mots sur l’image docker

J’ai préféré construire une image en partant de zéro, car celles disponibles sont soit plus mise à jour, soit elles utilisent systemd. Je préfère garder cette option pour les cas particuliers, inutile de sortir le tank pour écraser un moustique.

Supervisord est un bien meilleur candidat pour le poste d’orchestrateur dans un conteneur (le bon outil pour la bonne tâche) et permet de redémarrer un ou plusieurs services.

supervisorctl restart cobblerd

L’ensemble du projet cobbler est versionné sur gitlab, et en copie sur github (pour la construction automatique des images sur docker.io).

Fichier Dockerfile
FROM centos:7

MAINTAINER Didier FABERT (tartare) <didier@tartarefr.eu>

# RPM REPOs
RUN yum install -y \
    epel-release \
    && yum clean all \
    && rm -rf /var/cache/yum

RUN yum update -y \
    && yum clean all \
    && rm -rf /var/cache/yum

RUN yum install -y \
  cobbler \
  cobbler-web \
  pykickstart \
  debmirror \
  curl wget \
  rsync \
  supervisor \
  net-tools \
  memtest86+ \
  && yum clean all \
  &&  rm -rf /var/cache/yum

# Copy supervisor conf
COPY supervisord/supervisord.conf /etc/supervisord.conf
COPY supervisord/cobblerd.ini /etc/supervisord.d/cobblerd.ini
COPY supervisord/tftpd.ini /etc/supervisord.d/tftpd.ini
COPY supervisord/httpd.ini /etc/supervisord.d/httpd.ini

# Copy personnal snippets
COPY snippets/partition_config /var/lib/cobbler/snippets/partition_config
COPY snippets/configure_X /var/lib/cobbler/snippets/configure_X
COPY snippets/add_repos /var/lib/cobbler/snippets/add_repos
COPY snippets/disable_prelink /var/lib/cobbler/snippets/disable_prelink
COPY snippets/systemd_persistant_journal /var/lib/cobbler/snippets/systemd_persistant_journal
COPY snippets/rkhunter /var/lib/cobbler/snippets/rkhunter
COPY snippets/enable_X /var/lib/cobbler/snippets/enable_X
COPY snippets/yum_update /var/lib/cobbler/snippets/yum_update

# Copy personnal kickstart

# Activate personnal snippets
RUN for kickstart in sample sample_end legacy ; \
    do \
        additional_post_snippets="" ; \
        for snippet in \
                        add_repos \
                        disable_prelink \
                        systemd_persistant_journal \
                        rkhunter \
                        enable_X \
                        yum_update ; \
        do \
          additional_post_snippets="${additional_post_snippets}\n\$SNIPPET('${snippet}')" ; \
        done ; \
        sed -i \
           -e "/post_anamon/ s/$/${additional_post_snippets}/" \
           -e "/^autopart/ s/^.*$/\$SNIPPET('partition_config')/" \
           -e "/^skipx/ s/^.*$/\$SNIPPET('configure_X')/" \
       /var/lib/cobbler/kickstarts/${kickstart}.ks ; \
    done

# Install vim-enhanced by default and desktop packages if profile have el_type set to desktop (ksmeta)
RUN echo -e "@core\n\nvim-enhanced\n#set \$el_type = \$getVar('type', 'minimal')\n#if \$el_type == 'desktop'\n@base\n@network-tools\n@x11\n@graphical-admin-tools\n#set \$el_version = \$getVar('os_version', None)\n#if \$el_version == 'rhel6'\n@desktop-platform\n@basic-desktop\n#else if \$el_version == 'rhel7'\n@gnome-desktop\n#end if\n#end if\nkernel" >> /var/lib/cobbler/snippets/func_install_if_enabled

COPY first-sync.sh /usr/local/bin/first-sync.sh
COPY entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh /usr/local/bin/first-sync.sh

EXPOSE 69 80 443 25151

VOLUME [ "/var/www/cobbler", "/var/lib/tftp", "/var/lib/cobbler/config", "/var/lib/cobbler/backup", "/var/run/supervisor", "/mnt" ]

ENTRYPOINT /entrypoint.sh

Lancement de la construction

docker build -t local/cobbler .

En cas de problème, ne pas hésiter à regarder le fichier /var/log/cobbler/cobbler.log

Leave a Comment

Your email address will not be published. Required fields are marked *