Konfigurera ett Nomad-kluster med Consul och integrera med Gitlab

Inledning

På senare tid har Kubernetes popularitet vuxit snabbt - fler och fler projekt implementerar den. Jag ville beröra en orkestrator som Nomad: den är perfekt för projekt som redan använder andra lösningar från HashiCorp, till exempel Vault och Consul, och själva projekten är inte komplexa vad gäller infrastruktur. Detta material kommer att innehålla instruktioner för att installera Nomad, kombinera två noder till ett kluster, samt integrera Nomad med Gitlab.

Konfigurera ett Nomad-kluster med Consul och integrera med Gitlab

Testbänk

Lite om testbänken: tre virtuella servrar används med egenskaperna 2 CPU, 4 RAM, 50 Gb SSD, förenade till ett gemensamt lokalt nätverk. Deras namn och IP-adresser:

  1. nomad-livelinux-01: 172.30.0.5
  2. nomad-livelinux-02: 172.30.0.10
  3. consul-livelinux-01: 172.30.0.15

Installation av Nomad, konsul. Skapa ett Nomad-kluster

Låt oss börja med den grundläggande installationen. Även om installationen var enkel, kommer jag att beskriva den för artikelns integritet: den skapades i huvudsak från utkast och anteckningar för snabb åtkomst när det behövs.

Innan vi börjar praktiken kommer vi att diskutera den teoretiska delen, eftersom det i detta skede är viktigt att förstå den framtida strukturen.

Vi har två nomadnoder och vi vill kombinera dem till ett kluster, och i framtiden kommer vi också att behöva automatisk klusterskalning - för detta behöver vi Consul. Med detta verktyg blir klustring och att lägga till nya noder en mycket enkel uppgift: den skapade Nomad-noden ansluter till Consul-agenten och ansluter sedan till det befintliga Nomad-klustret. Därför kommer vi i början att installera Consul-servern, konfigurera grundläggande http-auktorisering för webbpanelen (den är utan auktorisering som standard och kan nås på en extern adress), såväl som Consul-agenterna själva på Nomad-servrar, varefter vi fortsätter bara till Nomad.

Att installera HashiCorps verktyg är väldigt enkelt: i huvudsak flyttar vi bara den binära filen till bin-katalogen, ställer in verktygets konfigurationsfil och skapar dess servicefil.

Ladda ner Consul binärfil och packa upp den i användarens hemkatalog:

root@consul-livelinux-01:~# wget https://releases.hashicorp.com/consul/1.5.0/consul_1.5.0_linux_amd64.zip
root@consul-livelinux-01:~# unzip consul_1.5.0_linux_amd64.zip
root@consul-livelinux-01:~# mv consul /usr/local/bin/

Nu har vi en färdig konsul-binär för vidare konfiguration.

För att arbeta med Consul måste vi skapa en unik nyckel med hjälp av keygen-kommandot:

root@consul-livelinux-01:~# consul keygen

Låt oss gå vidare till att ställa in Consul-konfigurationen, skapa en katalog /etc/consul.d/ med följande struktur:

/etc/consul.d/
├── bootstrap
│   └── config.json

Bootstrap-katalogen kommer att innehålla en konfigurationsfil config.json - i den kommer vi att ställa in Consul-inställningarna. Dess innehåll:

{
"bootstrap": true,
"server": true,
"datacenter": "dc1",
"data_dir": "/var/consul",
"encrypt": "your-key",
"log_level": "INFO",
"enable_syslog": true,
"start_join": ["172.30.0.15"]
}

Låt oss titta på huvuddirektiven och deras betydelser separat:

  • bootstrap: Sann. Vi möjliggör automatisk tillägg av nya noder om de är anslutna. Jag noterar att vi inte anger det exakta antalet förväntade noder här.
  • server: Sann. Aktivera serverläge. Consul på denna virtuella maskin kommer att fungera som den enda servern och mastern för tillfället, Nomads VM kommer att vara klienterna.
  • datacenter:dc1. Ange namnet på datacentret för att skapa klustret. Det måste vara identiskt på både klienter och servrar.
  • kryptera: din nyckel. Nyckeln, som också måste vara unik och matcha på alla klienter och servrar. Genereras med kommandot consul keygen.
  • start_join. I den här listan anger vi en lista över IP-adresser som anslutningen kommer att göras till. För tillfället lämnar vi bara vår egen adress.

Vid det här laget kan vi köra consul med kommandoraden:

root@consul-livelinux-01:~# /usr/local/bin/consul agent -config-dir /etc/consul.d/bootstrap -ui

Detta är ett bra sätt att felsöka nu, men du kommer inte att kunna använda den här metoden fortlöpande av uppenbara skäl. Låt oss skapa en servicefil för att hantera Consul via systemd:

root@consul-livelinux-01:~# nano /etc/systemd/system/consul.service

Innehållet i filen consul.service:

[Unit]
Description=Consul Startup process
After=network.target
 
[Service]
Type=simple
ExecStart=/bin/bash -c '/usr/local/bin/consul agent -config-dir /etc/consul.d/bootstrap -ui' 
TimeoutStartSec=0
 
[Install]
WantedBy=default.target

Starta Consul via systemctl:

root@consul-livelinux-01:~# systemctl start consul

Låt oss kontrollera: vår tjänst måste vara igång, och genom att utföra kommandot för konsulmedlemmar bör vi se vår server:

root@consul-livelinux:/etc/consul.d# consul members
consul-livelinux    172.30.0.15:8301  alive   server  1.5.0  2         dc1  <all>

Nästa steg: installera Nginx och ställa in proxy och http-auktorisering. Vi installerar nginx genom pakethanteraren och i katalogen /etc/nginx/sites-enabled skapar vi en konfigurationsfil consul.conf med följande innehåll:

upstream consul-auth {
    server localhost:8500;
}

server {

    server_name consul.doman.name;
    
    location / {
      proxy_pass http://consul-auth;
      proxy_set_header Host $host;
      auth_basic_user_file /etc/nginx/.htpasswd;
      auth_basic "Password-protected Area";
    }
}

Glöm inte att skapa en .htpasswd-fil och skapa ett användarnamn och lösenord för den. Denna artikel krävs för att webbpanelen inte ska vara tillgänglig för alla som känner till vår domän. Men när vi ställer in Gitlab måste vi överge detta - annars kommer vi inte att kunna distribuera vår applikation till Nomad. I mitt projekt finns både Gitlab och Nomad bara på den grå webben, så det finns inget sådant problem här.

På de återstående två servrarna installerar vi Consul-agenter enligt följande instruktioner. Vi upprepar stegen med den binära filen:

root@nomad-livelinux-01:~# wget https://releases.hashicorp.com/consul/1.5.0/consul_1.5.0_linux_amd64.zip
root@nomad-livelinux-01:~# unzip consul_1.5.0_linux_amd64.zip
root@nomad-livelinux-01:~# mv consul /usr/local/bin/

I analogi med den tidigare servern skapar vi en katalog för konfigurationsfiler /etc/consul.d med följande struktur:

/etc/consul.d/
├── client
│   └── config.json

Innehållet i filen config.json:

{
    "datacenter": "dc1",
    "data_dir": "/opt/consul",
    "log_level": "DEBUG",
    "node_name": "nomad-livelinux-01",
    "server": false,
    "encrypt": "your-private-key",
    "domain": "livelinux",
    "addresses": {
      "dns": "127.0.0.1",
      "https": "0.0.0.0",
      "grpc": "127.0.0.1",
      "http": "127.0.0.1"
    },
    "bind_addr": "172.30.0.5", # локальный адрес вм
    "start_join": ["172.30.0.15"], # удаленный адрес консул сервера
    "ports": {
      "dns": 53
     }

Spara ändringarna och gå vidare till att ställa in tjänstefilen, dess innehåll:

/etc/systemd/system/consul.service:

[Unit]
Description="HashiCorp Consul - A service mesh solution"
Documentation=https://www.consul.io/
Requires=network-online.target
After=network-online.target

[Service]
User=root
Group=root
ExecStart=/usr/local/bin/consul agent -config-dir=/etc/consul.d/client
ExecReload=/usr/local/bin/consul reload
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

Vi startar konsul på servern. Nu, efter lanseringen, bör vi se den konfigurerade tjänsten i nsul-medlemmar. Detta kommer att innebära att den framgångsrikt har anslutit till klustret som en klient. Upprepa samma sak på den andra servern och efter det kan vi börja installera och konfigurera Nomad.

Mer detaljerad installation av Nomad beskrivs i dess officiella dokumentation. Det finns två traditionella installationsmetoder: nedladdning av en binär fil och kompilering från källkod. Jag väljer den första metoden.

Notera: Projektet utvecklas mycket snabbt, nya uppdateringar släpps ofta. Kanske kommer en ny version att släppas när den här artikeln är klar. Därför, innan du läser, rekommenderar jag att du kontrollerar den aktuella versionen av Nomad för tillfället och laddar ner den.

root@nomad-livelinux-01:~# wget https://releases.hashicorp.com/nomad/0.9.1/nomad_0.9.1_linux_amd64.zip
root@nomad-livelinux-01:~# unzip nomad_0.9.1_linux_amd64.zip
root@nomad-livelinux-01:~# mv nomad /usr/local/bin/
root@nomad-livelinux-01:~# nomad -autocomplete-install
root@nomad-livelinux-01:~# complete -C /usr/local/bin/nomad nomad
root@nomad-livelinux-01:~# mkdir /etc/nomad.d

Efter uppackning får vi en Nomad binär fil som väger 65 MB - den måste flyttas till /usr/local/bin.

Låt oss skapa en datakatalog för Nomad och redigera dess servicefil (den kommer troligen inte att existera i början):

root@nomad-livelinux-01:~# mkdir --parents /opt/nomad
root@nomad-livelinux-01:~# nano /etc/systemd/system/nomad.service

Klistra in följande rader där:

[Unit]
Description=Nomad
Documentation=https://nomadproject.io/docs/
Wants=network-online.target
After=network-online.target

[Service]
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/local/bin/nomad agent -config /etc/nomad.d
KillMode=process
KillSignal=SIGINT
LimitNOFILE=infinity
LimitNPROC=infinity
Restart=on-failure
RestartSec=2
StartLimitBurst=3
StartLimitIntervalSec=10
TasksMax=infinity

[Install]
WantedBy=multi-user.target

Vi har dock ingen brådska att lansera nomad - vi har ännu inte skapat dess konfigurationsfil:

root@nomad-livelinux-01:~# mkdir --parents /etc/nomad.d
root@nomad-livelinux-01:~# chmod 700 /etc/nomad.d
root@nomad-livelinux-01:~# nano /etc/nomad.d/nomad.hcl
root@nomad-livelinux-01:~# nano /etc/nomad.d/server.hcl

Den slutliga katalogstrukturen blir som följer:

/etc/nomad.d/
├── nomad.hcl
└── server.hcl

Filen nomad.hcl bör innehålla följande konfiguration:

datacenter = "dc1"
data_dir = "/opt/nomad"

Innehållet i filen server.hcl:

server {
  enabled = true
  bootstrap_expect = 1
}

consul {
  address             = "127.0.0.1:8500"
  server_service_name = "nomad"
  client_service_name = "nomad-client"
  auto_advertise      = true
  server_auto_join    = true
  client_auto_join    = true
}

bind_addr = "127.0.0.1" 

advertise {
  http = "172.30.0.5"
}

client {
  enabled = true
}

Glöm inte att ändra konfigurationsfilen på den andra servern - där måste du ändra värdet på http-direktivet.

Det sista i detta skede är att konfigurera Nginx för proxy och ställa in http-auktorisering. Innehållet i filen nomad.conf:

upstream nomad-auth {
        server 172.30.0.5:4646;
}

server {

        server_name nomad.domain.name;
        
        location / {
	        proxy_pass http://nomad-auth;
	        proxy_set_header Host $host;
	        auth_basic_user_file /etc/nginx/.htpasswd;
		   auth_basic "Password-protected Area";
        }
        
}

Nu kan vi komma åt webbpanelen via ett externt nätverk. Anslut och gå till serversidan:

Konfigurera ett Nomad-kluster med Consul och integrera med Gitlab
Bild 1. Lista över servrar i Nomad-klustret

Båda servrarna visas framgångsrikt i panelen, vi kommer att se samma sak i utgången av nomadnodens statuskommando:

Konfigurera ett Nomad-kluster med Consul och integrera med Gitlab
Bild 2. Utdata från nomadnodens statuskommando

Hur är det med konsul? Låt oss ta en titt. Gå till Consul-kontrollpanelen, till nodsidan:
Konfigurera ett Nomad-kluster med Consul och integrera med Gitlab
Bild 3. Lista över noder i Consul-klustret

Nu har vi en förberedd Nomad som arbetar i samarbete med Consul. I slutskedet kommer vi till den roliga delen: att sätta upp leverans av Docker-containrar från Gitlab till Nomad, och även prata om några av dess andra utmärkande egenskaper.

Skapar Gitlab Runner

För att distribuera docker-bilder till Nomad kommer vi att använda en separat löpare med den binära Nomad-filen inuti (här kan vi förresten notera en annan funktion i Hashicorp-applikationer - individuellt är de en enda binär fil). Ladda upp den till löparkatalogen. Låt oss skapa en enkel Dockerfile för det med följande innehåll:


FROM alpine:3.9
RUN apk add --update --no-cache libc6-compat gettext
COPY nomad /usr/local/bin/nomad

I samma projekt skapar vi .gitlab-ci.yml:

variables:
  DOCKER_IMAGE: nomad/nomad-deploy
  DOCKER_REGISTRY: registry.domain.name
 

stages:
  - build

build:
  stage: build
  image: ${DOCKER_REGISTRY}/nomad/alpine:3
  script:
    - tag=${DOCKER_REGISTRY}/${DOCKER_IMAGE}:latest
    - docker build --pull -t ${tag} -f Dockerfile .
    - docker push ${tag}

Som ett resultat kommer vi att ha en tillgänglig bild av Nomad-löparen i Gitlab-registret, nu kan vi gå direkt till projektförrådet, skapa en pipeline och konfigurera Nomads nomadjobb.

Projektuppsättning

Låt oss börja med jobbets fil för Nomad. Mitt projekt i den här artikeln kommer att vara ganska primitivt: det kommer att bestå av en uppgift. Innehållet i .gitlab-ci kommer att vara följande:

variables:
  NOMAD_ADDR: http://nomad.address.service:4646
  DOCKER_REGISTRY: registry.domain.name
  DOCKER_IMAGE: example/project

stages:
  - build
  - deploy

build:
  stage: build
  image: ${DOCKER_REGISTRY}/nomad-runner/alpine:3
  script:
    - tag=${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${CI_COMMIT_SHORT_SHA}
    - docker build --pull -t ${tag} -f Dockerfile .
    - docker push ${tag}


deploy:
  stage: deploy
  image: registry.example.com/nomad/nomad-runner:latest
  script:
    - envsubst '${CI_COMMIT_SHORT_SHA}' < project.nomad > job.nomad
    - cat job.nomad
    - nomad validate job.nomad
    - nomad plan job.nomad || if [ $? -eq 255 ]; then exit 255; else echo "success"; fi
    - nomad run job.nomad
  environment:
    name: production
  allow_failure: false
  when: manual

Här sker distributionen manuellt, men du kan konfigurera den för att ändra innehållet i projektkatalogen. Pipeline består av två steg: bildmontering och dess utplacering till nomad. I det första steget sätter vi ihop en docker-bild och skjuter in den i vårt register, och i det andra lanserar vi vårt jobb i Nomad.

job "monitoring-status" {
    datacenters = ["dc1"]
    migrate {
        max_parallel = 3
        health_check = "checks"
        min_healthy_time = "15s"
        healthy_deadline = "5m"
    }

    group "zhadan.ltd" {
        count = 1
        update {
            max_parallel      = 1
            min_healthy_time  = "30s"
            healthy_deadline  = "5m"
            progress_deadline = "10m"
            auto_revert       = true
        }
        task "service-monitoring" {
            driver = "docker"

            config {
                image = "registry.domain.name/example/project:${CI_COMMIT_SHORT_SHA}"
                force_pull = true
                auth {
                    username = "gitlab_user"
                    password = "gitlab_password"
                }
                port_map {
                    http = 8000
                }
            }
            resources {
                network {
                    port "http" {}
                }
            }
        }
    }
}

Observera att jag har ett privat register och för att lyckas dra en docker-bild måste jag logga in på det. Den bästa lösningen i det här fallet är att ange ett användarnamn och lösenord i Vault och sedan integrera det med Nomad. Nomad har inbyggt stöd för Vault. Men först, låt oss installera de nödvändiga policyerna för Nomad i själva Vault; de kan laddas ner:

# Download the policy and token role
$ curl https://nomadproject.io/data/vault/nomad-server-policy.hcl -O -s -L
$ curl https://nomadproject.io/data/vault/nomad-cluster-role.json -O -s -L

# Write the policy to Vault
$ vault policy write nomad-server nomad-server-policy.hcl

# Create the token role with Vault
$ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json

Nu, efter att ha skapat de nödvändiga policyerna, kommer vi att lägga till integration med Vault i uppgiftsblocket i filen job.nomad:

vault {
  enabled = true
  address = "https://vault.domain.name:8200"
  token = "token"
}

Jag använder auktorisering per token och registrerar den direkt här, det finns också möjlighet att ange token som en variabel när man startar nomadagent:

$ VAULT_TOKEN=<token> nomad agent -config /path/to/config

Nu kan vi använda nycklarna med Vault. Funktionsprincipen är enkel: vi skapar en fil i Nomad jobb som kommer att lagra värdena för variabler, till exempel:

template {
                data = <<EOH
{{with secret "secrets/pipeline-keys"}}
REGISTRY_LOGIN="{{ .Data.REGISTRY_LOGIN }}"
REGISTRY_PASSWORD="{{ .Data.REGISTRY_LOGIN }}{{ end }}"

EOH
    destination = "secrets/service-name.env"
    env = true
}

Med detta enkla tillvägagångssätt kan du konfigurera leveransen av containrar till Nomad-klustret och arbeta med det i framtiden. Jag kommer att säga att jag i viss mån sympatiserar med Nomad - det är mer lämpligt för små projekt där Kubernetes kan orsaka ytterligare komplexitet och inte kommer att förverkliga sin fulla potential. Plus, Nomad är perfekt för nybörjare – det är enkelt att installera och konfigurera. Men när jag testar på vissa projekt stöter jag på ett problem med dess tidiga versioner - många grundläggande funktioner finns helt enkelt inte där eller så fungerar de inte korrekt. Jag tror dock att Nomad kommer att fortsätta utvecklas och i framtiden skaffa sig de funktioner som alla behöver.

Författare: Ilya Andreev, redigerad av Alexey Zhadan och Live Linux-teamet


Källa: will.com

Lägg en kommentar