Blog

Driftsätta Jenkins på Kubernetes

OCT 26, 2017

En installation för att arbeta med Windows-byggslavar

Sami Alajrami

Sami is a DevOps consultant in our Oslo office. He comes from Palestine and has a PhD in Computing Science from Newcastle University. Sami’s previous work focused on cloud-based software development, model-based engineering, and safety-critical systems. He’s also an INTJ.

Installation och hantering av CI-servrar är en viktig uppgift för alla IT-team. Kubernetes och dess pakethanterare (Helm) erbjuder ett enkelt sätt att anpassa Jenkins-installationer. Låt oss se hur du gör detta och lägger till Windows-byggagenter.

Containerlösningar (t.ex. Docker) gör det möjligt för dina utvecklare att utveckla applikationer och skicka dem för testning eller driftsättning utan att behöva oroa sig för miljökonfiguration eller drabbas av fenomenet ”fungerar-på-min-maskin”.

Kubernetes (även kallat k8s) erbjuder ett orkestreringsramverk för containeriserade applikationer. Ramverket säkerställer att den containeriserade applikationen är tillgänglig genom hälsoövervakning och återställning av felande containrar.

Containers och k8s snabbar upp din utveckla-bygg-testa-driftsätt-cykel genom att abstrahera bort merparten av administrationen av infrastrukturen. Nya verktyg bygger på k8s och containers för att göra det möjligt att skapa och hantera infrastruktur, konfigurationer och även driftsättning av applikationer från kod. Sådana verktyg är bland annat Kops – ett verktyg för hantering av k8s-kluster – och Helm (ett verktyg för pakethantering i k8s). Med dessa verktyg kan du automatisera skapandet och hanteringen av ditt k8s-kluster. Du kan också enkelt driftsätta och hantera dina applikationer i k8s-klustret.

Kops gör det möjligt att definiera dina k8s-kluster med manifestfiler i Yaml-format. När du har skapat ett kluster kommer Kops att upprätthålla klustrets tillstånd i en S3-bucket.

Helm gör det möjligt att hantera driftsättning av applikationer i ditt k8s-kluster. Det erbjuder ett antal stabila paket – så kallade charts – som du kan driftsätta i ditt k8s-kluster direkt. Du kan också skapa ett eget chart och återanvända det.

Så driftsätter du Jenkins CI-server i ett k8s-kluster på AWS

I det här inlägget driftsätter vi Jenkins CI-server i ett k8s-kluster på AWS med Helm och ansluter sedan Windows-agenter till den. Följande steg behövs för att driftsätta Jenkins i k8s:

Observera: Även om det här inlägget använder AWS som molnleverantör kan koncepten och stegen som beskrivs här tillämpas på andra molnleverantörer som erbjuder liknande tjänster.

  1. Skapa ett k8s-kluster på AWS med Kops genom att följa den här guiden.

  2. När du har skapat klustret behöver du installera Kubectl och sedan installera Helm på den dator du använder för att hantera klustret. När Helm har installerats måste det initieras så att dess server installeras automatiskt. Den kallas Tiller i det k8s-kluster du använder.

  3. Nu när du har ett kluster och Helm är installerat och initierat kan du installera det stabila Jenkins-chartet i k8s-klustret med följande kommando: helm install --name <<your-release-name>> stable/jenkins

Skapa ett k8s-kluster på AWS med Kops genom att följa den här guiden.

När du har skapat klustret behöver du installera Kubectl och sedan installera Helm på den dator du använder för att hantera klustret. När Helm har installerats måste det initieras så att dess server installeras automatiskt. Den kallas Tiller i det k8s-kluster du använder.

Nu när du har ett kluster och Helm är installerat och initierat kan du installera det stabila Jenkins-chartet i k8s-klustret med följande kommando: helm install --name <<your-release-name>> stable/jenkins

Klart! Du har nu en Jenkins-master driftsatt i ditt kluster och exponerad för omvärlden med hjälp av en lastbalanserare (AWS ELB i det här fallet). Helms utdata visar hur du hämtar URL:en till din Jenkins-master och administratörslösenordet.

Jenkins Helm chart output

Vad hände bakom kulisserna med det där Helm-kommandot på en rad?

Figuren nedan visar vad som har hänt. Helm har skapat en deployment och ett par tjänster i ditt k8s-kluster. Deploymenten definierar ett önskat tillstånd för den pod som innehåller Jenkins-mastern. Det gör att k8s kan starta en ny pod som kör en Jenkins-master i en Docker-container om den aktuella poden slutar fungera. Eftersom poddar är tillfälliga gör tjänsterna som skapades i detta steg det möjligt för andra poddar och applikationer att nå Jenkins-mastern med ett DNS-namn för tjänsten, i stället för IP-adressen till den underliggande poden. Jenkins-masterns port exponeras externt, så att den kan nås från var som helst på internet, med molnleverantörens lastbalanserare (i det här fallet AWS ELB). Oavsett vad som händer med poddarna i klustret kan du därför alltid nå din Jenkins-master via lastbalanserarens IP-adress. Jenkins-agenttjänsten exponeras däremot med Cluster IP, vilket innebär att den endast är åtkomlig inifrån klustret.

k8s services created by Helm

Men vänta! Hur kan jag anpassa mina Jenkins-konfigurationer?

Du behöver inte oroa dig, eftersom Jenkins Helm-chartet har en fil med konfigurerbara parametrar som du kan anpassa. Du kan till exempel ange vilka plugins som ska installeras med Jenkins och vilka Docker-images som ska användas för både mastern och agenterna.

Du kanske undrar – var är agenterna?

Vi använde standardkonfigurationen som följer med Jenkins Helm-chartet. I den konfigurationen levereras Jenkins med Jenkins Kubernetes-pluginet installerat. Pluginet gör det möjligt för mastern att skapa agenter vid behov som Docker-containrar i poddar. Det innebär att mastern skapar en agent dynamiskt i ditt k8s-kluster när det finns ett jobb. Agenten utför jobbet och tas sedan bort.

Nu kanske du undrar om det går att ha Windows-agenter, eller hur?

I ett tidigare inlägg diskuterade vi det aktuella stödet för Windows i k8s och drog slutsatsen att det för närvarande inte är tillräckligt moget för produktionsliknande miljöer när du använder Kops för att hantera ditt k8s-kluster. Därför rekommenderade vi att Windows-värdar skapas utanför klustret och får kommunicera med applikationer som driftsatts i ditt k8s-kluster. Följande diagram illustrerar den arkitektur vi använder:

adding windows slaves

Vi skapade en separat AWS VPC för Windows-VM:ar som kör permanenta Jenkins-slavar.

Ansluta Windows-slavar till Jenkins-mastern

Helm har exponerat Jenkins-agenttjänsten (som ansvarar för att ansluta slavar) endast för klustret (med tjänsttypen Cluster IP). Helm utgår från att alla slavar ansluter inifrån k8s-klustret. Windows-slavarna ansluter däremot utifrån klustret, som vi beskrev ovan.

Det finns två alternativ för att göra Jenkins-agenttjänsten tillgänglig för Windows-slavar som ansluter från Windows VPC:

  1. Exponera slavagenten med tjänsttypen NodePortNodePort exponerar tjänsten på en specifik port på alla klusternoder. Det gör tjänsten tillgänglig inifrån klustret via Cluster IP-adresser, inifrån k8s VPC via AWS privata IP-adresser och externt (utanför k8s VPC) via valfri offentlig IP-adress för någon av k8s-noderna. Problemet med den metoden är att k8s-noder inte är permanenta: när de försvinner ersätts de av nya noder (och därmed nya externa IP-adresser).

  2. Alternativt kan du exponera slavagenten med tjänsttypen LoadBalancerEn lastbalanserare ansluter alltid till Jenkins-agenttjänsten från Windows VPC, oavsett tjänstens interna IP-adress. Av säkerhetsskäl behöver du även här bara tillåta trafik från Windows VPC.

Exponera slavagenten med tjänsttypen NodePortNodePort exponerar tjänsten på en specifik port på alla klusternoder. Det gör tjänsten tillgänglig inifrån klustret via Cluster IP-adresser, inifrån k8s VPC via AWS privata IP-adresser och externt (utanför k8s VPC) via valfri offentlig IP-adress för någon av k8s-noderna. Problemet med den metoden är att k8s-noder inte är permanenta: när de försvinner ersätts de av nya noder (och därmed nya externa IP-adresser).

Alternativt kan du exponera slavagenten med tjänsttypen LoadBalancerEn lastbalanserare ansluter alltid till Jenkins-agenttjänsten från Windows VPC, oavsett tjänstens interna IP-adress. Av säkerhetsskäl behöver du även här bara tillåta trafik från Windows VPC.

Obs! För det första alternativet behöver du tillåta trafik på Jenkins Slavelistener-porten (standardvärde 50000) från din Windows VPC i säkerhetsgruppen för dina k8s-noder. Som standard blockerar denna säkerhetsgrupp anslutningar utanför k8s-klustrets VPC.

Obs! Om du har flera tjänster som behöver vara tillgängliga utanför ditt k8s-kluster kan du överväga att använda en HTTP-reverse proxy (till exempel Træfik) för att undvika höga kostnader för AWS ELB.

Nu kan du ha en Jenkins-master driftsatt i ditt k8s-kluster som kan skapa Linux-slavar på begäran inuti klustret. Den kan dessutom ansluta till permanenta Windows-slavar som körs på VM:ar utanför k8s-klustret. I ett kommande inlägg berättar vi om hur du provisionerar Jenkins Windows-buildslavar med Packer och Terraform. Håll utkik!

  • Moln
  • CI/CD

Subscribe to our newsletter