Journal Yocto+Docker: Continuons l'expérience

Posté par (page perso) . Licence CC by-sa
Tags :
8
12
avr.
2016

Sommaire

Introduction

Il y a quelques jours, j'ai commencé à m'intéresser à Docker et à un possible mariage avec Yocto. Ref. Yocto+docker: Les containers personnalisés
Aujourd'hui, je continue l'expérience et continue à la partager (attention, le papier est un peu long…).

Les idées développées cette fois-ci sont les suivantes :

  • Construire une image un peu plus complexe qui servira de base à nos futures applications incluant un accès ssh et smart (gestionnaire de paquet).
  • Mettre en place un dépôt (contenant les paquets crées par Yocto) et qui sera disponible pour nos applications.
  • Utiliser ce dépôt pour installer des logiciels sur notre image.

Mettons en place notre dépôt

Le dépôt contenant les paquets créés par Yocto se trouve dans le répertoire ~/yocto/poky/build/tmp/deploy/rpm/

Nous allons donc lancer un conteneur nginx avec la commande suivante :

sudo docker run --name docker-nginx -p 80:80 -ti --rm -v /home/developper/yocto/poky/build/tmp/deploy/rpm/:/usr/share/nginx/html nginx

Note : Sur FC23, j'ai désactivé selinux pour faire marcher mon volume (dans /etc/selinux/config).

Pour vérifier que notre dépôt fonctionne, on peut activer l'affichage des répertoires dans nginx.

Connectons nous à notre conteneur :

docker exec -ti docker-nginx bash

Et modifions la configuration de notre site pou y ajouter autoindex on; :

cat > /etc/nginx/conf.d/default.conf<<EOF
server {
    listen       80;
    server_name  localhost;
    location / {
        autoindex on;
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
EOF

Rechargeons maintenant la configuration de nginx :

/etc/init.d/nginx reload

Maintenant, si on navigue sur la page http://127.0.0.1/ on doit voir le contenu de notre dépôt (jusqu'au prochain démarrage…).

Améliorons l'image de base

Notre dépôt est prêt, il faut maintenant que notre image de base soit capable de l'utiliser. Nous allons donc mettre à jour la recette de notre image comme suit :

cat > ~/yocto/poky/meta-xb/recipes-core/images/docker-image-base.bb <<EOF
SUMMARY = "Base image for docker guest - Proof of Concept"
DISTRO = "poky-tiny"
IMAGE_FSTYPES = "tar.bz2 "
LICENSE = "MIT"
IMAGE_FEATURES += "package-management"
IMAGE_INSTALL += "busybox dropbear"
inherit core-image
EOF

On peut noter que j'ai ajouté le gestionnaire de paquet. C'est smart qui est proposé par défaut par Yocto en association avec des paquets au format rpm.
J'ai aussi ajouté dropbear pour l'accès ssh.

On reconstruit l'image :

cd ~/yocto/poky
source oe-init-build-env
bitbake docker-image-base

On copie maintenant l'image dans notre espace de travail docker pour pouvoir l'utiliser :

mkdir -p ~/yocto/docker
cd ~/yocto/docker
cp ../poky/build/tmp/deploy/images/genericx86-64/docker-image-base-genericx86-64.tar.bz2 .

On va avoir besoin d'un script de démarrage pour démarrer dropbear. Ce script (écrit vite fait) démarrera ensuite une commande top afin d'avoir une commande bloquante (pour avoir une image fonctionnelle avec docker-compose qu'on utilisera plus tard)  :

cat > init.sh <<EOF
#!/bin/sh
/etc/init.d/dropbear start
top
EOF

On créé le Dockerfile décrivant notre application:

cat > Dockerfile <<EOF
FROM scratch
ADD docker-image-base-genericx86-64.tar.bz2 /
ENV PS1 '[`whoami`@`hostname | sed "s/\..*//"` ${PWD}]# '
RUN smart channel -y --add all type=rpm-md baseurl=http://repo/all/
RUN smart channel -y --add core2_64 type=rpm-md baseurl=http://repo/core2_64/
RUN smart channel -y --add genericx86_64 type=rpm-md baseurl=http://repo/genericx86_64/
EXPOSE 22
COPY init.sh /usr/bin/init.sh
RUN chmod +x /usr/bin/init.sh
CMD ["init.sh"]
EOF

Dans cette nouvelle version, j'ai ajouté un prompt un peu plus explicite et quelques commandes qui initialiseront les dépôts disponibles et notre script de démarrage.

Ensuite, on peut construire l'image et la tester.

docker build -t docker-base . 
docker run -ti --rm -p22:22 docker-base

Pour vérifier, on peut se connecter en ssh et vérifier la présence de la commande smart

ssh root@127.0.0.1
smart

Démarrons notre environnement de test de manière automatisée

Nous allons utiliser docker-compose pour lancer nos deux conteneurs (dépôt et machine) en même temps et les mettre en relation.
Installons d'abord docker-compose

sudo dnf install docker-compose

Créons la description de notre environnement dans docker-compose.yml :

cd ~/yocto/docker
cat > yocto-docker-test.yml <<EOF
repo:
 image: nginx
 ports:
   - "80:80"
 volumes:
   /home/developper/yocto/poky/build/tmp/deploy/rpm/:/usr/share/nginx/html
machine:
  image : docker-base
  ports :
    - "22:22"
  link :
    - repo:repo
EOF

On retrouve ici la description de nos deux conteneurs et un lien permettant à notre machine de test de se connecter à notre dépôt.

Utilisons notre dépôt

Pour continuer l'expérience et à titre d'exemple, nous allons installer vim. vim est disponible dans le layer meta-oe d'openembedded. Installons ce layer à partir du dépôt git d'openembedded :

cd ~/yocto/poky
git://git.openembedded.org/meta-openembedded -b jethro

Il faut ensuite mettre à jour le fichier ~/yocto/poky/build/conf/bblayer.conf et rajouter la ligne qui donnera accès à ce nouveau layer :

BBLAYERS += "/home/developper/yocto/poky/meta-openembedded/meta-oe "

Pour créer le paquet et mettre à jour le dépôt, on exécute les lignes suivantes :

bitbake vim
bitbake package-index

Pour installer vim, il suffit de taper les commandes suivantes sur la machine cible :

smart update
smart install vim

Un petit bonus…

Voici un exemple d'utilisation de notre dépôt pour une application qui n'est pas dans les dépôts officiels. (J'ai choisi cette application au hasard sur github)
Commençons par créer la recette de cette nouvelle application :

mkdir -p ~/yocto/poky/meta-xb/recipes-game/tty-tetris
cat > ~/yocto/poky/meta-xb/recipes-game/tty-tetris/tty-tetris_git.bb <<EOF
SUMMARY = "Example of recipe"
DESCRIPTION = "Part of Yocto+Docker journal fro X@v"
SRC_URI = "git://github.com/xorg62/tty-tetris.git"
SRCREV  = "616bec61c52f3f5370e36993d7ba18c9f24d669b"
PV = "0.1+git${SRCPV}"
PR = "r1"
LICENSE = "BSD"
LIC_FILES_CHKSUM = "file://tetris.c;beginline=1;endline=31;md5=6b9c612aa8a5fb85148b8975e8079af4"
S = "${WORKDIR}/git"
FILES_${PN} += "/usr/local/bin/tty-tetris"
FILES_${PN}_dbg += "/usr/local/bin/.debug/tty-tetris"
do_configure() {
    echo "done"
} 
do_install() {
    install -d ${D}/usr/local/bin/
    install -m 0755 ${S}/tty-tetris ${D}/usr/local/bin/
}
EOF

Construisons notre nouveau paquet :

bitbake tty-tetris

Mettons à jour notre dépôt :

bitbake package-index

Enfin, sur la machine cible, installons le nouveau paquet :

smart update
smart install tty-tetris

Ça y est c'est installer, vous pouvez maintenant jouer à Tetris sur votre conteneur docker à partir d'un connexion ssh… rigoureusement indispensable ;-).

Conclusion

Comme le prouve mes petites expériences, il est possible d'associer Yocto et Docker pour créer des images personnalisées.
Ne reste plus qu'à trouver des cas d'usages… des idées?

  • # Mauvaise pratique : SSH dans un conten

    Posté par . Évalué à 6.

    Avoir un SSH dans un conteneur docker est considéré comme une mauvaise pratique. Mieux vaut avoir un unique accès SSH sur le host et ensuite faire un docker exec pour entrer dans un conteneur.

    Parce que sinon, avoir 150 docker déployés ça fait beaucoup de clé ssh à gérer.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.