Riot Games

i den här första handledningen i Docker-serien lär du dig:

  • vad vi försöker åstadkomma på Riot

  • grundläggande inställning för Docker

  • grundläggande Docker Pull-kommandon

  • hur man kör Docker Containers som demoner

  • grundläggande Jenkins konfigurationsalternativ

när jag först började lära mig om Docker för ett år sedan och utforska dess användning hade jag problem med att hitta bra dokumentation och exempel – även idag beskriver många enkla användningsfall som i slutändan inte är produktionsklara. Productionizing applikationer med Docker behållare kräver anpassning till deras efemära natur och enprocess fokus. Detta innebär utmaningar för applikationer med databeständighetsbehov eller multiprocessarkitekturer.

som jag nämnde i mitt senaste inlägg använder vi Jenkins som en grundläggande del av öppen källkodsprogramvara som vi bygger vår automatisering på. Jenkins är också en bra applikation för att visa ett sätt att tänka på att ”Dockerisera” dina applikationer. Vi distribuerar Jenkins med dessa arkitektoniska komponenter i åtanke:

  • Jenkins master server (Java-process)

  • Jenkins master data (Plugins, Jobbdefinitioner, etc)

  • NGINX web proxy (vi använder SSL-certifikat etc, med NGINX är ett enkelt val här)

  • Bygg slavagenter (maskiner som antingen är SSH ’ d in, eller JNLP ansluter till, Jenkins Master)

detta är ett bra ställe att börja. Under denna serie blogginlägg kommer jag att täcka sätt att tänka på alla ovanstående som behållare och avsluta med en avancerad titt på sätt att använda Docker-behållare som byggslavar. Till att börja med skapar vi en Jenkins master-server i en Docker-behållare. Sedan går vi vidare till att hantera datapersistens och lägga till en webbproxy med NGINX.

hela denna bloggserie kommer att täcka följande Docker-koncept:

  • gör din egen Dockerfiles

  • minimera bildberoenden på offentliga bilder

  • skapa och använda datamängder, inklusive säkerhetskopior

  • skapa containeriserade ”byggmiljöer” med Behållare

  • hantering av ”hemliga” data med bilder och Jenkins

om du inte har tittat på Cloudbees Jenkins Docker-bilden, börja där eftersom det verkligen är ganska bra. Detta var min referenspunkt när jag först tänkte på att köra Jenkins i en Docker-behållare och för många kan det vara tillräckligt. Du hittar deras dokumentation här och deras Git repo / Dockerfile här.

denna första blogg är uppdelad i två lektionsplaner. Var och en är dimensionerad för att ta cirka 30 minuter att slutföra. Först upp, del ett är att få din utvecklingsmiljö redo och lära sig att arbeta med standard Jenkins Docker container som Cloudbees erbjuder. Del två handlar om att lägga grunden för att slå in den här bilden i din egen Dockerfile och ta mer elegant kontroll över bilden. Tillsammans är de utformade för att komma igång, speciellt om du aldrig har arbetat med Docker tidigare eller är relativt ny för Docker—även om de antar att du redan vet och förstår hur man arbetar med Jenkins. Om du har erfarenhet av Docker kommer en del av materialet i Lektion 1 att vara lite av en rehash av saker du förmodligen redan vet.

lektion 1: Ställ in och kör din första bild

Låt oss få dig redo att rulla. Här på Riot arbetar vi med Docker (och Jenkins) på Windows, Mac OSX och Linux. Jag föredrar att arbeta med Docker på OSX, men det är perfekt funktionellt på Windows sedan Docker 1.6. Idag finns det utmärkta installatörer för båda operativsystemen. Jag kommer att arbeta från ett OSX-perspektiv men samma verktyg finns för Windows.

PRE-KRAV:

1. Du behöver Windows 10 Pro eller Mac OSX Yosemite 10.10.3 (eller senare)

2. Om du använder Windows måste du se till att du har Windows virtualisering aktiverad (se dokumentationen Docker ger)

en snabb anteckning om KITEMATIC

med Docker 1.8 och lanseringen av Docker Toolbox, Docker innehåller nu ”Kitematic,” en tjusig GUI verktyg för att hantera och visualisera vad som händer med dina Docker bilder och behållare. Det mesta av denna handledning fokuserar på att använda kommandoradsargument och arbeta med Docker utan Kitematic GUI. Detta för att bättre utsätta dig för de underliggande mekanismerna. På samma sätt börjar jag i senare bloggar täcka användningen av Compose för att starta och stoppa flera behållare samtidigt.

STEG 1: INSTALLERA DOCKER

1. Gå till: https://www.docker.com/docker-mac eller https://www.docker.com/docker-windows

2. Ladda ner och installera lämplig version av Docker för ditt operativsystem

3. Följ alla installationsanvisningar.

4. Kontrollera att din installation fungerar genom att öppna det rekommenderade skalet för ditt operativsystem (Terminal för OSX, Powershell för windows) genom att köra ”Docker Quickstart Terminal”. På Windows kommer detta att vara en genväg på skrivbordet. På OSX hittar du den i mappen applications/Docker. Kontrollera följande kommandon och se till att du inte får några fel

docker ps
docker info

5. Innan vi gör något annat bör vi öka standardminnet och CPU-inställningarna Docker använder. Senare kommer vi att ställa in Jenkins för att använda mer minne och om vi inte justerar dessa inställningar först kan Jenkins krascha.

  • gå till din Docker widget i verktygsfältet och välj ”Inställningar”

  • gå till fliken Avancerad konfiguration

  • öka CPU-användningen till minst 4 kärnor

6. Öka minnesanvändningen till minst 8 GB, helst mer, något som 12 GB för att vara säkert (om du har det tillgängligt)

steg 2: dra och kör CloudBees JENKINS-behållaren

1. Stanna i ditt Docker-terminalfönster.

2. Dra Jenkins från den offentliga repo genom att köra:

docker pull jenkins/jenkins
docker run -p 8080:8080 --name=jenkins-master jenkins/jenkins

3. Observera att meddelandet” Jenkins initial setup ” i ditt skalfönster genererar ett lösenord för dig. Skriv ner det som du behöver det senare. Om du förlorar det kan du köra ’ docker exec jenkins-master cat/var/jenkins_home / secrets / initialAdminPassword` med din behållare igång för att hämta den.

4. Öppna din favoritwebbläsare och peka på den http://localhost:8080

Observera att du ser att jag använder Docker –name-flaggan och namnger behållaren jenkins-master – det här är en konvention som jag kommer att använda i hela den här bloggen. Att namnge dina behållare är en praktisk bästa praxis med tre fördelar:

1. Det gör dem lätta att komma ihåg och interagera med

2. Docker tillåter inte att två behållare har samma namn, vilket förhindrar misstag som att oavsiktligt starta två identiska

3. Många vanliga Docker-verktyg (som Docker Compose) använder specifika behållarnamn, så att vänja sig vid att namnge dina behållare är en bra bästa praxis.

steg 3: gör detta lite mer praktiskt

föregående steg startar Jenkins med sina mest grundläggande Startinställningar. Du kan även se att Jenkins behöver grundläggande config och ber dig om ett administratörslösenord (som du kan få från loggarna som visas på skärmen under start). Om du är som Riot är det osannolikt att du kör Jenkins på standardinställningarna. Låt oss gå igenom att lägga till några användbara alternativ. Vi kommer inte att bry sig om att konfigurera Jenkins ännu; det räcker att veta att det kan starta och springa.

steg 3A: DAEMONIZING

du förmodligen inte vill se Jenkins loggar Spy standard ut för det mesta. Så använd Docker daemon-flaggan för att starta behållaren (-d).

1. Ctrl-c i terminalfönstret som kör din behållare för att stoppa den

2. Kör följande kommandon

docker rm jenkins-master
docker run -p 8080:8080 --name=jenkins-master -d jenkins/jenkins

nu ska du bara få en hashsträng som visas och returneras till din terminal. Om du är ny på Docker är den hashsträngen faktiskt det unika ID för din behållare (användbart om du börjar automatisera dessa kommandon).

steg 3B: minnesinställningar

vi brukar köra Jenkins med några biffiga inställningar vid Riot. Kom ihåg när du ökade CPU/Memory Docker använder tidigare? Detta är den främsta anledningen till. För en grundläggande start, Kör följande kommandon

docker stop jenkins-master
docker rm jenkins-master
docker run -p 8080:8080 --name=jenkins-master -d --env JAVA_OPTS="-Xmx8192m" jenkins/jenkins

det borde ge Jenkins en trevlig 8 GB minnespool och utrymme för att hantera sophämtning.

steg 3C: öka ANSLUTNINGSPOOLEN

på Riot får vi mycket trafik till vår Jenkins-server, så vi har lärt oss att ge Jenkins lite mer andningsrum. Kör följande

docker stop jenkins-master
docker rm jenkins-master

det ger Jenkins en fin baspool av hanterare och ett lock. Tillfälligt har du nu lärt dig hur man använder både JAVA OPTS och JENKINS OPTS som miljövariabler på ett meningsfullt sätt. Observera att detta fungerar på grund av hur Cloudbees bekvämt strukturerade sin Jenkins Dockerfile.

steg 4: att sätta ihop allt

jag placerade allt vi lärt oss här i en enkel makefile så att du kan använda göra kommandon för att styra kör din Jenkins docker behållare. Du hittar den här:

  • https://github.com/maxfields2000/docker Jenkins_tutorial / träd / mästare / tutorial_01

du kan använda följande kommandon:

  • gör bygga-drar Jenkins image

  • gör run-Kör behållaren

  • gör stopp-stoppar behållaren

  • gör rena Stopp och tar bort den befintliga behållaren

du behöver inte använda makefile, jag tycker bara att det är lättare än att skriva ut hela körkommandot. Du kan enkelt sätta dessa i ett manus som du väljer istället.

förhoppningsvis ser du hur lätt det är att komma igång med Docker och Jenkins. Jag har försökt ge dig några grundläggande alternativ för att ta Standard Cloudbees Jenkins-behållaren och göra den lite mer användbar. Cloudbees har många användbara handledning för att köra sin behållare, till exempel hur man förinstallerar plugins och lagrar Jenkins-data.

det leder mig till framtida inlägg om ämnet. Denna behållare / bild är användbar men har några nackdelar: ingen konsekvent loggning, ingen uthållighet, ingen webbserverproxy framför den och inget rent sätt att garantera att du använder den version av Jenkins du vill ha. Detta tar upp frågor som: vad händer om du vill hålla dig till en äldre version? Eller vad händer om du vill använda den senaste tillgängliga släppperioden?

i nästa lektion ska jag täcka att göra denna behållare lite mer robust. Särskilt:

  • skapa din egen Dockerfile för att linda Cloudbees-basen

  • flytta några av miljövariablerna till den här nya bilden

  • skapa en loggmapp, inställningsbehörigheter och andra användbara Jenkins-kataloger och hämta Jenkins-loggarna medan den körs

lektion 2-en JENKINS BASE IMAGE WRAPPER

i föregående lektion diskuterade jag att skapa en utvecklingsmiljö för att köra Docker och experimenterade med Jenkins Docker-bilden från Cloudbees. Vi fann att det var enkelt och lätt att använda, med några fantastiska funktioner ur lådan. För att göra framsteg inom de förbättringsområden vi identifierade är Docker-koncepten som behandlas i denna lektion:

  • gör din egen Dockerfile

  • ställa in miljövariabler i en Dockerfile

  • skapa mappar och behörigheter i en Dockerfile

  • använda docker exec för att köra kommandon mot en löpande Behållare

gör din bas DOCKERFILE

vi vill göra några ändringar i hur Jenkins startar som standard. I den sista bloggen hanterade vi detta genom att skapa en makefile som passerade i argument som miljövariabler. Med tanke på att vi vill göra det varje gång kan vi bara flytta dem till vår egen Dockerfil. Dessutom kommer vår egen Dockerfile att låta oss låsa den version av Jenkins vi använder om Cloudbees uppdaterar deras och vi är inte redo att uppgradera.

vi gör detta i fyra steg:

1. Skapa en arbetskatalog

2. I din favorittextredigerare skapar du en ny fil som heter ”Dockerfile”

3. Lägg till följande i filen och spara den:

FROM jenkins/jenkins:2.112LABEL maintainer=""

4. Ange sedan på kommandoraden:

docker build -t myjenkins .

vad vi gjorde här var att dra en viss version av Jenkins bilden från den offentliga docker repo. Du hittar alla tillgängliga versioner här:

  • du kan alltid ställa in from-klausulen för att vara vilken version av bilden som är tillgänglig. Du kan dock inte bara ställa in versionen till vilken version av Jenkins du vill ha. Detta är bildversionen ”tag” eller” etikett ” och Cloudbees är tillräckligt bra för att matcha Jenkins-versionen inuti bilden. Cloudbees erbjuder ” jenkins / jenkins ”som ett bekvämt sätt att få den senaste versionen, eller” jenkins/jenkins:lts ”för att få den senaste” Long Term Support ” – versionen. I det här exemplet använder jag en specifik version. Dessa taggar som märker typer av utgåvor är bra men använder dem betyder att versionen av Jenkins kan förändras under dig vilket kan orsaka komplikationer om du inte var redo att uppgradera. Jag rekommenderar ”versionslåsning” som en allmän bästa praxis när man hanterar eventuella beroenden i Docker eller andra beroendehanteringsverktyg. Du vill att saker ska förändras när du tänker dem, inte tidigare. Det är därför jag använder en specifik version här.

    testa den nya DOCKERFILEN

    vi kan växla över till bilden mycket enkelt genom att ändra vårt docker run-kommando till följande:

    docker run -p 8080:8080 --name=jenkins-master -d --env JAVA_OPTS="-Xmx8192m" --env JENKINS_OPTS=" --handlerCountMax=300" myjenkins

    nu kan vi rensa dessa miljövariabler genom att placera dem i vår egen Dockerfile.

    lägga till miljövariabler i vår DOCKERFILE

    det är enkelt att lägga till standardinställningar för saker som miljövariabler i Dockerfiles. Detta ger också en fin del av självdokumentation. Och eftersom du alltid kan skriva över dessa när du kör Docker-behållaren finns det verkligen ingen nackdel.

    1. I din Dockerfile lägger du till följande rader efter raden ”MAINTAINER” :

    ENV JAVA_OPTS="-Xmx8192m"ENV JENKINS_OPTS=" --handlerCountMax=300"

    2. Spara och bygga om din bild:

    • docker build-t myjenkins .

    docker build -t myjenkins .

    ganska enkelt! Du kan testa att det fortfarande fungerar genom att ange följande tre kommandon:

    docker stop jenkins-master
    docker rm jenkins-master
    docker run -p 8080:8080 --name=jenkins-master -d myjenkins

    din bild ska börja rätt upp! Men hur vet du att miljövariablerna fungerade? Enkel: på samma sätt som du skulle kontrollera för att se vilka argument som startade din Jenkins-app normalt med ps. Och detta fungerar även om du utvecklar på Windows.

    kör ett grundläggande kommando mot din behållare

    för att bekräfta att Java – och Jenkins-alternativen är korrekt inställda kan vi köra ps i vår behållare och se den löpande Jenkins Java-processen genom att använda docker exec

    docker exec jenkins-master ps -ef | grep java

    du bör se något som liknar detta kom tillbaka

    jenkins 1 0 99 21:28 ? 00:00:35 java -Xmx8192m -jar /usr/share/jenkins/jenkins.war --handlerCountMax=300

    från detta kan du enkelt se att våra inställningar har fastnat. docker exec är ett enkelt sätt att utföra skalkommandon i din behållare och också ett otroligt enkelt sätt att inspektera dem. Detta fungerar även på Windows eftersom, kom ihåg, kommandot efter ”exec” körs inuti din behållare och är således baserat på vilken basbild din behållare använder.

    ställa in en LOGGMAPP

    i den tidigare bloggen noterade vi att vi förlorade synligheten i Jenkins-loggarna när vi körde vår behållare med daemonize-flaggan (- d). Vi vill använda den inbyggda Jenkins-funktionen för att ställa in en loggmapp. Vi kommer att behöva göra detta i vår Dockerfile och sedan passera i loggningsalternativet till Jenkins.

    låt oss Redigera vår Dockerfil igen. Mellan” MAINTAINER ” och första ENV-raden kommer vi att lägga till följande

    RUN mkdir /var/log/jenkins

    vi placerar kommandot på den här platsen i filen för att följa bästa praxis. Det är mer troligt att vi kommer att ändra miljövariablerna än dessa installationskataloger, och varje kommandorad i en Dockerfil blir i huvudsak sitt eget bildlager. Du maximerar lageråteranvändning genom att placera ofta ändrade objekt nära botten.

    Bygg nu din bild igen:

    docker build -t myjenkins

    du får ett fel som ser ut som

    ---> Running in 0b5ac2bce13bmkdir: cannot create directory '/var/log/jenkins': Permission denied

    inga problem. Detta beror på att standard Cloudbees-behållaren ställer in den löpande användaren till” Jenkins ” – användaren. Om du tittar på deras Dockerfile (finns här: https://github.com/ Jenkinsci/docker/blob/master/Dockerfile) bör du se, nära botten

    USER ${user}

    denna syntax kan vara lite förvirrande. Den använder Dockers bygga” argument ” så att du kan definiera användaren. Om du tittar längre upp i Docker-filen hittar du standardvärdet. Titta nära toppen av Dockerfilen för

    ARG user=jenkins

    detta skapar argumentet ”användare” (ARG) och ställer in det till Jenkins-användaren. Detta gör att du kan ändra användarnamnet som Jenkins använder när du ringer Docker build –build-arg somevariable=somevalue. Observera att detta bara fungerar om du bygger Dockerfilen från början. Du kan inte ändra dessa värden med en Docker pull eller en docker run. Du kan läsa mer om byggargument här. Eftersom vi använder en förbyggd version i vår FROM-klausul slutar vi med standardanvändaren: ”jenkins”.

    i normal Linux skulle du bara använda SUDO eller något annat sätt att skapa mappen (/var/log ägs av root). Lyckligtvis för oss Docker låter oss byta användare.

    Lägg till följande i din Dockerfile:

    1. Innan du kör mkdir linje Lägg till

    USER root

    2. Efter din körning mkdir linje Lägg till

    RUN chown -R jenkins:jenkins /var/log/jenkins

    3. Efter din körning chown linje Lägg till:

    USER jenkins

    Observera att vi också var tvungna att lägga till ett chown-kommando eftersom vi vill att Jenkins-användaren ska kunna skriva till mappen. Därefter sätter vi rot och återställer sedan Jenkins så att Dockerfilens beteende bevaras.

    Bygg nu din bild igen:

    docker build -t myjenkins .

    och… dina fel borde vara borta.

    med loggkataloguppsättningen (Observera: Du kan placera den här mappen var du vill, vi använder /var/log för konsistens) vi kan nu berätta för Jenkins att skriva till den mappen vid start genom att ändra JENKINS_OPTS miljövariabler.

    i din Dockerfile redigerar JENKINS_OPTS-raden så att den ser ut så här:

    • ENV JENKINS_OPTS= ” –handlerCountMax=300 –logfile=/var/log/jenkins/jenkins.logga in”

    ENV JENKINS_OPTS="--handlerCountMax=300 --logfile=/var/log/jenkins/jenkins.log"

    Bygg nu din bild en gång till

    docker build -t myjenkins .

    låt oss testa vår nya bild och om vi kan svans loggfilen! Prova följande kommandon

    docker stop jenkins-master
    docker rm jenkins-master
    docker run -p 8080:8080 --name=jenkins-master -d myjenkins

    med behållaren igång kan vi svans loggfilen om allt fungerade

    docker exec jenkins-master tail -f /var/log/jenkins/jenkins.log

    hämta loggar om JENKINS kraschar

    dags för en bonusrunda! Så länge vi diskuterar loggar presenterar Docker ett intressant problem om Jenkins kraschar. Behållaren slutar springa och docker exec fungerar inte längre. Så vad ska man göra?

    vi diskuterar mer avancerade sätt att fortsätta loggfilen senare. För tillfället, eftersom behållaren är stoppad kan vi kopiera filer ur den med kommandot docker cp. Låt oss simulera en krasch genom att stoppa behållaren och sedan hämta loggarna:

    1. ctrl-c för att avsluta loggfilen tail

    2. Kör följande kommandon

    docker stop jenkins-master
    docker cp jenkins-master:/var/log/jenkins/jenkins.log jenkins.log
    cat jenkins.log

    avslutande tankar

    du hittar allt arbete i min handledning Git repo (och den uppdaterade bekvämligheten makefile) här:

    • https://github.com/maxfields2000/docker Jenkins_tutorial / träd / mästare / tutorial_02

    genom att göra vår egen Dockerfil som sveper Cloudbees-filen kunde vi göra livet lite enklare för oss själva. Vi skapade en bekväm plats för att lagra loggarna och lärde oss att titta på dem med kommandot docker exec. Vi flyttade våra standardinställningar till Dockerfilen och nu kan vi lagra detta i källkontroll som en bra del av självdokumentation.

    vi har fortfarande en utmaning för datapersistens. Vi har lärt oss hur man drar loggfiler ur en stoppad Behållare (praktiskt när Jenkins kraschar). Men i allmänhet om vår container slutar förlorar vi fortfarande alla jobb vi skapade. Så utan uthållighet är denna Jenkins-bild bara användbar för lokal utveckling och testning.

    som leder oss till nästa artikel. Med våra fundament på plats-vårt eget Dockerfile-omslag, låst till en praktisk version av Jenkins – kan vi lösa uthållighetsproblemet. Nästa artikel kommer att undersöka dessa begrepp:

    • bevara Jenkins jobb och Plugin data

    • Docker data Persistens med volymer

    • skapa en datavolymbehållare

    • dela data i volymer med andra behållare

    för mer information, kolla in resten av den här serien:

    del i: tänker inuti behållaren
    del II: att sätta Jenkins i en Docker-behållare (den här artikeln)
    del III: Docker & Jenkins: Data som kvarstår
    del IV: Jenkins, Docker, Proxies och Compose
    Del V: Ta kontroll över din Docker-bild
    Del VI: bygga med Jenkins inuti en efemär Docker-behållare
    del VII: handledning: bygga med Jenkins inuti en efemär Docker-behållare
    del VIII: DockerCon Talk och historien hittills

Lämna ett svar

Din e-postadress kommer inte publiceras.