Cosmin L. Neagu

Nivel: Avansat
Data ultimei modificări: 2014.08.21

Îndrumar Docker

În mare Docker funcționează ca o mașină virtuală cu overhead
considerabil mai mic. E folosit pentru a rula aplicații într-un mediu
izolat de restul sistemului. Fiecare container Docker poate rula
propria distribuție Linux indiferent de distribuția de pe host.
Host-ul poate fi o mașină fizică sau un VPS (KVM, XEN, Virtualbox
…) și pentru a instala și folosi Docker e nevoie de acces root.

Definite printr-un singur fișier de configurare containerele Docker
pot fi refăcute de la zero în foarte scurt timp și vor funcționa
identic indiferent de serverul pe care sunt refăcute.
Este avantajoasă dezvoltarea aplicațiilor, local, folosind Docker pentru
ca mai apoi să poată fi mutate în producție, fără prea multe surprize.

Instalare Docker (ex. pentru Ubuntu 14.04)

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 \
     --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9

sudo sh -c "echo deb https://get.docker.io/ubuntu \
     docker main /etc/apt/sources.list.d/docker.list"

sudo apt-get update
sudo apt-get install lxc-docker

Pentru instalare pe alte distribuții puteți vizita
Docker.

Imagini Docker / Instanțe Docker

Imaginile Docker sunt practic filesystem-uri predefinite ce pot fi
folosite de către Docker. Se pot folosi imagini predefinite gen
ubuntu, ubuntu:12.04, centos, busybox, tianon/gentoo:latest
sau imagini construite pornind de la imagini de bază și aplicând
propriile modificări, update-uri, instalări și configurări.

Toate comenzile Docker trebuie rulate ca root:

# descarcă de pe net imaginea "ubuntu"
docker pull ubuntu:latest

# listează toate imaginile accesibile local
docker images

# pornește o instanță de ubuntu rulând comanda /bin/bash
# se poate detașa cu ^P^Q și reatașa cu docker attach
docker run -i -t ubuntu /bin/bash

# șterge imaginea respectiv toate imaginile
docker rmi ubuntu
docker rmi $(docker images -q)

# listează instanțele active
docker ps

# listează toate instanțele
docker ps -a

# șterge toate instanțele oprite
docker rm $(docker ps -a -q)

# repornește instanța cu ID 15786070c102
docker start 15786070c102

# conectare la instanța cu ID 15786070c102
docker attach 15786070c102

# salvează modificările din instanța 15786070c102
docker commit 15786070c102 imagine_noua

Imagini noi / Dockerfile

Imaginile noi pot fi create salvând modificările unei instanțe Docker,
ca în exemplul de mai sus, sau prin execuția unui fișier Dockerfile.
Execuția unui Dockerfile presupune pornirea unei imagini existente,
executarea succesivă a unei liste de comenzi și definirea unor
parametrii de execuție, totul într-un sistem automat.

Un exemplu minimal de Dockerfile ar putea fi:

FROM       ubuntu:latest
MAINTAINER Cosmin L. Neagu <cosmin@rohost.com>

RUN apt-get update
RUN apt-get -y upgrade

ENTRYPOINT /bin/bash

Comanda de mai jos crează practic o imagine nouă numită xxx pornind
de la ubuntu:latest și executând comenzile de update/upgrade.
La execuția imaginii fără comandă explicită se va executa bash-ul de
la ENTRYPOINT.

docker build -t="xxx" .

Folosind Dockerfile se pot instala și configura automat servicii
foarte complexe, inclusiv servicii distribuite și redundante pe un
număr mare de instanțe.

Atenție: Instanțele Docker se opresc automat în momentul în care
comanda inițială își încheie execuția. Pentru a rula servicii pe termen
lung se folosește în mod uzual supervisord, un sistem de control
al proceselor.

Docker Șablon/Template - exemplu funcțional

Indiferent de proiectul pe care îl implementăm fiecare avem propriile
preferițe legate de setări sau utilitare preferate. Din acest motiv
vom crea un docker de bază, un șablon, pe care mai apoi îl vom folosi
ca punct de plecare. Există mai multe feluri de lucru însă deocamdata
vom explora varianta mai comodă, în care folosim Docker ca o mașină
virtuala ce ruleaza mai multe servicii simultan.

Pentru scenarii mai avansate se pot instala imagini minimaliste
și servicii/aplicații individuale, eventual compilate static, pentru fiecare instanță.

Revenind la varianta comodă, într-un director gol creați fișierul
Dockerfile cu conținutul de mai jos. Practic îi spunem Docker-ului
să pornească de la un Ubuntu 14.04, să facă update la pachetele de
sistem, să instaleze utilitarele dorite de noi după care configurăm
SSH pentru a avea acces de la distanță și supervisord pentru
a putea ulterior adăuga ușor servicii noi.

FROM ubuntu:14.04
MAINTAINER Cosmin L. Neagu <cosmin@rohost.com>

# Set locale
RUN locale-gen --no-purge en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8
RUN echo 'LANG="en_US.UTF-8"'    >> /etc/environment
RUN echo 'LC_ALL="en_US.UTF-8"'  >> /etc/environment

# Upgrade packages
ENV DEBIAN_FRONTEND noninteractive 
RUN sed -i.bk 's/main$/main universe/' /etc/apt/sources.list && \
    apt-get update && \
    apt-get upgrade -y

# Install & setup supervisord and SSH
RUN mkdir -p /var/run/sshd
RUN mkdir -p /var/log/supervisor
RUN apt-get install -y supervisor openssh-server \
    rsync git vim mc

ADD authorized_keys         /root/.ssh/authorized_keys
ADD supervisord.conf        /etc/supervisor/conf.d/supervisord.conf
ADD supervisord.sshd.conf   /etc/supervisor/conf.d/sshd.conf

#RUN echo 'root:' | chpasswd

EXPOSE 22/tcp

CMD ["/usr/bin/supervisord"]

Fișierul authorized_keys, din acest nou director, trebuie sa
conțină cheile SSH publice ale persoanelor care doriți
să aibă acces. Cel mai probabil aici veți pune conținutul
fișierului ~/.ssh/id_rsa.pub.

supervisord.conf se asigură că serviciul rămâne activ în
foreground. Dacă acest serviciu și-ar încheia funcționarea
întreaga funcționare al containerului ar înceta.

[supervisord]
nodaemon=true

supervisord.sshd.conf asigură funcționarea serverului SSH.

[program:sshd]
command=/usr/sbin/sshd -D
stdout_logfile=/var/log/supervisor/%(program_name)s.out
stderr_logfile=/var/log/supervisor/%(program_name)s.err
autorestart=true

Aceste fișiere vor fi copiate automat în interiorul
containerului Docker pe care îl vom crea mai jos și vor face
parte din șablonul pe care îl vom folosi în continuare.

Crearea propriu zisă a imaginii

Pe orice calculator cu Docker instalat, dacă avem fișierele de
mai sus, putem recrea de la zero imaginea șablon. În acest caz
numele este “base” dar putem folosi orice nume dorim.
IP-ul folosit trebuie să fie setat pe host iar portul 222
trebuie să fie liber.

Imaginea creată mai sus, cu ajutorul fișierului Dockerfile este
doar un exemplu pentru a parcurge împreună anumiți pași.
În imaginea pe care o veți crea dv. înstalați și configurați
doar acele pachete care vă sunt de folos.

# crearea imaginii
docker build -t "base" .

# listăm imaginile disponibile
docker images

# pornim o instanță a imaginii base accesibila prin SSH cu:
# ssh root@93.115.111.248 -p 222
docker run -d -i -p 93.115.111.248:222:22/tcp -t base

GitRepo e un exemplu de proiect instalat
și menținut cu ajutorul Docker și al imaginii base creată
mai sus.

Pentru mai multe detalii vizitați website-ul proiectului la adresa docker.com

Conținutul acestui site reflectă interese și preferințe personale. Nu sunt un expert în fiecare subiect atins. Nu prezint adevăruri ci perspective.

Email: cosmin (at) rohost.com

Social: Google+, Twitter, GitHub