DOCKER – Considerações em Aplicações Legacy.

Olá a todos,

Depois do ultimo post e de ter recebido tantos emails referentes a questão do docker estar a ser preterido em função do LXC típico , resolvi esta semana fazer um post em todo idêntico ao anterior, mas utilizando neste o Docker.
Nota: Por motivos de sigilo, a aplicação em questão não será revelada, sendo ela subsistida por uma instância de apache.

Em primeiro lugar, e após instalar uma instalação suportada de Linux na máquina física (RHEL 7.1 – 64bits) e configurada a componente de rede, chegou a altura de recuperar o  volume do raid, utilizando para tal uma máquina temporária.

Na pratica, a máquina arranca o sistema operativo (Linux) de um disco SATA local, e deixa os volumes do RAID idle.

Com o sistema temporário  em cima, ativei os antigos volume groups do RAID legacy e efetuei as copias do logical volumes que necessitava, utilizando para tal o dd_rescue, que é um pequeno aplicativo perfeito para recuperação de discos com IO errors (ou possíveis), para outros devices ou ficheiros:

# vgscan
# vgchange -ay vglegacy
# dd_rescue /dev/vglegacy/lvol0 /mnt/lvol0.img
# dd_rescue /dev/vglegacy/lvol1 /mnt/lvol1.img

Copiei em seguida os ficheiros gerados para a máquina final, e montei os mesmos como loop devices, de forma a eliminar alguns componentes que não interessavam para o arranque:

# mkdir /mnt/container0/rootfs
# mkdir /mnt/data1
# mount -o loop /mnt/lvol0.img /mnt/container0/rootfs
# mount -o loop /mnt/lvol1.img /mnt/data1

Nota: Para o caso especifico em mãos, foi necessário remover de dentro do /mnt/container0/rootfs/ os initscripts para UDEV, dentro da diretoria de init.d da máquina antiga, referencias a swap e configurações especificas de hardware que agora já não existiam. Lembrem-se igualmente que muito provavelmente os mac addresses das placas de rede irão igualmente mudar.

Foi necessário ainda criar a mão dentro do container todos os as consolas series virtuais e devices necessários.

#target=/mnt/container0/rootfs
#mkdir -m 755 “$target”/dev
#mknod -m 600 “$target”/dev/console c 5 1
#mknod -m 600 “$target”/dev/initctl p
#mknod -m 666 “$target”/dev/full c 1 7
#mknod -m 666 “$target”/dev/null c 1 3
#mknod -m 666 “$target”/dev/ptmx c 5 2
#mknod -m 666 “$target”/dev/random c 1 8
#mknod -m 666 “$target”/dev/tty c 5 0
#mknod -m 666 “$target”/dev/tty0 c 4 0
#mknod -m 666 “$target”/dev/urandom c 1 9
#mknod -m 666 “$target”/dev/zero c 1 5

# mknod -m 666 /dev/tty1 c 4 1
# mknod -m 666 /dev/tty2 c 4 2

E atribuir permissões para acesso por consola:

echo “pts/0” >>/etc/securetty

#sed -i s/”session    required     pam_selinux.so close”/”#session    required     pam_selinux.so close”/g /etc/pam.d/login
#sed -i s/”session    required     pam_selinux.so open”/”#session    required     pam_selinux.so open”/g /etc/pam.d/login
#sed -i s/”session    required     pam_loginuid.so”/”#session    required     pam_loginuid.so”/g /etc/pam.d/login

Em seguida e tendo em conta que estamos a falar de executar em 32bits um container dentro de um sistema a 64bits (lembrar o tema da aplicação ter hardcoded a validação do tipo de arquitetura  do CPU temos que observar as seguintes regras:

https://github.com/docker/docker/issues/611
https://github.com/docker-32bit
http://stackoverflow.com/questions/26490935/how-to-fake-cpu-architecture-in-docker-container

Finalmente iremos importar o antigo FS do nosso sistema com um docker container:

# tar –numeric-owner -c -C “$target” . | docker import – applegacy:build1

Após o tar finalizar, foi apenas questão de arrancar com o container:

# docker run -i -t –rm applegacy:build1 /bin/bash

E já está! Temos como resultado final uma maquina chrooted de 32bits a funcionar dentro de um servidor de 64bits:

(no host):

# uname -a
Linux XXXXXX 3.10.0-229.el7.x86_64 #1 SMP Thu Jan 29 18:37:38 EST 2015 x86_64 x86_64 x86_64 GNU/Linux

(no guest):

# uname -a
LinuxXXXXXX 3.10.0-229.el7.x86_64 #1 SMP Thu Jan 29 18:37:38 EST 2015 i686 i686 i386 GNU/Linux

É importante ainda, tendo em conta que não podemos utilizar o libvirtd (virt-manager) a semelhança do nosso ultimo post para gerir o nosso docker container, será importante validar as configurações de rede: https://docs.docker.com/v1.8/articles/networking/

Existem soluções de gestão de containers bundled em produto suportado, como por exemplo Red Hat Atomic. Caso procurem soluções suportadas de gestão, esse deverá ser o caminho.

Com esta configuração, a aplicação já arrancou conforme desejado e está presentemente a funcionar sem problemas.

Como considerações finais lembro que esta solução é uma solução de recurso,e que uma aplicação assim provavelmente não será suportada.

Podem agora tratar o vosso container de uma forma comum, incluindo backups e alarmistica, lembrando que as operações de backup devem ser feitas desde o host e não desde o container, e sempre com o cuidado especifico para aplicações com SGBD’s incluídas “inside”

No caso da nossa imagem docker, poderão a encontrar em:

# ls -lah /var/lib/docker/devicemapper/devicemapper
total 2.1G
drwx—— 2 root root   34 Jan 29 10:22 .
drwx—— 5 root root   53 Jan 29 10:23 ..
-rw——- 1 root root 100G Jan 30 18:55 data
-rw——- 1 root root 2.0G Jan 30 18:55 metadata

Se tiverem alguma duvida contactem-me através do email nuno at nuneshiggs.com

Abraço
Nuno