Docker 101

Î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ă interesele și preferințele autorilor.