39
Docker on Ubuntu Friday, August 4, 2017 1:48 PM Install and configure Docker, along with deploying and managing Linux-based containers, on an Ubuntu server.

Docker on Ubuntu - Azure Workshops on... · Docker on Ubuntu Friday, August 4, 2017 1:48 PM Install and configure Docker, along with deploying and ... , choose Ubuntu Server 16.04

Embed Size (px)

Citation preview

DockeronUbuntuFriday,August4,20171:48PM

InstallandconfigureDocker,alongwithdeployingandmanagingLinux-basedcontainers,onanUbuntuserver.

ThisisashortworkshoptointroduceyoutoLinux-basedcontainers.Inthisworkshop,youwillgainexperienceininstallingandconfiguringDockeronanUbuntuserver.You'llthendeployacoupleofdifferentimagesascontainerstotheserverandexperimentwithmanagingthoseimagesandcontainers.Finally,youwillconfigureAzuretoallowyoutoaccessthosecontainersfromoutsideofyourvirtualnetwork.

WhatYouWillLearnInstallingandConfiguringDockeronUbuntuDownloadingandManagingImagesDeployingandWorkingWithContainersExposingDockerServicesinAzure

IdealAudienceITManagersDevelopersandSoftwareArchitectsConfigurationandChangeManagersDevOpsEngineers

ThisisashortworkshoptointroduceyoutoLinux-basedcontainers.Inthisworkshop,youwillgainexperienceininstallingandconfiguringDockeronanUbuntuserver.You'llthendeployacoupleofdifferentimagesascontainerstotheserverandexperimentwithmanagingthoseimagesandcontainers.Finally,youwillconfigureAzuretoallowyoutoaccessthosecontainersfromoutsideofyourvirtualnetwork.

TimeEstimate:2.5hours

Overview

SetupRequirementsThefollowingworkshopwillrequirethatyouuseaTelnet/SSHclientinordertoconnecttoaremotemachine.IfyoudonothaveaSSHclient,thenPuTTYwillworkfine.Dependingonyourenvironment,downloadtheexecutableinastandalonefile(.EXE)oraninstallablepackage(.MSI),eitherina32-bitor64-bit.

AdditionalRequirementsForthefollowingworkshop,youwillneedasubscription(trialorpaid)toMicrosoftAzure.Pleaseseethenextpageforhowtocreateatrialsubscription,ifnecessary.

Requirements

AzureWeneedanactiveAzuresubscriptioninordertoperformthisworkshop.Thereareafewwaystoaccomplishthis.IfyoualreadyhaveanactiveAzuresubscription,youcanskiptheremainderofthispage.Otherwise,you'lleitherneedtouseanAzurePassorcreateatrialaccount.Theinstructionsforbotharebelow.

AzurePassIfyou'vebeenprovidedwithavoucher,formallyknownasanAzurePass,thenyoucanusethattocreateasubscription.InordertousetheAzurePass,directyourbrowsertohttps://www.microsoftazurepass.comand,followingtheprompts,usethecodeprovidedtocreateyoursubscription.

TrialSubscriptionDirectyourbrowsertohttps://azure.microsoft.com/en-us/free/andbeginbyclickingonthegreenbuttonthatreadsStartfree.

1. Inthefirstsection,completetheforminitsentirety.Makesureyouuseyourrealemailaddressfortheimportantnotifications.

2. Inthesecondsection,enterarealmobilephonenumbertoreceiveatextverificationnumber.Clicksendmessageandre-typethereceivedcode.

3. Enteravalidcreditcardnumber.NOTE:Youwillnotbecharged.Thisisforverificationofidentityonlyinordertocomplywithfederalregulations.Youraccountstatementmayseeatemporaryholdof$1.00fromMicrosoft,but,again,thisisforverificationonlyandwill"falloff"youraccountwithin2-3bankingdays.

4. AgreetoMicrosoft'sTermsandConditionsandclickSignUp.

Thismaytakeaminuteortwo,butyoushouldseeawelcomescreeninformingyouthatyoursubscriptionisready.LiketheOffice365trialabove,theAzuresubscriptionisgoodforupto$200ofresourcesfor30days.After30days,yoursubscription(andresources)willbesuspendedunlessyouconvertyourtrialsubscriptiontoapaidone.And,shouldyouchoosetodoso,youcanelecttouseadifferentcreditcardthantheoneyoujustentered.

AzureRegistration

Congratulations!You'venowcreatedanOffice365tenant;anAzuretenantandsubscription;and,havelinkedthetwotogether.

ObjectiveThefirstobjectiveisforyoutobecomefamiliarwithconnectingtoandnavigatingtheAzureportal.Thiswillnotbeadifficultexercise,butwillnonethelessdemonstratehowtoworkwithintheAzureuserinterface.

AzurePortalBasicsLet'sstartbyconnectingtotheAzureportalandbecomingfamiliarwithnavigation.

1. Openabrowserandnavigatetohttp://www.azure.com.

2. Inthetop-rightcornerofyourscreen,youwillseethemenuoptionPORTAL.Clickonit.

3. Ifyouhavenotalready,youwillberequiredtoauthenticate.

4. Afterauthenticationissuccessful,youwillbedirectedtoyourDashboard.Thedashboardisconfigurablebyadding,removingandresizingtiles.Additionally,youcanhavemultipledashboardsdependingonyourpreferences.Youcouldhavedifferentdashboardsforresourcesdedicatedtodifferentfunctions,linesofbusiness,orforoperations.

5. Ontheleftwillbeyourprimarynavigationalmenu.Youshouldseealistoffavoritedservicesonthemenuwithdescriptions.(NOTE:Thenumberofoptionslistedinyourmenumaydifferfromthatofothersdependingonthenumberofservicesyouhaveselectedasafavorite.)Ifallyouseeareicons(nodescriptions)onyourmenu,yourmenuiscurrentlycollapsed.Clickthe"hamburger" toexpandit.

6. Prettyclosetothetopofyourmenu,youshouldseeResourceGroups .Clickthisoption.

7. UponclickingtheResourceGroupsmenuitem,abladewillopenrevealinganycreatedresourcegroups.InordertocreateresourcesinAzure,youmustassign/placeitinaresourcegroup.

Thisiswherewewillgetstartedcreatingourresources.

Whilethisintroductionwasn'ttootechnical,itissufficientforgettingustoapointwherewecanbeginthespecificsintheworkshop.Ifyou'dliketolookaroundabitmore,clickafewoftheotheroptionsinthemainmenu.Then,whenyouareready,canyouproceedtothenextstep.

ExploringAzure

ObjectiveNowthatwe'veexploredtheAzureportalabit,let'sgetstartedwithcreatingsomeresources.OurprimaryresourcewillbeavirtualmachineonwhichweinstallDocker.Oncewecreatethevirtualmachine,we'llseethatsomeadditionalresourcesarecreatedforus.

CreateaResourceGroupAsstatedonthepreviouspage,inordertocreateresources,weneedaResourceGrouptoplacethemin.

1. Ifyouarenottherealready,goaheadandclickontheResourceGroups intheAzurePortaltoopentheResourceGroupsblade.

2. AtthetopoftheResourceGroupsblade,clickonAdd .Thiswillopenapanelthatasksforsomebasicconfigurationsettings.

3. Completetheconfigurationsettingswiththefollowing:

Resourcegroupname:azworkshops_docker_ubuntu_demoSubscription:<chooseyoursubscription>Resourcegrouplocation:<chooseyourlocation>

4. <Optional>CheckPintodashboardatthebottomofthepanel.

5. ClickCreate.

6. Itshouldonlytakeasecondfortheresourcegrouptobecreated.Onceyouclickcreate,theconfigurationpanelclosesandreturnsyoutothelistofavailableresourcegroups.Yourrecentlycreatedgroupmaynotbevisibleinthelist.ClickingonRefresh atthetopoftheResourceGroupsbladeshoulddisplayyournewresourcegroup.

NOTE:Whenyoucreatearesourcegroup,youarepromptedtochoosealocation.Additionally,asyoucreateindividualresources,youwillalsobepromptedtochooselocations.Thelocationofresourcegroupsandtheirresourcescanbedifferent.Thisisbecauseresourcegroupsstoremetadatadescribingtheircontainedresources;and,duetosometypesofcompliancethatyourcompanymayadhereto,youmayneedtostorethatmetadatainadifferentlocationthantheresourcesthemselves.Forexample,ifyouareaUS-basedcompany,youmaychoosetokeepthemetadatastate-sidewhilecreatingresourcesinforeignregionstoreducelatencyfortheend-user.

CreateaVirtualMachine

CreateaVirtualMachineNowthatwehaveanavailableresourcegroup,let'screatetheactualUbuntuserver.

1. Ifyouarenottherealready,goaheadandnavigatetotheazworkshops_docker_ubuntu_demoresourcegroup.

2. Atthetopofthebladeforourgroup,clickonAdd .ThiswilldisplaythebladefortheAzureMarketplaceallowingyoutodeployanumberofdifferentsolutions.

3. WeareinterestedindeployinganUbuntuserver.Therefore,intheSearchEverythingbox,typeinUbuntuServer.Thiswilldisplayacoupleofdifferentversions.SincewewanttodeploythelateststableversionofUbuntu,fromthedisplayedoptions,chooseUbuntuServer16.04LTS.

4. Thiswilldisplayabladeprovidingmoreinformationabouttheserverwehavechosen.Tocontinuecreatingtheserver,chooseCreate.

5. Wearenowpromptedwithsomeconfigurationoptions.Thereare3sectionsweneedtocompleteandthelastsectionisasummaryofourchosenoptions.

1. Basics

Name:docker-ubuntuVMdisktype:SSDUsername:localadminAuthenticationtype:Password(NOTE:YoucanchooseSSHifyouarefamiliarwithhowtosetthisup.Ifyouarenot,wewilldothisinalaterworkshop.However,forthisworkshop,Passwordauthenticationissufficient.)Password:Pass@word1234Confirmpassword:<sameasabove>Subscription:<chooseyoursubscription>Resourcegroup:Useexisting-azworkshops_docker_ubuntu_demoLocation:<choosealocation>

2. Size

DS1_V23. Settings

Usemanageddisks:No

Storageaccount:(clickonit&CreateNew)

Name:dockerubuntudata<randomnumber>(ex.dockerubuntudata123456)(NOTE:Thisnamemustbegloballyunique,soitcannotalreadybeused.)Performance:PremiumReplication:Locally-redundantstorage(LRS)

Virtualnetwork:<acceptdefault>(e.g.(new)azworkshops_docker_ubuntu_demo-vnet)

Subnet:<acceptdefault>(e.g.default(172.16.1.0/24))

PublicIPaddress:<acceptdefault>(e.g.(new)docker-ubuntu-ip)

Networksecuritygroup(firewall):<acceptdefault>(e.g.(new)docker-ubuntu-nsg)

Extensions:Noextensions

Availabilityset:None

Bootdiagnostics:Enabled

GuestOSdiagnostics:Disabled

Diagnosticsstorageaccount:(clickonit&CreateNew)

Name:dockerubuntudiags<randomnumber>(ex.dockerubuntudiags123456)Performance:StandardReplication:Locally-redundantstorage(LRS)

4. Summary(justclickOKtocontinue)

Thismachineisrelativelysmall,butwithcontainers,itcanstilldeliversomeprettyimpressiveperformance.Oncescheduled,itmaytakeaminuteortwoforthemachinetobecreatedbyAzure.Onceithasbeencreated,Azureshouldopenthemachine'sstatusbladeautomatically.

ConnecttotheVirtualMachineOnceyourmachinehasbeencreated,wecanremotelyconnecttoitusingsecureshell(SSH).TheseinstructionsassumethatyoudonothavestrongfamiliaritywithSSHand/orthatyouhavenobuilt-inSSHclientinyourlocalOS.Forthisreason,wewillbeusingthePuTTYclientwedownloadedearlierfortheworkshop.However,ifyouaremorecomfortableusinganotherTelnet/SSHclient(e.g.MacOS,Linux,WindowsSub-Layer(WSL)),pleasefeelfreetouseit.

GetPublicIP1. Ifitisnotalreadyopen,navigatetotheOverviewbladeofyournewlycreatedvirtual

machine.

2. Inthetopsectionoftheblade,intherightcolumn,youshouldseeaPublicIPaddresslisted.

3. CopytheIPaddress.

ConnectwithSSH1. OpenPuTTY.

2. Intheconfigurationwindow:

Hostname:<IPaddressfrompreviousstep>Port:22Connectiontype:SSH

3. ClickOpen

4. Inthesecurityprompt,clickYes.

5. YouwillthenconnecttotheremoteUbuntuserver.

6. Entertheusernameandpasswordfromabove(e.g.localadminandPass@word1234,respectively).

7. Youshouldthenseethe bash prompt:

localadmin@docker-ubuntu:~$

Congratulations.YouhavesuccessfullycreatedandconnectedtoyourremoteUbuntuserverinAzure.YouarenowreadytoinstalltheDockerruntime.

OverviewWehavejustcreatedourUbuntuserver.WenowneedtoapplyanyavailablesystemupdatesalongwithinstallingandconfiguringDockertobeginworkingwithcontainers.

InstallUpdatesJustlikeanyotheroperatingsystem,updatesareperiodicallyreleasedtosupportnewfeaturesandpatchanypotentialsecuritythreats.Wewillapplytheupdatesfirst.

1. Ifyouhavenotalready,connecttoyourremoteUbuntuserverandlogin.

2. Fromtheloginprompt,youmayseeastatusofavailableupdates.(Ifnot,don'tbetooalarmed-continuewiththesestepsanywayjusttobesure.)

3. Firstweneedtoensureourlistofsourcesforoursystemupdatesareup-to-date.Fromthe

InstallDocker

commandprompt,typethefollowing:

sudoapt-getupdate

4. Nowwecaninstallupdates.Fromthecommandprompt,typethefollowingtoautomaticallyinstallallavailableupdates:

sudoapt-getupgrade-y

5. Dependingonthenumberandsizeofavailableupdates,thisprocessmaytakeafewminutes.Nowwouldbeagoodtimetotakeabreak.

InstallDockerWenowhaveanupdatedUbuntuoperatingsystem.WearereadytoinstallDocker.

1. WeneedtoaddtheGPGkeyfortheofficialDockerrepositorytothesystembecauseinthenextstepwewanttodownloadtheDocker'installer'directlyfromDockerandnotthedefaultUbuntuserverstoensurewegetthelatestversionoftheengine.Fromthecommandprompt,typethefollowing:

sudoapt-keyadv--keyserverhkp://p80.pool.sks-keyservers.net:80--recv-keys58118E89F3A912897C070ADBF76221572C52609D

Cut&PasteYoucanpastethisintoPuTTYbyright-clickingtheterminalscreen.

2. Now,weneedtotellUbuntuwheretheDockerrepositoryislocated.Fromthecommandprompt,type(orpaste)thefollowing:

sudoapt-add-repository'debhttps://apt.dockerproject.org/repoubuntu-xenialmain'

3. Onceagain,updatethepackagedatabasewiththeDockerpackagesfromthenewlyaddedrepository:

sudoapt-getupdate

4. MakesureyouareabouttoinstallfromtheDockerrepositoryinsteadofthedefaultUbunturepository:

apt-cachepolicydocker-engine

5. Youshouldseeoutputsimilartothefollowing(noticethat docker-engine isnotinstalledandthe docker-engine versionnumbermightbedifferent):

docker-engine:Installed:(none)Candidate:1.11.1-0~xenialVersiontable:1.11.1-0~xenial500500https://apt.dockerproject.org/repoubuntu-xenial/mainamd64Packages1.11.0-0~xenial500500https://apt.dockerproject.org/repoubuntu-xenial/mainamd64Packages

6. Finally,installDocker:

sudoapt-getinstall-ydocker-engine

7. InstallingtheDockerenginemaytakeanadditionalminuteortwo.

AdditionalConfigurationTosimplifyrunningandmanagingDocker,there'ssomeadditionalconfigurationthatweneedtoimplement.Whilethissectionisoptional,itisrecommendedtomakemanagingDockermucheasier.

EnsureDockerEngineisRunning1. Fromthecommandprompt,type:

sudosystemctlstatusdocker

2. Youshouldseesomethingsimilartothefollowing:

●docker.service-DockerApplicationContainerEngineLoaded:loaded(/lib/systemd/system/docker.service;enabled;vendorpreset:enabled)Active:active(running)sinceSun2017-06-0422:38:16UTC;4min10sagoDocs:https://docs.docker.comMainPID:32844(dockerd)

3. Becausetheserviceisrunning,wecannowusethe docker commandlaterinthisworkshop.

EnableDockerEngineatStartupLet'smakesuretheDockerengineisconfiguredtorunonsystemstartup(andreboot).

1. Fromthecommandprompt,type:

sudosystemctlenabledocker

2. Youshouldseesomethingsimilartothefollowing:

Synchronizingstateofdocker.servicewithSysVinitwith/lib/systemd/systemd-sysv-install...Executing/lib/systemd/systemd-sysv-installenabledocker

ElevateYourPrivilegesBedefault,runningthe docker commandrequiresrootprivileges-thatis,youhavetoprefixthecommandwith sudo .Itcanalsoberunbyauserinthedockergroup,whichisautomaticallycreatedduringtheinstallofDocker.Ifyouattempttorunthe docker commandwithoutprefixingitwith sudo orwithoutbeinginthedockergroup,you'llgetanoutputlikethefollowing:

docker:CannotconnecttotheDockerdaemon.Isthedockerdaemonrunningonthishost?.See'dockerrun--help'.

Toavoidtyping sudo wheneveryourunthe docker command,addyourusernametothedockergroup:

sudousermod-aGdocker$(whoami)

Youwillthenneedtologoutandbackinforthechangestotakeeffect.

Ifyouneedtoaddanotherusertothe docker group(oneinwhichyouhavenotloggedinascurrently),simplyprovidethatusernameexplicitlyinthecommand:

sudousermod-aGdocker<username>

You'vesuccessfullyinstalledtheDockerengine.YouhavealsoconfiguredittorunatstartupandhaveaddedyourselftotheDockergroupsothatyouhavesufficientprivilegesforrunningDocker.

OverviewNowthatwehaveDockerinstalled,weareabletodeployimagesascontainers.Inthisshortstepoftheworkshop,wewilldeployacoupleofsmallcontainersaspractice.

HelloWorld1. EnsureyouhaveloggedintoyourremoteUbuntuserverandareattheprompt.

2. Fromthecommandprompt,typethefollowing:

dockerrunhello-world

3. Youshouldthenseesomethingsimilartothefollowing:

HelloWorld

Unabletofindimage'hello-world:latest'locallylatest:Pullingfromlibrary/hello-world78445dd45222:PullcompleteDigest:sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7Status:Downloadednewerimageforhello-world:latest

HellofromDocker!Thismessageshowsthatyourinstallationappearstobeworkingcorrectly.

Togeneratethismessage,Dockertookthefollowingsteps:1.TheDockerclientcontactedtheDockerdaemon.2.TheDockerdaemonpulledthe"hello-world"imagefromtheDockerHub.3.TheDockerdaemoncreatedanewcontainerfromthatimagewhichrunstheexecutablethatproducestheoutputyouarecurrentlyreading.4.TheDockerdaemonstreamedthatoutputtotheDockerclient,whichsentittoyourterminal.

Totrysomethingmoreambitious,youcanrunanUbuntucontainerwith:$dockerrun-itubuntubash

Shareimages,automateworkflows,andmorewithafreeDockerID:https://cloud.docker.com/

Formoreexamplesandideas,visit:https://docs.docker.com/engine/userguide/

I'llexplainwhatthefirstcoupleoflinesmeanlater.Theimportantthinghereistoseethataroundthe7thline,you'llseethemessage'HellofromDocker!'followedbyalineinformingyouthattheDockerinstallation'appearstobeworkingcorrectly.'

WhalesayNowlet'srunanotherfuncontainer.

1. Fromthecommandprompt,type:

dockerrundocker/whalesaycowsay'AzureRocks!'

2. Afterdownloadingthedependentimages,youshouldseeanASCIIwhalewithaspeechbubblecontainingthemessage'AzureRocks!'.

ThisimageisbasedontheoldUnixcowsaygame.We'rebasicallyrunningcowsayinacontainerandtellingthewhaletosaywhateverweprovideinsinglequotes.Youcanrunthecommandasmanytimesasyou'dlikeandputwhateveryou'dlikethewhaletosayinsinglequotes.Goaheadandgiveitatry.Notice,thatafterthefirsttimerunningthecontainer,theimageisnolongerdownloaded.Moreaboutthisinthenextsection.

OverviewWe'vesuccessfullydeployedacoupleofcontainersintoourDockerengine.Inthissection,we'lldigalittledeeperintoworkingwithandinteractingwithcontainers.

ListingImagesAsweexperiencedwithrunningtheWhalesaycontainermultipletimes,theactualimagewasonlydownloaded,uncompressedandbuiltonce.Onallsubsequentexecutions,anewcontainerwassimplyinstantiatedbasedontheimage.Dockerkeepsalocalrepositoryofimagescurrentlyinuse;and,thoseimagescannotbedeleteduntilalldependentcontainershavebeendeleted.

Toviewalistofcurrentlydownloadedimages,typethefollowinginthecommandprompt:

dockerimages

Theoutputshouldlooksimilartothefollowing:

REPOSITORYTAGIMAGEIDCREATEDSIZEhello-worldlatest48b5124b27684monthsago1.84kBdocker/whalesaylatest6b362a9f73eb2yearsago247MB

There'safewthingsthatarereportedtoushere.

First,weseetherepository,includingthenamespace,oftheimage.The hello-world iswhatwewouldconsideralibraryimage.Inotherwords,it'sanimagethat,forlackofabetterwaytodescribeit,is'built-in'toDocker.For whalesay ,weseethattherepositoryis docker .We'lltalkmoreaboutrepositoriesbelow.

Thesecondcolumnshowsusthecurrenttagoftheimage.Welookattagginginthenextworkshopsection.

WorkingWithContainers

Thethirdcolumndisplaysauniqueidoftheimage.Justsothatyouknow,wecanrefertotheimageinourcommandsthroughouttheexercisebythefullnameasit'slistedunder REPOSITORY ,theimageid,orsimplyusethefirst3charactersintheimageid(e.g. hello-world couldalsobereferencedby 48b5124b2768 or 48b ).Thethingis,theminimumis3characters,butifyouhavemultipleimagesthathavethesamefirst3characters,youmayneedtouseacoupleofmoreuntilyoureachadifferentiator.

Thecreatedcolumndoesnotreportwhenyoudownloadedtheimagelocally.Instead,itreportsthedateofwhentheimagewascreatedbyitsowner/designer.ThisisagreatcolumnforDevOpstousewhenquicklytryingtodeterminewhenaparticularimagewascreated.

Thesizecolumnreportsthetotalsizeoftheimage-asumofalllayerscomprisedtomaketheimage.

DockerRepositories/RegistriesAregistryisaservice-publicorprivate-fromwhichimagescanbehostedandpulledbyotherusers.Imagesarestoredintheserepositoriesundernamespaceswhichare,typically,usernamesororganizationalnames.

Intheaboveexample,the whalesay imageislocatedunderthe docker namespace.ThismeansthattheimagebelongstoandismanagedbytheDockerorganization.

Microsoft'spublicregistryishostedbyDocker.YoucanvisitMicrosoft'sregistryathttps://hub.docker.com/u/microsoft/.Asyouviewtheavailableimages(whichareonlyavailableforWindows-basedmachines),you'llseethateachbeginwith microsoft/ .IfweweretopullanimagecreatedandmaintainedbyMicrosoftintoourlocalDockerinstance,wewouldseetheimageprefacedbythatnamespace.

InspectingImagesThereareacoupleofwayswecangetsomegreaterdetailsaboutourimages.Wecanviewtheunderlyingmetadataofourimage;and,wecanseethebuildhistoryoftheimage.

ImageInspection(Metadata)Toviewthemetadataofanimage,we'llneedtoinspectit.Fromthecommandprompt,typethefollowing:

dockerimageinspectdocker/whalesay

Youshouldseesomethingthatbeginswiththefollowing:

[{"Id":"sha256:6b362a9f73eb8c33b48c95f4fcce1b6637fc25646728cf7fb0679b2da273c3f4","RepoTags":["docker/whalesay:latest"],"RepoDigests":["docker/whalesay@sha256:178598e51a26abbc958b8a2e48825c90bc22e641de3d31e18aaf55f3258ba93b"],"Parent":"","Comment":"","Created":"2015-05-25T22:04:23.303454458Z","Container":"5460b2353ce4e2b3e3e81b4a523a61c5adc238ae21d3ec3a5774674652e6317f","ContainerConfig":{"Hostname":"9ec8c01a6a48","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop)ENVPATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Image":"5d5bd9951e26ca0301423625b19764bda914ae39c3f2bfd6f1824bf5354d10ee","Volumes":null,"WorkingDir":"/cowsay","Entrypoint":null,"OnBuild":[],"Labels":{}},"DockerVersion":"1.6.0",...

Takeamomenttoexaminethemetadata.Asyoulookthroughthisinformation,youwillfindvariousattributesthatdescribetheimage.

ImageHistoryThelastbitofinformationthatthe inspect commandreportedwasasetoflayers:

"Layers":["sha256:1154ba695078d29ea6c4e1adb55c463959cd77509adf09710e2315827d66271a","sha256:528c8710fd95f61d40b8bb8a549fa8dfa737d9b9c7c7b2ae55f745c972dddacd","sha256:37ee47034d9b78f10f0c5ce3a25e6b6e58997fcadaf5f896c603a10c5f35fb31","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef","sha256:b26122d57afa5c4a2dc8db3f986410805bc8792af3a4fa73cfde5eed0a8e5b6d","sha256:091abc5148e4d32cecb5522067509d7ffc1e8ac272ff75d2775138639a6c50ca","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef","sha256:d511ed9e12e17ab4bfc3e80ed7ce86d4aac82769b42f42b753a338ed9b8a566d","sha256:d061ee1340ecc8d03ca25e6ca7f7502275f558764c1ab46bd1f37854c74c5b3f","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"]

Otherthanthelayerid's,thisdoesn'treallytellyoumuch.Toseetheactualbuildhistoryoftheimage,typethefollowingcommand:

dockerimagehistorydocker/whalesay

You'llwillthenseesomethingsimilartothefollowing:

IMAGECREATEDCREATEDBYSIZECOMMENT6b362a9f73eb2yearsago/bin/sh-c#(nop)ENVPATH=/usr/local/bin:...0B<missing>2yearsago/bin/sh-cshinstall.sh30.4kB<missing>2yearsago/bin/sh-cgitreset--hardorigin/master43.3kB<missing>2yearsago/bin/sh-c#(nop)WORKDIR/cowsay0B<missing>2yearsago/bin/sh-cgitclonehttps://github.com/mo...89.9kB<missing>2yearsago/bin/sh-capt-get-yupdate&&apt-getin...58.6MB<missing>2yearsago/bin/sh-c#(nop)CMD["/bin/bash"]0B<missing>2yearsago/bin/sh-csed-i's/^#\s*\(deb.*universe\...1.9kB<missing>2yearsago/bin/sh-cecho'#!/bin/sh'>/usr/sbin/po...195kB<missing>2yearsago/bin/sh-c#(nop)ADDfile:f4d7b4b3402b5c5...188MB

Keepinmindthatthesearelayers.Sothewaytoreadthisisfrombottom-up,meaningthatthelastrowisactuallythefirstlayer.Then,asyougoupthelist,additionallayersareapplied.Thebottomlayerisusuallyabaseimage,suchasanOSand,becauseit'stheOS,isusuallylargerinsize.Then,actionsorcommandsareappliedtothatimagethatmakeuptheadditionallayers.Someofthelastactionstobeappliedtothisimagewererunninganinstallscriptandsettingsomeenvironmentvariables.

Let'stakealookatanotherexample.DownloadanotherimagetoyourlocalDockerenginebytypingthefollowingcommand:

dockerimagepulla11smiles/softcover

ThisisanimagestoredundermypersonalnamespaceinthepublicDockerregistry.Softcoverisaruby-basedapplicationusedtobuilddigitalbooksforvariousplatforms.Runningthiscommandwilltakeafewminutes,but,asyouwillobserve,there'squiteafewlayerstothisimage.

Oncethisimagedownloadandreconstructionhascompleted,checkoutthehistoryoftheimage:

dockerimagehistorya11smiles/softcover

Youwillseeallofthecommands,whichincludeinstallingmultipledependencylibrariesforSoftcover(e.g. apt-getinstall... ),issuedtobuildtheimage.Someofthesedependenciesarequitelarge,rangingfrom815kBtoalmost4GB.Imagethetimeitwouldrequiretodownloadalloftheserequirementsmanually.Thisdoesn'tincludethetimeitwouldtaketoproperlyandconsistentlyconfigurethemforeachdeveloperand/orenvironment.WiththeSoftcovercontainer,inthiscase,simplydownloadtheimageandrunthecontainerwithsupplyingyourbook'ssourcetocreateadigitalpublication.Thiscanbeeasilywiredupinanautomatedbuildprocess.

ListingContainersNotonlycanwelistourlocalimages,butwecanalsolistourlocal,instantiatedcontainers.

RunningContainersTypeinthecommandline:

dockerps

Youshouldseesomelikethefollowing:

CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES

Thistellsusthatnocontainersarecurrentlyrunning.

Non-runningContainersWecanseepreviouslyrancontainersbytypinginthefollowing:

dockerps-a

Thiswillrenderareportsimilartothefollowing:

CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESa883ff18a967docker/whalesay"cowsayHola!"26hoursagoExited(0)26hoursagosad_goldstinebaa0591c4392hello-world"/hello"26hoursagoExited(0)26hoursagojovial_raman

Youmayseemoredependingonhowmanytimesyouinstantiatedthe whalesay image.The

Youmayseemoredependingonhowmanytimesyouinstantiatedthe whalesay image.TheimportantthingtoseefromthisreportistheStatusofcontainers.Allcontainers,inthisreport,haveexitedandarenolongerrunning.

Onethingtonoteisthateventhoughthecontainershavefinishedexecuting,theyhavenotbeendeleted.Thisallowsyoutoenterintoastoppedcontainer.Onereasonthismaybeusefulisifanapplicationhasthrownanexceptionandquit,youmaywanttoenterintothecontainertocheckoutsomelogfilesorsomethingofthatnaturetodebugtheapplication.Onceyou'redonewiththecontainer,youmustdeleteit.Wewillseehowtodothisinthenextpageoftheworkshop.

RunningaContainerWe'vealreadyinstantiatedacoupleofimages.Wedothisbythefollowingcommand:

dockerrun<namespace/image>

Therearetwoprimarytypesofprocesses-short-runningandlong-running.

Short-runningProcessesShort-runningprocessarejustliketheimageswe'vealreadyran- hello-world and whalesay .Anotherexampleisthe softcover image.Ashort-runningprocesstypicallyrunsasinglecommand,performingasinglefunction,thenexits.Thisfunctioncouldbedisplayingamessage,sendinganemail,orbuildinganapplicationorotherresource(e.g.abook,helpdocumentation,etc).

Everytimewewerunashort-runningprocess,usingtheabovecommandanothercontainerisinstantiated.Thisiswhyanewcontainerwascreatedevertimeyouran whalesay .

Long-runningProcessesLong-runningprocessesaretypicallyservice-basedapplications(e.g.webservers,servicebuses,queues,etc.).WecanalsorunanOSasacontainer.Trytypinginthefollowing:

dockerrun-itubuntu/bin/bash

Thiscommandwillwilldownloadan ubuntu imageandrunthe bash shellininteractivemode( -i )byopeningupaterminal( -t ).Whenthisruns,youwillbeautomaticallyplacedinsideoftherunningUbuntucontainer(noticethechangeinthecommandprompt(e.g.somethingsimilartoroot@<containerid>:/# )).IfyouarefamiliarwithUbuntu,feelfreetotakealookaround.Toexitthecontainer,simplytypein exit .Thiswillreturnyoutoyourhostmachine.

Let'snowrunUbuntuindetachedmode.Instantiatingacontainerininteractivemodeassumeswearegoingtointeractwiththerunningcontainer.However,typicallong-runningprocesses(likewebservers)don'trequirecommandlineinteraction.We'llrunawebserverlaterinthisworkshop.However,forthemoment,let'smimicalong-runningprocessbyrunningUbuntuinaninfinitesleepmode.Executethefollowingcommand:

dockerrun-dubuntusleepinf

Again,thiswillrunanUbuntucontainerindetachedmode( -d )andsetittosleepinfinitely.

Let'sseethecontainerrunninginthebackgroundbytypingin:

dockerps

Youshouldseesomethinglike:

CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES094012b145c8ubuntu"sleepinf"2secondsagoUp2secondsvigorous_yalow

You'llseeundertheStatuscolumn,thatit'sreportinganup-timeforthecontainer.Wedon'ttypicallyruncommandsagainstlong-runningprocesses,butjustforthepractice,issuethefollowingcommand(substitutethecontaineridwithyourid):

dockerexec094ls

Thiswillruna list commandagainstthecurrentdirectoryinsideofthecontainerandreturnalistofsubfolders.

Whilethecontainerisrunning,let'slookatonemoreinterestingthing.Atthecommandprompt,typethefollowing:

psaux

Thiswilllistallofthecurrentlyrunningprocesses.Asyouscrollandlookatthebackgroundprocesses,youshouldseealinesimilartothefollowing.Theprocessid,memoryconsumption,etc.maybedifferentbuttrytofindthelastcolumn.

root555150.00.04380664?Ss01:390:00sleepinf

Whatyouseehereisthatcontainerprocessesareexposedtothehostkernelandhaveaccesstohostsystemresources.

Nowlet'sstopthecontainer.Technically,wecouldkilltheprocessusingtraditionalLinux(UNIX)commands,butthiswouldleaveourDockerengineinanuncleanstateandwouldrequireustodosomeadditionalcleanup.Let'sstopthecontainerusingDockercommands.

dockerstop094

(NOTE:Again, 094 isthefirst3charactersofmycontainer'sid.You'llneedtousetheidassignedtoyourcontainer.)

Running dockerps againshouldshowyouthatnomorecontainersarecurrentlyrunning.

Re-runningaStoppedContainerTherewillbetimeswhenyoumayneedtore-runastoppedcontainer.Findoneofthestopped'whalesay'containersbytypingthefollowing:

dockerps-a

Myoutputlookslikethefollowing:

CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES094012b145c8ubuntu"sleepinf"27minutesagoExited(137)4minutesagovigorous_yalowa883ff18a967docker/whalesay"cowsayHola!"27hoursagoExited(0)38minutesagosad_goldstinebaa0591c4392hello-world"/hello"27hoursagoExited(0)27hoursagojovial_raman

Bytypingthefollowingcommand,Icanre-runmy whalesay containerwithoutinstantiatinganewcontainerandwithouthavingtosupplyanyparameters.Basically,Icanre-runthecontainerasitwasoriginallyran.

dockerstart-aa88

(NOTE:Again, a88 isthefirst3charactersofthestopped whalesay container'sid.)

Withthiscommand,wearerestartingastoppedcontainerandattaching( -a )tothecontainer'soutput(STDOUT/STDERR)toviewanymessages.Inourcase,themessageisasimplewhalewithaspeechbubble.

Wow,congratulations!Youjustsuccessfullycompletedwhatmayseemlikeacrashcourseinmanagingcontainers.However,there'sreallynotmuchmoretoitthanthis.Aswithanything,themoreyouplaywithDocker,themorefamiliarandconfidentyoubecomewithit.

OverviewYou'vejustlearnedquiteabitinworkingwithcontainers.Asamatteroffact,themajorityofcontainermanagementhasalreadybeencovered.We'renowgoingtobringourknowledgeofcontainerandimagemanagementaroundfull-circle.Thiswillcompletetheadministrationportionoftheworkshop.

TaggingImagesTherewillbeinstances,likeDevOpsforinstance,wherewewillneedtotagourimages.Tagsallowustoapplylabelstoourimages.Thisisusefulfortrackingchanges,suchasinversioning,toourimages.

Let'screateasimplederivativeoftheUbuntuimagewedownloadedpreviously.

InstantiateanewUbuntucontainerbytypingthefollowing:

dockerrun-itubuntu/bin/bash

Thiswillplaceyouatthecommandpromptinsideoftherunningcontainer.Now,let'sinteractwiththeOSbytypingthefollowingcommands.

cdmkdirtestcdtestecho"Thisissomesampletext.">test.txtexit

We'vejustcreatedanewdirectorywithatesttextfileintheuser'shomedirectory.IfIviewmyavailablecontainers( dockerps-a ),I'llfindtheidofthecontainerIjustexitedfrom(lookundertheStatuscolumnforthecontainerthatwasjustexited).Inmycase(seethefollowingoutput),thecontainer'sidis 335abd61d52d .

ImageandContainerAdministration

CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES335abd61d52dubuntu"/bin/bash"3minutesagoExited(0)Aboutaminuteagoblissful_wing094012b145c8ubuntu"sleepinf"AboutanhouragoExited(137)27minutesagovigorous_yalowa883ff18a967docker/whalesay"cowsayHola!"27hoursagoExited(0)17minutesagosad_goldstinebaa0591c4392hello-world"/hello"27hoursagoExited(0)27hoursagojovial_raman

Let'srestartthecontainerandchecktomakesureourtextfileisstillthere(justtoconfirm).Again,replacetheidbelowwithyourcontainer'sid.

dockerstart-i335

Attheprompttypein:

ls~/test

Thisshouldlistafilenamed test.txt .Now,type exit toexitoutofthecontainer.

WenowhaveacustomizedcontainerbasedonourUbuntuimage.Let'screateourownimagewithit'stag.We'realsogoingtoaddamessageandanauthortotheimage'smetadata.Onceagain,replacethe 335 belowwiththeidofyourstoppedcontainer.

dockercommit-m"addedtest.txt"-a"SomeUser"335mynamespace/testtext:v1

Withthiscommand,again,I'maddedamessage( -m )todescribetheimageandanauthor( -a )toinformoftheauthor.The 335 isthefirst3charactersofmystopped,modifiedcontainer.Finally,I'vesuppliedanamespace( mynamespace/ ),animagename( testtext ),andatag( v1 ).

Thenamespaceisoptional,butagoodpracticetodifferentiatebetweenimagesthatmighthavethesamename.Forexample,ifyouandanotherdeveloperareworkingontwoseparateimagesandyouhavethembothlocally,it'seasiertokeeptrackofwho'simagebelongstowho.

Nowexecutethefollowingcommand:

dockerimages

Youshouldseesomethingsimilartothefollowing:

REPOSITORYTAGIMAGEIDCREATEDSIZEmynamespace/testtextv1556c25bff4b15minutesago118MBubuntulatest7b9b13f7b9c03daysago118MBa11smiles/softcoverlatest306f236838723monthsago5.74GBhello-worldlatest48b5124b27684monthsago1.84kBdocker/whalesaylatest6b362a9f73eb2yearsago247MB

Noticethatyounowhaveyourcustomimagewithitstag.Also,becauseourtextfileisn'tverylarge,ourimagehas,virtually,thesamesizeasthatofthe ubuntu image(118MB).

Wecantheninstantiateacontainerbasedonourimagebyrunningthefollowing:

dockerrun-itmynamespace/testtext:v1/bin/bash

(NOTE:Inalltheprevioustimeswe'verunthiscommand,we'veneverhadtospecifyatagbecausethe latest tagisimplied.Inourcase,thetagweusedis v1 sowehavetospecifyit.)

Thiswillplaceus,onceagain,insidethecontainer.Runthefollowingcommandinthecontainer:

cat~/test/test.txt

Thiswillshowthecontentsofthefileweaddedearlier.

Nowwecanexitoutofthecontainerbysimplytypingin exit .

Inthehostmachine,typingin dockerps-a showsusthatourcustomimageinstantiatedacontainerwhichjustexitedsuccessfully.

CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESa215acbb7981mynamespace/testtext:v1"/bin/bash"3minutesagoExited(0)13secondsagoinspiring_spence335abd61d52dubuntu"/bin/bash"26minutesagoExited(0)16minutesagoblissful_wing094012b145c8ubuntu"sleepinf"AboutanhouragoExited(137)Aboutanhouragovigorous_yalowa883ff18a967docker/whalesay"cowsayHola!"28hoursagoExited(0)39minutesagosad_goldstinebaa0591c4392hello-world"/hello"28hoursagoExited(0)28hoursagojovial_raman

Finally,ifweinspectourcustomimage( dockerimageinspectmynamespace/testtext:v1 ),wewillseethecommentandauthorattributesdisplaying"addedtest.txt"and"SomeUser",respectively.And,thetoplayerofourhistory( dockerimagehistorymynamespace/testtext:v1 )showsusenteringintothe bash shell.

DeletingContainersWecancleanupdiskspacebyremovingunusedcontainersandimages.However,wecannotremoveanyimagesthatcurrentlyhavedependentcontainers-evencontainersthathavestopped.Therefore,wemustdeletedependentcontainersfirst.

Forourexample,let'ssupposethatwenolongerneedthe ubuntu containeranymorebecausewe'vecustomizedit(e.g.addedourowntextfile).Wecandeletethe ubuntu containerbytypingthefollowing:

dockerrm335

Let'salsodeleteour hello-world container:

dockerrmbaa

Remember,fortheprevioustwocommands,substituteyourrespectivecontainerids.

DeletingImagesDeletingimagesarejustaseasy.First,let'srefreshourselvesonourlocallyinstalledimages.Runningdockerimages producesthefollowingoutput:

REPOSITORYTAGIMAGEIDCREATEDSIZEmynamespace/testtextv1556c25bff4b119minutesago118MBubuntulatest7b9b13f7b9c03daysago118MBa11smiles/softcoverlatest306f236838723monthsago5.74GBhello-worldlatest48b5124b27684monthsago1.84kBdocker/whalesaylatest6b362a9f73eb2yearsago247MB

Sinceimages,combinedwiththeirnamespacesandtags,areuniqueonthelocalDockerengine,wecandeleteimagesbyusingthefullnamespacereference(includingthetag)orbyusingtheimageid.Let'spracticedeletingimages.

First,let'sdeletethe hello-world image:

dockerrmihello-world

Asareminder,the latest tagisimplied.Ifweweretodeleteourcustomimage,wewouldberequiredtosupplythetagbecauseitdiffersfrom latest .

Runningthe dockerrmi commandwillremoveanylinksbetweentheimageandsharedlayers.Ifthelayerisnolongerrequiredbyanyotherimage,thelayerisalsodeleted.

Now,let'sattempttodeletethe ubuntu image:

dockerrmiubuntu

Runningthiscommandproducesanderror-namely,thattheimagecannotbedeletedbecausethere'sstillacontainerthatdependsonit.Running dockerps-a showsthatthis,indeed,isthecase(thesecondcontainerlistedbelow):

CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESa215acbb7981mynamespace/testtext:v1"/bin/bash"20minutesagoExited(0)17minutesagoinspiring_spence094012b145c8ubuntu"sleepinf"AboutanhouragoExited(137)Aboutanhouragovigorous_yalowa883ff18a967docker/whalesay"cowsayHola!"28hoursagoExited(0)Aboutanhouragosad_goldstine

Oneofthemanyreasonsforthis,istoprotectagainstaccidentaldeletionofourcontainersandimages.However,ifaresurewewanttodeletetheimageandallitscontainers,wecanforceadeletion:

dockerrmi-fubuntu

Besidesforcingadeleteoftheimage,noticehowtheoutputisdifferentfromthepreviousdeletionofthe hello-world image.Inthislastcase,onlythereference,orlink,wasremovedfromtheimage.Theunderlyinglayersweren'tdeleted.Why?BecausethecustomimagethatwecreatedearlierstilldependsontheunderlyingUbuntuOSlayer(s).ThisisonewayDockerhelpstoconservediskspace-sharedandreuseofdependencies.Deletingourcustomimage(andcontainers)wouldperformanactualdeleteoftheUbuntuOSlayer(s).

OverviewThefinalpartofthisworkshopistopracticeexposingacontainerserviceoutsideofAzure.We'regoingtocreateasimplewebserverandaccessitfromourlocalmachine.

NGINXWearegoingtodeployacontainerhostingNGINX(pronounced"engineX"),asimple,butpowerfulwebserver.NGINXistypicallyusedincontainerizeddeploymentsbecauseitsupportsautoscaling,servicediscoveryandothercapabilitiesoftenleveragedinmicroservicearchitecture.

RunNGINXbytypingthefollowingcommand:

dockerrun-d-p8080:80nginx

ThiswilldownloadandrunNGINXinthebackground.Asstatedearlierinthisworkshop,weoftenrunservicesindetachedmode( -d ).Asnewparameterthatyouseehereismapping,orpublishing( -p ),ports-verysimilartoaNAT,ifyouarefamiliarwiththeconcept.Therearetwoportsspecifiedhereseparatedbyacolon.Thefirstnumberisthehost'sportwhilethesecondnumberisthecontainer'sport.So,inessence,wearemappingthehost'sport8080tothecontainer'sport80.Ifourcontainerrunsmultipleservicesoraservicerequiringmultipleports,wecanalsospecifyaportrange.WecouldhaveusedthedefaultHTTPport80forthehost,butfortheworkshopIchoseport8080fordifferentiationbetweenthetwoenvironmentsinpursuitofclarity.

Let'smakesurethatNGINXisrunningsuccessfully.

curlhttp://localhost:8080

Runningthepreviouscommand,shoulddisplaysomehtmlsourcecode.

ExposingServicesInAzure

<!DOCTYPEhtml><html><head><title>Welcometonginx!</title><style>body{width:35em;margin:0auto;font-family:Tahoma,Verdana,Arial,sans-serif;}</style></head><body><h1>Welcometonginx!</h1><p>Ifyouseethispage,thenginxwebserverissuccessfullyinstalledandworking.Furtherconfigurationisrequired.</p>

<p>Foronlinedocumentationandsupportpleasereferto<ahref="http://nginx.org/">nginx.org</a>.<br/>Commercialsupportisavailableat<ahref="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thankyouforusingnginx.</em></p></body></html>

NetworkSecurityGroup(NSG)Nowthatourwebserverisrunning,let'smakeitavailableoutsideofAzure.

WhenwecreatedourUbuntuvirtualmachine,weacceptedthedefaults,includingthedefaultsettingsforourNSG.ThedefaultsettingsonlyallowedSSH(port22)access.WeneedtoaddaruletoourNSGtoallowHTTPtrafficoverport8080.

1. Ifyouarenotstillthere,gobacktotheAzureportalandnavigatetothesettingsofyourUbuntuvirtualmachine.

2. Intheleftmenu,clickonNetworkinterfaces .

3. ThiswillopentheNetworkInterfacesbladeforyourUbuntuvirtualmachine.Clickonthesingular,listedinterface.

4. Intheleftmenu,clickonNetworksecuritygroup .

5. ThiswilllistthecurrentlyactiveNSG.Inourcase,itshouldbetheNSGthatwascreatedwithourvirtualmachine-docker-ubuntu-nsg.ClickontheNSG(NOTE:ClickontheactualNSGlink,NOTonEdit).

6. Intheleftmenu,clickonInboundsecurityroles .

7. Atthetopoftheblade,clickAdd .

8. Enterthefollowingconfiguration:

Name:allow-httpPriority:1010Source:AnyService:CustomProtocol:AnyPortrange:8080Action:Allow

9. ClickOK.

Thisshouldonlytakeacoupleofseconds.Onceyouseetheruleadded,openanewbrowserandnavigatetotheIPaddressofyourUbuntuvirtualmachine,includingtheportnumber.TheIPaddressusedinthisworkshop'sscreenshotsis40.121.213.77(yourIPaddresswillbedifferent).UsingtheaforementionedIPaddress,Iwoulddirectmybrowsertohttp://40.121.213.77:8080.Doingso,youshouldseetheNGINXlandingpage.