introduction À docker -...

159
INTRODUCTION À DOCKER Benoît Benedetti

Upload: hakhanh

Post on 14-Nov-2018

248 views

Category:

Documents


1 download

TRANSCRIPT

INTRODUCTIONÀDOCKERBenoîtBenedetti

APERÇUDOCKER

source:docker.com@Docker,inc

GÉNÉRALITÉSSURLESCONTAINEURS

MACHINEVIRTUELLE

VMAvantages

Emulationbasniveau

Sécurité/compartimentationfortehôte/VMset

VMs/VMs

Inconvénients

Usagedisqueimportant

Impactsurlesperformances

CONTENEURDOCKER

CONTENEURAvantages:

Espacedisqueoptimisé

ImpactquasinulsurlesperformancesCPU,réseauet

I/O

Inconvénients

FortementliéaukernelHôte

NepeutémulerunOSdifférentquel’hôte

Sécurité

CONTENEURLINUXProcessusisolépardesmécanismesnoyaux.

3élémentsfondamentaux

Namespaces

CGroups

Copy-On-Write

NAMESPACES

FONCTIONNALITÉDUKERNEL,AVECSONAPIApparuedanslenoyau2.4.19en2002,réellementutiles

en2013danslenoyau3.8

Limitecequ’unprocessuspeutvoirdusystème:

unprocessusnepeututiliser/impacterquecequ’ilpeut

voir

Types:pid,net,mnt,uts,ipc,user

Chaqueprocessusestdansunnamespacedechaquetype

NETNAMESPACELeprocessusnevoitquelapileréseauduNamespacedontil

faitpartie:

sesinterfaces(eth0,l0,différentesdel’hôte)

Tablederoutagesépararée.

règlesiptables

socket(ss,netstat)

NAMESPACEUTSIdentificationpropreauNamespace:

{get,set}hostname

NAMESPACEIPCPermettentàungroupedeprocessusd’unmêmenamespace

d’avoirleurspropres:

ipcsemaphore

ipcmessagequeues

ipcsharedmemory

Sansrisquedeconflitavecd’autresgroupesd’autres

namespaces

NAMESPACEUSERmappeuid/gidversdifférentsutilisateursdel’hôte

uid0⇒9999duC1correspondàuid10000⇒119999

surl’hôte

uid0⇒9999duC2correspondàuid12000⇒139999

surl’hôte

NAMESPACEMOUNTUnnamespacedisposedesonproprerootfs

(conceptuellementproched’unchroot)

peutmasquer/proc,/sys

peutaussiavoirsesmounts"privés"

/tmp(parutilisateur,parservice)

NAMESPACEPIDlesprocessusd’unnamespacepidnevoitquelesprocessus

decelui-ci

Chaquenamespacepidasaproprenumérotation,

débutantà1

SilePID1disparaît,lenamespaceestdétruit

Lesnamespacespeuventêtreimbriqués

UnprocessusadoncplusieursPIDs

Unpourchaquenamespacedanslequelilestimbriqué

ChaquenamespacepiddébuteaveclePID1etluietles

suivantssontlesseulsvisiblesdepuiscenamespace.

UTILISATIONDESNAMESPACESCréésàl’aidedeclone()ouunshare()

Matérialiséspardespseudo-filesdans/proc/$PID/ns

fichiersdans/proc/{pid}/ns

CONTROLGROUPS

CGROUPSLINUXFonctionnalitédunoyau,apparueen2008(noyau2.6.24)

Contrôlelesressourcesd’unprocessus:

allocation

monitoring

limite

type:

cpu,memory,network,blockio,device

Namepsaces permettent une séparation logique des containers alors que les cgroups permettent de spécifier quels resources physiques ils peuvent consommer

HIÉRARCHIENotiondehiérarchie:

Chaquesoussystèmeaunehiérarchie

hiérarchiesdifférentepourCPU,memory,blockI/O,

etc…

Hiérarchiesindépendantes:

LesarbrespourMEMORYetCPUsontdifférents

Chaqueprocessusestdansunnoeuddechaquehiérarchie

Chaquehiérarchiepartd’uneracine

Al’originechaqueprocessuspartdelaracine

Chaquenoeudéquivautàungroupedeprocessus

MEMORYCGROUPLimitespossibles

surlamémoirephysique,dunoyauettotale

Limitessoft/hard

Surveillancedel’utilisationdesressources

NotificationsOOMpossibles

CGROUPCPUSurveillancedutempsCPUutilisateur/système,de

l’utilisationparCPU

Possibilitédedéfinirunpoids

AllocationdeprocessusàunouplusieursCPU(s)

spécifique(s).

SUBTILITÉSCGROUPSPid1estplacéàlaracinedechaquehiérarchie

Lesnouveauxprocessussontdémarrésdanslegroupede

leurparent

Lesgroupessontmatérialiséspardespseudossystèmesde

fichiers

généralementmontésdans/sys/fs/cgroup

Lesgroupessontcréésdanscespseudossystèmesde

fichiers:

mkdir/sys/fs/cgroup/memory/somegroup/subgroup

Pourdéplacerunprocessusdansungroup:

DOCKER

CONTENEURS:LESBASES

CONTENEURBASIQUE$dockerrundebian/bin/echo"Salut"Salut$dockerrundebian/bin/echo"Coucou"Coucou

COMMANDESPS$dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES

$dockerps-aCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESd0683f6462a5debian"/bin/echoSalut"AboutaminuteagoExited(0)Aboutaminuteagohungry_visvesvarayae1794g7573b6debian"/bin/echoCoucou"AboutaminuteagoExited(0)Aboutaminuteagohappy_torvalds

RÉ-EXÉCUTERUNCONTENEUR$dockerstart-ihungry_visvesvarayaSalut

LOGS$dockerlogshungry_visvesvarayaSalutSalut

MÉNAGE$dockerrmhungry_visvesvaraya

CONTENEURENCOURSD’EXÉCUTION$dockerrun-itdebian/bin/bashroot@2c666d3ae783:/#ps-aPIDTTYTIMECMD6?00:00:00ps

AFFICHAGEAVECPSDepuisuneautreconsole

$dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES2c666d3ae783debian"/bin/bash"44secondsagoUp42secondshappy_mietner

DOCKERTOP$dockertophappy_mietnerUIDPIDPPIDCSTIMETTYTIMECMDroot23338867015:06pts/1500:00:00/bin/bash

INTERROMPRELECONTENEURETSONPROCESSUS

Outoutsimplementarrêterleprocessus(exitpourbash)

$dockerstop$conteneur$dockerkill$conteneur$dockerpause$conteneur#unpause

SEDÉTACHERPoursedétacherduprocessusd’unconteneursansl’arrêter

root@2c666d3ae783:/#^P^Q

SERATTACHERÀUNCONTENEURLeconteneurdoitêtreencoursd’exécution,onserattache

auprocessusexécuté:

$dockerattachhappy_mietnerroot@2c666d3ae783:/#

DOCKEREXEC

Leexitnetueraquelebashencours

$dockerexec-ithappy_mietner/bin/bashroot@2c666d3ae783:/#exit

IMAGES

IMAGE?Collectiondefichiers+méta-données

CesfichiersformentleFSracineduconteneur

Composéesdecouches,enthéoriesuperposées

Chaquecouchepeutrajouter,modifier,supprimerdes

fichiers

Desimagespeuventpartagerdescouchespouroptimiser

L’usagedisque

Lestempsdetransfert

DIFFERENCESAVECLESCONTENEURSSystèmesdefichierslecture-seule

Unconteneurestunensembledeprocessuss’exécutant

dansunecopieenlecture-écrituredecesystèmede

fichiers

Pouroptimiserlesressources,leCoWestutiliséaulieude

copierlesystèmedefichiers.

dockerrundémarreunconteneurdepuisuneimage

copy on write (en lecture seule au départ puis on duplique quand on modifie)

COUCHES

MÉTAPHORESLesimagessontdespatronsdepuislesquellesvouscréezdes

conteneurs.

EnProgammationOrientéeObjet:

LesImagessontconceptuellementsimilairesauxclasses,

Lescouchessontconceptuellementsimilairesàl’héritage,

LesConteneurssontconceptuellementsimilairesàdes

instancesd’image.

EXEMPLESIMAGEShello-world

ubuntu

mysql

Wordpress

ApplicationJAVA

REGISTREHébergelesimages,etlesmetàdisposition.

Lesimagessontrécupéréesenlocaldepuisunregistre

distant.

Ilexiste2typesderegistre:

DockerHub

Auto-hébergés

DOCKERHUBServiceenligne,officieldeDocker,pourdistribuerlesimages

composants:

Unindex:indexetouteslesméta-donnésdesimages

hébergéespourrecherche.

Unregistre:stockelescouchesdesimagespour

récupérationetupload.

Pardéfaut,lescommandesdeDockerliéesauximages

utilisentleDockerHub.

https://hub.docker.com/

REGISTREAUTO-HÉBERGÉRegistrehébergéeninterne.

Dockerfournitunconteneurpourhébergersonpropre

registre.

Protocoleopen-source:différentesimplémentations

existent.

ESPACESDENOMIlexiste3manièresdenommerdesimages:

Imagesofficielles:

Ex:ubuntu,debian

Imagesutilisateur:

Ex:benedetti/myapp

Imagesauto-hébergées:

Ex:registry.example.com:5000/my-private/image

ESPACEDENOMSRACINECetespacedenomestpourlesimagesdistribuées

officiellementparDocker,maisgénéralementcrééespardes

tiers.

Typesd’images:

imagesdedistributionàutilisercommebase:debian,

ubuntu

servicesprêtàl’emploi:mysql,tomcat

ESPACEDENOMUTILISATEURImagesmisesàdispositionparDockersansvérification.

Exbenedetti/mysqloubenedetti/myapp

benedettiestmonnomd’utilisateurchezDocker

Lenomdel’imageestmysqloumyapp

ESPACEDENOMAUTO-HÉBERGÉImagesauto-hébergéesetdistribuéesnonofficiellement.

Ex:exemple.fr:5000/wordpress

exemple.fr:5000:hôteetportduregistreauto-hébergé

wordpress:nomdel’image

⇒vousn’utiliserezsûrementpasderegistreetimageauto-

hébergés.

RECHERCHERUNEIMAGEVouspouvezlefairevial’interfaceweb,ouvialaCLI:

$dockersearchnginxNAMEDESCRIPTIONSTARSOFFICIALAUTOMATEDnginxOfficialbuildofNginx.4172[OK]jwilder/nginx-proxyAutomatedNginxreverseproxyfordockerc...800[OK]richarvey/nginx-php-fpmContainerrunningNginx+PHP-FPMcapable...274[OK]million12/nginx-phpNginx+PHP-FPM5.5,5.6,7.0(NG),CentOS...76[OK]maxexcloo/nginx-phpFrameworkcontainerwithnginxandPHP-FPM...58[OK]webdevops/php-nginxNginxwithPHP-FPM51[OK]

RÉCUPÉRERUNEIMAGEFaireunpullpourrécupérerl’imageenlocal.

Elleseraensuiteutilisablepourcréerunconteneuravec

dockerrun

NB:dockerrunfaitunpullsil’imagen’estpasdisponibleen

local

$dockerpullnginxUsingdefaulttag:latestlatest:Pullingfromlibrary/nginx709f78077458:Pullcomplete5f5490fb32ee:Pullcomplete

LISTERLESIMAGESImagesdisponibleslocalement

$dockerimagesREPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZEdebianlatest93a2e30f10003daysago123MBnginxlateste8b9e1a0dfbe7daysago183.5MBhello-worldlatest95f1eedc264a11weeksago1.848kB

TAGSLesimagespeuventavoirdestags

Untagdéfinirauneversion,unevariantedifférented’une

image

pardéfautletagestlatest:

dockerrunubuntu==dockerrunubuntu:latest

Untagestjusteunalias,unsurnompourunidentifiant

d’image

plusieurstagsdifférents==uneimage

ex:ubuntu:latest==ubuntu:16.04

EXEMPLE$dockerimagesdebianREPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZEdebianlatest93a2e30f10004daysago123MBdebian8.5f854eed3f31f3monthsago125.1MBdebian8.432f2a4cccab85monthsago125MBdebian8.2140f9bdfeb978monthsago125.1MB

EXEMPLETAG$dockertagdebianbenedetti/debian:8.6dockerimages|grepdebiandebianlatest93a2e30f10004daysago123MBbenedetti/debian8.693a2e30f10004daysago123MBdebian8.5f854eed3f31f3monthsago125.1MBdebian8.432f2a4cccab85monthsago125MBdebian8.2140f9bdfeb978monthsago125.1MB

CRÉATIONUSUELLED’IMAGESDeuxméthodes:

dockercommit:

sauvegardelesmodificationsapportéesàunconteneur

dansunenouvellecouche

créel’image

dockerbuild:

séquenced’instructionsrépétables,

Dockerfile

Méthoderecommandée

CRÉATIOND’IMAGEINTERACTIVEinteractive==manuellement:

Onlanceunshelldansconteneur

Onfaitlesmodificationsvoulues:

ajoutdepaquets,defichiers,etc..

Oncommitcesmodificationsenimage

Onpeutéventuellementtaggerl’image

ENPRATIQUEInstallationdeNginx

$dockerrun-itdebian/bin/bashroot@05739348bc4e:/#root@05739348bc4e:/#aptupdate&&aptinstall-ynginx

VALIDATIONENUNECOUCHE$dockercommit05739348bc4e4f98b27dcc19d60c913ba29516bc31c9b0c80d2ebfdd28f99f43521db3caffed

UTILISATIONDENOTREIMAGEdockerrun-it4f98b27dcc19d60c/bin/bashroot@9fc1ee35e2a4:/#nginx-vnginxversion:nginx/1.6.2

TAGGERNOTREIMAGE$dockertag4f98b27dcc19d6benedetti/nginx$dockertagbenedetti/nginxbenedetti/nginx:0.1$dockerimagesbenedetti/nginxREPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZEbenedetti/nginx0.14f98b27dcc1912minutesago194.3MBbenedetti/nginxlatest4f98b27dcc1912minutesago194.3MB$dockerrun-itbenedetti/nginxnginx-vnginxversion:nginx/1.6.2

HISTORIQUEDENOTREIMAGE$dockerhistorybenedetti/nginxIMAGECREATEDCREATEDBYSIZECOMMENT4f98b27dcc1914minutesago/bin/bash71.33MB93a2e30f10004daysago/bin/sh-c#(nop)CMD["/bin/bash"]0Bd5daf556aca74daysago/bin/sh-c#(nop)ADDfile:cae7a35a0d8c43d5ba123MB

CRÉATIONINTERACTIVEIntérêt

manipulationusuelle

bienpourtesterrapidementquelquechose

Désavantage

Manuelle

Nonrépétable

CRÉATIONAUTOMATISÉED’IMAGEEcrireunDockerfile

Créerl’imageàpartirduDockerfile

DOCKERFILEPrincipe:

Recetteautomatiséedecréationd’images

Contientunesuited’instructions

LacommandedockerbuildutiliseleDockerfilepourcréer

l’image

NOTREPREMIERDOCKERFILEOntravailledansundossierquivacontenirleDockerfile

propreànotrefutureimage:

OnseplacedanscedossieretonouvreunfichierDockerfile

ContenuduDockerfile:

$mkdir-p~/docker/nginx

$cd~/docker/nginx/$editDockerfile

FROMdebianRUNapt-getupdateRUNapt-getinstall-ynginx

INSTRUCTIONSUnDockerfileestcomposéd’instruction,uneparligne.

FROM:imagedebaseàutiliserpournotrefutureimage

UnseulFROMparDockerfile

RUN:commandeshellàexécuter

serontexécutéesdurantleprocessusdebuild

utilisableàvolonté

non-interactive:aucuninputpossibledurantlebuild

BUILDIT!DepuisledossiercontenantleDockerfile

$dockerbuild-tbenedetti/nginx:0.2.SendingbuildcontexttoDockerdaemon2.048kBStep1:FROMdebian--->93a2e30f1000Step2:RUNapt-getupdate--->Runningin20f50a8284f5Get:1http://security.debian.orgjessie/updatesInRelease[63.1kB]...Processingtriggersforsgml-base(1.26+nmu4)...--->95f9e15fa8d2Removingintermediatecontainere99f0c6f5bd2Successfullybuilt95f9e15fa8d2

EXÉCUTIONL’imageobtenuepermetdedémarrerunconteneur,de

manièresimilaireàcellecrééemanuellement:

$dockerrun-itbenedetti/nginx:0.2nginx-vnginxversion:nginx/1.6.2

CMDAvecl’instructionCMD,onpeutdéfinirunecommandeà

exécuterpardéfautlorsquel’onlanceunconteneur.

Parexemple:

$dockerrun-itbenedetti/nginxnginxversion:nginx/1.6.2

UTILISATIONDECMDFROMdebianRUNapt-getupdateRUNapt-getinstall-ynginxCMDnginx-v

BUILDETTESTDECMD$dockerbuild-tbenedetti/nginx:0.3.$dockerrun-itbenedetti/nginx:0.3nginxversion:nginx/1.6.2

ENTRYPOINTDéfinitunecommandedebaseàexécuterparle

conteneur,

Lesparamètresdelalignecommandesontajoutésàces

paramètres.

UTILISATIONDEENTRYPOINTFROMdebianRUNapt-getupdateRUNapt-getinstall-ynginxENTRYPOINT["nginx","-g"]

BUILDAVECENTRYPOINT$dockerbuild-tbenedetti/nginx:0.4.

EXÉCUTIONDEENTRYPOINT

Depuisunautreterminal:

$dockerrun-itbenedetti/nginx:0.4"parambidon;"nginx:[emerg]unknowndirective"param"incommandline$dockerrun-itbenedetti/nginx:0.4"daemonoff;"#nginxs'exécuteenavantplan

$dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES29e86a41e506benedetti/nginx:0.4"nginx-g'daemonoff"AboutaminuteagoUpAboutaminutefurious_mcclintock'"

CMDETENTRYPOINTFROMdebianRUNapt-getupdateRUNapt-getinstall-ynginxENTRYPOINT["nginx","-g"]CMD["daemonoff;"]

BUILDCMDETENTRYPOINT$dockerbuild-tbenedetti/nginx:0.5.

EXÉCUTIONCMDETENTRYPOINT

Nousavonsunnginxquitourne:commentyaccéder?

$dockerrun-dbenedetti/nginx:0.510bb961dfe60fc4c92b45f6a1a390f62f7edc0f6d78fe2088a0cf08c6d6cb040

EXPOSERLESPORTSD’UNCONTENEURTouslesportssontprivéspardéfaut

Unportprivén’estpasaccessibledel’extérieur

C’estauclientàrendrepublicsounonlesportsexposés

Public:accessiblepard’autresconteneursetendehors

del’hôte.

EXPOSERUNPORTVIALACLI$dockerrun-d-p8080:80benedetti/nginx:0.5

$dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES0ed02461dc0ebenedetti/nginx:0.5"nginx-g'daemonoff"37secondsagoUp32seconds0.0.0.0:8080->80/tcpserene_stallman

ACCÈSWEB

ACCÈSCLI$curllocalhost:8080<!DOCTYPEhtml><html><head><title>WelcometonginxonDebian!</title>etc..

EXPOSEInstructionDockerfilequiindiqueàDockerquel(s)port(s)

publierpournotreimage.

Cesportsserontautomatiquementexposésavecl’option-P

aulancementd’unconteneur.

EXPOSEETDOCKERFILEFROMdebianRUNapt-getupdateRUNapt-getinstall-ynginxEXPOSE80443ENTRYPOINT["nginx","-g"]CMD["daemonoff;"]

BUILDAVECEXPOSE$dockerbuild-tbenedetti/nginx:0.6.

EXÉCUTIONAVEC-P$dockerrun-it-P-dbenedetti/nginx:0.6e1696c7edeaf6c68893244e6dee10950e1829cd43a9bbc6b5abf04a5db31b341

$dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESe1696c7edeafbenedetti/nginx:0.6"nginx-g'daemonoff"5secondsagoUp2seconds0.0.0.0:32772->80/tcp,0.0.0.0:32771->443/tcpclever_bartik

$dockerporte1696c7edeaf443/tcp->0.0.0.0:3277180/tcp->0.0.0.0:32772

$dockerporte1696c7edeaf800.0.0.0:32772

TESTDEEXPOSE$curlhttp://localhost:32772<!DOCTYPEhtml><html><head><title>WelcometonginxonDebian!</title><style>

COPYL’instructionCOPYpermetdecopierfichiersetdossiers

depuislecontextedegénération,dansleconteneur.

Imaginonsquel’onveuillemodifierlapaged’accueildenotre

serveurNginx?

DOCKERFILEAVECCOPY$echo"BienvenuesurmonimageNginx">index.html

FROMdebianRUNapt-getupdateRUNapt-getinstall-ynginxEXPOSE80443COPYindex.html/var/www/html/index.htmlENTRYPOINT["nginx","-g"]CMD["daemonoff;"]

BUILDAVECCOPY$dockerbuild-tbenedetti/nginx:0.7.

TESTDECOPY$dockerrun-it-P-dbenedetti/nginx:0.787987bf2e06f0d14dcbf6d9d65eabb5adc34b5b56bc95f195b564b52de6f0a39

$dockerport87987bf2800.0.0.0:32776

$curlhttp://localhost:32776BienvenuesurmonimageNginx

VOLUMESProblèmes:

Sijeveuxmodifierindex.html,jedoisregénéreruneimage

laborieuxsurtoutenphasedetest

Nginxgénéredeslogs

Cesmodificationsengendrentdesdonnéesdansune

couche

Jevoudraislespartageravecunautreserveur

VOLUMELesvolumespeuventêtrepartagés:

entreconteneurs

entrehôteetunconteneur

Lesaccèsausystèmedefichiersviaunvolume

outrepassentleCoW:

Meilleuresperformances

Nesontpasenregitrésdansunecouchepournepasêtre

enregistrésparundockercommit

NOTREPREMIERVOLUME$dockerrun-d-v$(pwd):/var/www/html-Pbenedetti/nginx:0.786bc6648b0bb2423adbb20c7dcdd6b3b27d2c4c5670a9330cc7571c2ec35be42

$dockerexec-it86bc6648b0bb2423adbb20c7dls/var/www/htmlDockerfileindex.html

$dockerport86bc6648b0bb2423800.0.0.0:32780

$curlhttp://localhost:32780BienvenuesurmonimageNginx

$echo"Miseàjourdufichierindex.html">index.html

$curlhttp://localhost:32780Miseàjourdufichierindex.html

PARTAGERUNDOSSIERD’UNCONTENEURVIAUNVOLUME

Demanièreinteractive

$dockerrun-P-v/var/log/nginx-dbenedetti/nginx:0.734938297dcde666df6e724e4d7bf752d6eb94f23cdbb1f253599985b4ae23266

$dockerrun-it--volumes-from34938297dcde666ddebianls/var/log/nginxaccess.logerror.log

CRÉATIONDEVOLUMENOMMÉ$dockervolumecreate--name=logslogs

$dockerrun-P-vlogs:/var/log/nginx-dbenedetti/nginx:0.7055ac104acf1d734ae38005e96512f666cbe483b1db87b653648d045c2c1a744

$dockerrun-it--volumes-from055ac104acf1d73debianls/var/log/nginxaccess.logerror.log

PERSISTENCELesvolumesexistentindépendammentdesconteneurs

Siunconteneureststoppé,sesvolumessontencore

disponibles

Vousêtesresponsabledelagestion,delasauvegardedes

volumes

LISTERLESVOLUMES

Onpeutmontercesvolumesdepuisunautreconteneur

dockervolumelsDRIVERVOLUMENAMElocal57a0848c5e5f2924be84a66157e84e830757922c7b5b856aa5bac12e494da495locallogs

MÉNAGEVOLUME$dockerrm055ac104acf1d734$dockervolumels-fdangling=true|greplogs$dockervolumermlogs

RÉFÉRENCESDocumentationofficielle

Vidéosd’apprentissageofficielles

JérômePetazzoni-IntroductiontoDockerandcontainers

-PyCon2016

JérômePetazzoni:Cgroups,namespaces,andbeyond:

whatarecontainersmadefrom?-PyCon2016

ORCHESTRATIONDOCKERBenoîtBenedetti

COMMENTORCHESTRERDESCONTENEURSAVEC

DOCKER

RAPPELSNousavonsvu:

Cequ’estunconteneur

Cequ’estDocker

Commentlancerunconteneur

Commentgérerlesimages

Commentexposerdesportsd’unconteneur

Commentpartagerdesdonnéesavecdesvolumes

PROBLÉMATIQUESJusqu’àprésent,nousavonstravailléavecuneapplication

monolithique,surunseulhôteDocker.

Nousvoulonsdéployeretgérerdesapplicationsdetype

micro-services,surplusieurshôtes.

PLANDECETTESÉANCE

Réseau

DockerCompose

DockerMachine

DockerSwarm

COMPOSE

BILAN

Onsaitcréerdesimages

demanièremanuelle

demanièreautomatisée

Onsaitlancerdesconteneurs

partagerlesdonnéesavecdesvolumes

lesinterconnectersurleréseau

PROBLÈME

Onveutcoordonnerdesconteneurs

Onveutsimplifierlagestionmulti-conteneurs

Onneveutpasutiliserdescriptsshellcomplexes

Onveutuneinterfacestandardiséeavecl’APIDocker

COMMENTFAIREPOUR

Gérerlesdeuxconteneursàlavolée?

Gérerdesvolumes?

Gérerdesportsdifférents?

Mesouvenirdecescommandes?

SOLUTIONComposevouspermetd’éviterdegérerindividuellementdes

conteneursquiformentlesdifférentsservicesdevotre

application.

Outilquidéfinitetexécutedesapplicationsmulti-

conteneurs

Utiliseunfichierdeconfigurationdanslequelvous

définissezlesservicesdel’application

Al’aided’unesimplecommande,vouscontrôlezlecyclede

viedetouslesconteneursquiexécutentlesdifférents

servicesdel’application.

UTILISATION

Vousdéfinissezl’environnementdevotreapplicationpour

qu’ilsoitpossibledelagénérerden’importeoù

àl’aidedeDockerfile

àl’aided’imageofficielle

Vousdéfinissezvosservicesdansunfichierdocker-

compose.ymlpourlesexécuteretlesisoler.

Exécutezdocker-composequisechargerad’exécuter

l’ensembledevotreapplication

SERVICESComposeintroduitunenotiondeservice:

Concrétement,unconteneurexécutantunprocessus

Chaqueconteneurexécuteunserviceinter-dépendant

Leservicepeut-êtreévolutifenlançantplusoumoins

d’instancesduconteneuravecCompose.

ExempleWordpress:

Servicedb

Servicewordpress

EXEMPLEDOCKER-COMPOSE.YMLversion:'2'services:db:image:mysql:5.7volumes:-"./.data/db:/var/lib/mysql"restart:alwaysenvironment:MYSQL_ROOT_PASSWORD:wordpressMYSQL_DATABASE:wordpressMYSQL_USER:wordpressMYSQL_PASSWORD:wordpress

wordpress:depends_on:-dbimage:wordpress:latestlinks:-dbports:-"8000:80"restart:alwaysenvironment:WORDPRESS_DB_HOST:db:3306WORDPRESS_DB_PASSWORD:wordpress

DÉMARRAGED’UNEAPPLICATION

Lesdifférentsservicesquicomposentmonapplicationont

étédémarrés,aveclaconfigurationetl’environnementquiva

bien.

$docker-composeup-dCreatingwordpress_db_1Creatingwordpress_wordpress_1

INFORMATIONDEMONAPPLICATIONOnutiliselacommandepsdeCompose:

$docker-composepsNameCommandStatePorts-------------------------------------------------------------------------------------wordpress_db_1docker-entrypoint.shmysqldUp3306/tcpwordpress_wordpress_1/entrypoint.shapache2-for...Up0.0.0.0:8000->80/tcp

$docker-composepswordpressNameCommandStatePorts-------------------------------------------------------------------------------------wordpress_wordpress_1/entrypoint.shapache2-for...Up0.0.0.0:8000->80/tcp

CONTENEURSCLASSIQUESLesservicess’exécutentviadesconteneurssurl’hôte.Les

commandesdockerclassiquessonttoujoursfonctionnelles.

$dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES8d086aeba614wordpress:latest"/entrypoint.shapach"7minutesagoUp7minutes0.0.0.0:8000->80/tcpwordpress_wordpress_1689405bb755dmysql:5.7"docker-entrypoint.sh"7minutesagoUp7minutes3306/tcpwordpress_db_1

LOGSLogsd’uneapplication:

Logsd’unservice

$docker-composelogs

$docker-composelogsdb

PASSAGEÀL’ÉCHELLEOnpeutpasseràl’échelleunservice.Autrementdit,onpeut

augmenter/diminuerlenombredeconteneursexécutantun

service

Pardéfaut,Composeexécutechaqueserviceavecun

conteneur.

SCALEOnutiliselacommandescalepourchangerlenombrede

réplicasd’unservice:

$docker-composescaledb=3$docker-composepsdbNameCommandStatePorts---------------------------------------------------------------wordpress_db_1docker-entrypoint.shmysqldUp3306/tcpwordpress_db_2docker-entrypoint.shmysqldUp3306/tcpwordpress_db_3docker-entrypoint.shmysqldUp3306/tcp$docker-composescaledb=2

CYCLEDEVIE$docker-composeup$docker-composestop#oukill$docker-composestart$docker-composerestart$docker-composerm$docker-composedown#==stop+rm

RÉSUMÉCOMPOSE

Composeestunoutilpourdéfinir,lanceretgérerdes

servicesquisontdéfiniscommeuneouplusieursinstances

d’unconteneur,

ComposeutiliseunfichierdeconfigurationYAMLcomme

définitiondel’environnement,

Avecdocker-composeonpeutgénérerdesimages,lancer

etgérerdesservices,…

Certainescommandesdedocker-composesont

équivalentesàl’outildocker,maiss’appliquentseulement

auxconteneursdelaconfigurationdecompose.

SWARM

PROBLÈMEVousavezplusieurshôtesDocker.

Vousdésirezlesutilisersousformedecluster,etrépartirde

manièretransparentel’exécutiondeconteneur.

SOLUTIONDockerEngine1.12inclutlemodeswarmpournativement

gérerunclusterdeDockerEnginesqu’onnommeunswarm

(essaim).

OnutiliselaCLIDockerpourcréerunswarm,déployerdes

serviced’applicationsurunswarm,etgérerlecomportement

devotreswarm.

MODESWARM

Lesfonctionnalitésdegestionetorchestrationdecluster

inclusesdansleDockerEngine.

LesMoteursDockerparticipantàunclusters’exécutenten

modeswarm.

Unswarm(essaim)estunclusterdeDockerEnginessur

lequelvousdéployezdesservices.

LaCLIDockerinclutlagestiondesnoeudsd’unswarm

ajoutdenoeuds,

déploiementdeservices,

gestiondel’orchestrationdesservices

NOEUDUnnoeudestuneinstanceDockerEngineparticipantàun

swarm.

Noeuddetypemanager:

déploielesapplicationssuivantlesdéfinitionsde

servicesquevousluisoumettez,

dispatchelestâchesaunoeuddetypeworker,

Gestionducluster,orchestration

Unleaderestchoisiparmilesmanagerspourgérerles

tâchesd’orchestration

NoeudWorker:

SERVICESETTÂCHES

Unserviceestladéfinitiondetâchesàexécuterparles

workers

exécutiond’unecommandeviaunconteneur

utiliseuneimage

deuxmodesd’exécutiondeservice:

repliqué:unmanagerdistribueunnombredonnéde

tâchessurchaquenoeud

global:exactementunetâcheestexécutéparnoeud

tâche:unitéatomiqued’exécutiond’unswarm

représenteleconteneuretlacommandeàyexécuter

DIAGRAMMEDESSERVICESETTÂCHES

RÉPARTITIONDECHARGE

Lemanagerutiliseunerépartitiondechargeverstousles

workerspourexposerlesportsdesservices

Leportrendupublicestégalementaccessiblesurtout

workerduswarm

ChaqueserviceduswarmàsonproprenomDNSinterne:

Lemanagerutiliseunerépartitiondechargeinterne

pourdistribuerlesrequêtesdesservicesducluster.

COMMANDENODE

Unclusterestinitialiséavecdockerswarminit.Aexécuter

unefoissurunhôte.

$dockernodelsErrorresponsefromdaemon:Thisnodeisnotaswarmmanager.[...]

CRÉERNOTRESWARM

Danslasortiedelacommande,unmessagenousindiquela

commandeàexécuterpourajouterunworkerànotre

nouveauswarm.

$dockerswarminit--advertise-addr<MANAGER-IP>Swarminitialized:currentnode(8jud...)isnowamanager.Toaddaworkertothisswarm,runthefollowingcommand:dockerswarmjoin\--tokenSWMTKN-1-59fl4ak4nqjmao1ofttrc4eprhrola2l87...\172.31.4.182:2377

VÉRIFIERL’ÉTATDENOTRESWARMOnutiliselaclassiquecommandedockerinfo:

$dockerinfoSwarm:activeNodeID:8jud7o8dax3zxbags3f8yox4bIsManager:trueClusterID:2vcw2oa9rjps3a24m91xhvv0c

PREMIÈRECOMMANDEENMODESWARMPourvoirlesinformationsdesnoeudsduswarm:

$dockernodelsIDHOSTNAMESTATUSAVAILABILITYMANAGERSTATUS8jud...ox4b*ip-172-31-4-182ReadyActiveLeader

SOUSLECAPOTlorsdudockerswarminit,uncertificatRacineTLSaétécréé.

Puisunepairedecléspournotrepremiernoeud,signéeavec

lecertificat.

Pourchaquenouveaunoeudseracrééesapairedeclésignée

aveclecertificat.

TouteslescommunicationssontainsichiffréesenTLS.

TOKENDockeragénéré2tokensdesécurité(équivalentd’une

passphraseoupassword)pournotrecluster,àutiliserlorsde

l’ajoutdenouveauxnoeuds:

Untokenpourlesworkers

Untokenpourlesmanagers

Récupérationdestokens:

$dockerswarmjoin-tokenworker$dockerswarmjoin-tokenmanager

AJOUTD’UNWORKERAUCLUSTERSeconnecteràunautreserveurDocker:

$dockerswarmjoin\--tokenTOKEN-WORKER...\172.31.4.182:2377

CLUSTERDE2NOEUDS$dockernodelsIDHOSTNAMESTATUSAVAILABILITYMANAGERSTATUS8jud...ox4b*ip-172-31-4-182ReadyActiveLeaderehb0...4fvxip-172-31-4-180ReadyActive

AJOUTD’UNMANAGER$dockerswarmjoin\--tokenTOKEN_MANAGER...\172.31.4.182:2377

CLUSTERDE3NOEUDS$dockernodelsIDHOSTNAMESTATUSAVAILABILITYMANAGERSTATUS8jud...ox4b*ip-172-31-4-182ReadyActiveLeaderabcd...1234ip-172-31-4-181ReadyActiveManagerehb0...4fvxip-172-31-4-180ReadyActive

PROMOUVOIRUNWORKERENMANAGER

Inverse:demote

$dockernodepromoteNODE

QUITTERUNSWARM$dockerswarmleavenode-2$dockernodermnode-2

EXÉCUTERUNSERVICEOnutiliselacommandeservicesurunmanagerenmode

Swarm:

$dockerservicecreate--replicas1--namehelloworldalpinepingdocker.com9uk4639qpg7npwf3fn2aasksr

LISTERLESSERVICES$dockerservicelsIDNAMESCALEIMAGECOMMAND9uk4639qpg7nhelloworld1/1alpinepingdocker.com

PSExécutezpspoursavoirsurquelnoeuds’exécutelatâche

d’unservice:

$dockerservicepshelloworld

IDNAMESERVICEIMAGELASTSTATEDESIREDSTATENODE8p1vev3fq5zm0mi8g0as41w35helloworld.1helloworldalpineRunning3minutesRunningworker2

PASSAGEÀL’ÉCHELLEOnutilisescale

$dockerservicescale<SERVICE-ID>=<NUMBER-OF-TASKS>

EXEMPLE$dockerservicescalehelloworld=5helloworldscaledto5

$dockerservicepshelloworld

IDNAMESERVICEIMAGELASTSTATEDESIREDSTATENODE8p1vev3fq5zm0mi8g0as41w35helloworld.1helloworldalpineRunning7minutesRunningworker2c7a7tcdq5s0uk3qr88mf8xco6helloworld.2helloworldalpineRunning24secondsRunningworker16crl09vdcalvtfehfh69ogfb1helloworld.3helloworldalpineRunning24secondsRunningworker1auky6trawmdlcne8ad8phb0f1helloworld.4helloworldalpineRunning24secondsAssignedmanager1ba19kca06l18zujfwxyc5lkynhelloworld.5helloworldalpineRunning24secondsRunningworker2

CYCLEDEVIESivousêtesassezrapide,vouspourrezvoirlesdifférents

étatsd’unetâche:

assigned:latâcheaétéassignéeàunnoeud,

preparing:récupérationdel’image

running

failed

CYCLEDEVIE

MODEGLOBALPardéfautlemoderépliquéestutilisé.Pourpasserenmode

global:

Chaqueworkerexécuteraunseulréplicaduservice

Pourchaquenouveauworkerajouté,leréplicasera

automatiquementdémarré

$dockerservicecreate--namemyservice--modeglobalalpinetop

ROLLINGUPDATEMettreàjourunservice

$dockerserviceupdate--imagenginx:3.0.7nginx

MISESÀJOURLemanagervaappliquerlamiseàjourduserviceaunoeud:

Arrêtdelatâche

miseàjourd’unetâchearrêtée

démarrageduconteneurdelatâchemiseàjour

attendreuncertaindélaiavantdepasseràl’autretâche

etc,

Siunetâcheestenéchec,interromprelamiseàjour.

STRATÉGIEDEMISEÀJOURVouspouvezconfigurerleparallélismedesmisesàjour,etun

délaid’exécutionentrechaquemiseàjourdetâche:

$dockerserviceupdateworker--update-parallelism2--update-delay5s

MODEMAINTENANCEPardéfaut,toutnoeudestACTIVE.Maisvouspouvezpasser

unnoeudenmodemaintenance:

$dockernodeupdate--availabilitydrainworker1

SORTIEDEMAINTENANCE$dockernodeupdate--availabilityactiveworker1

SUPPRIMERUNSERVICE$dockerservicermhelloworld

POURCONCLURE

SwarmestunmoyendeconsolidervoshôtesDocker

Moyensimplecompatibleavecl’APIdeDocker

Beaucoupdefonctionnalitésencoreenbeta