Blog

Driftsätta Jenkins på Kubernetes

OCT 26, 2017

En installation för arbete med Windows-byggagenter

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-buildslavar.

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

Kubernetes (även kallat k8s) erbjuder ett ramverk för orkestrering av containerbaserade applikationer. Ramverket säkerställer att den containerbaserade applikationen är tillgänglig genom hälsoövervakning och återställning av containrar som har fallerat.

Containers och k8s snabbar upp din utveckla-bygg-testa-driftsätt-cykel genom att abstrahera bort merparten av administrationen av infrastrukturen. Nya verktyg bygger vidare på k8s och containers för att göra det möjligt att skapa och hantera infrastruktur, konfigurationer och till och med 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 pakethanteringsverktyg för k8s. Med dessa verktyg kan du automatisera skapandet och hanteringen av dina k8s-kluster. Dessutom kan du enkelt driftsätta och hantera dina applikationer i k8s-klustret.

Kops låter dig definiera dina k8s-kluster med manifestfiler skrivna i Yaml-format. När du har skapat ett kluster håller Kops klustrets status uppdaterad 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 – kallade charts – som du kan driftsätta direkt i ditt k8s-kluster. Alternativt kan du 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-slavar till den. Följande steg krävs för att driftsätta Jenkins i k8s:

Note: While this post uses AWS as a cloud provider. The concepts and steps discussed here can be mapped to other cloud providers offering similar services.

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

  2. När klustret är skapat behöver du installera Kubectl och sedan installera Helm på den maskin du använder för att hantera klustret. När Helm är installerat behöver 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 klustret är skapat behöver du installera Kubectl och sedan installera Helm på den maskin du använder för att hantera klustret. När Helm är installerat behöver 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 via en lastbalanserare (AWS ELB i det här fallet). Utdata från Helm visar hur du hämtar URL:en till din Jenkins-master och administratörslösenordet.

Jenkins Helm chart output

Vad hände i bakgrunden med det hä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 med en Jenkins-master i en Docker-container om den aktuella poden slutar fungera. Eftersom poddar är tillfälliga gör tjänsterna som skapas i det här steget det möjligt för andra poddar och applikationer att nå Jenkins-mastern med hjälp av 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 var som helst på internet, via molnleverantörens lastbalanserare (i det här fallet AWS ELB). Oavsett vad som händer med poddarna i klustret kan du alltså alltid komma åt din Jenkins-master via lastbalanserarens IP-adress. Jenkins-agenttjänsten exponeras däremot med Cluster IP, vilket innebär att den endast är tillgänglig 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 master och slavar.

Du kanske undrar – var är slavarna?

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 slavar vid behov som Docker-containrar i poddar. Det innebär att mastern skapar en slav direkt i ditt k8s-kluster varje gång det finns ett jobb. Slaven utför jobbet och tas sedan bort.

Nu kanske du undrar om du kan ha Windows-slavar, eller hur?

I ett tidigare inlägg diskuterade vi det aktuella stödet för Windows i k8s och drog slutsatsen att det vid den tidpunkten inte var 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 är driftsatta i ditt k8s-kluster. Diagrammet nedan illustrerar den arkitektur vi använder:

adding windows slaves

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

Ansluta Windows-slavarna till Jenkins-mastern

Helm har exponerat Jenkins agent-tjänsten (som ansvarar för att ansluta slaves) enbart för klustret (med tjänsttypen Cluster IP). Helm förutsätter att alla slaves ansluter inifrån k8s-klustret. Windows-slaves kommer däremot att ansluta utanför klustret, som vi beskrev ovan.

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

  1. Exponera slave-agenten med tjänsttypen NodePortNodePort exponerar tjänsten på en specifik port över alla klusternoder. Det gör tjänsten tillgänglig inifrån klustret med Cluster IP-adresser, från k8s VPC med privata AWS IP-adresser och externt (utanför k8s VPC) med valfri publik 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 med nya noder (och därmed nya externa IP-adresser).

  2. Eller exponera slave-agenten med tjänsttypen LoadBalancerEn lastbalanserare ansluter alltid till Jenkins agent-tjänsten från Windows VPC, oavsett tjänstens interna IP-adress. Av säkerhetsskäl behöver du även här endast tillåta trafik från Windows VPC.

Exponera slave-agenten med tjänsttypen NodePortNodePort exponerar tjänsten på en specifik port över alla klusternoder. Det gör tjänsten tillgänglig inifrån klustret med Cluster IP-adresser, från k8s VPC med privata AWS IP-adresser och externt (utanför k8s VPC) med valfri publik 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 med nya noder (och därmed nya externa IP-adresser).

Eller exponera slave-agenten med tjänsttypen LoadBalancerEn lastbalanserare ansluter alltid till Jenkins agent-tjänsten från Windows VPC, oavsett tjänstens interna IP-adress. Av säkerhetsskäl behöver du även här endast tillåta trafik från Windows VPC.

Note: for the first option you need to allow traffic on the Jenkins Slavelistener port (default 50000) from your Windows VPC in your k8s nodes’ security group. By default this security group blocks connections from outside the k8s cluster VPC.

Note: If you have multiple services that need to be accessible from outside your k8s cluster then you might consider using an HTTP reverse proxy (e.g. Træfik) to avoid receiving hefty bills for AWS ELB.

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

  • Cloud
  • CI/CD

Subscribe to our newsletter