Sette opp en Nomad-klynge ved hjelp av Consul og integrering med Gitlab

Innledning

I det siste har populariteten til Kubernetes vokst raskt - flere og flere prosjekter implementerer den. Jeg ønsket å berøre en orkestrator som Nomad: den er perfekt for prosjekter som allerede bruker andre løsninger fra HashiCorp, for eksempel Vault og Consul, og selve prosjektene er ikke komplekse med tanke på infrastruktur. Dette materialet vil inneholde instruksjoner for å installere Nomad, kombinere to noder til en klynge, samt integrere Nomad med Gitlab.

Sette opp en Nomad-klynge ved hjelp av Consul og integrering med Gitlab

Prøvestativ

Litt om testbenken: tre virtuelle servere brukes med egenskapene til 2 CPU, 4 RAM, 50 Gb SSD, samlet til et felles lokalt nettverk. Deres navn og 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

Installasjon av Nomad, konsul. Opprette en Nomad-klynge

La oss starte med den grunnleggende installasjonen. Selv om oppsettet var enkelt, vil jeg beskrive det av hensyn til integriteten til artikkelen: det ble i hovedsak opprettet fra utkast og notater for rask tilgang når det er nødvendig.

Før vi begynner praksis, vil vi diskutere den teoretiske delen, fordi på dette stadiet er det viktig å forstå den fremtidige strukturen.

Vi har to nomadenoder og vi ønsker å kombinere dem til en klynge, og i fremtiden vil vi også trenge automatisk klyngeskalering - til dette trenger vi Consul. Med dette verktøyet blir klynging og å legge til nye noder en veldig enkel oppgave: den opprettede Nomad-noden kobles til Consul-agenten, og kobler deretter til den eksisterende Nomad-klyngen. Derfor vil vi i begynnelsen installere Consul-serveren, konfigurere grunnleggende http-autorisasjon for webpanelet (det er uten autorisasjon som standard og kan nås på en ekstern adresse), samt Consul-agentene selv på Nomad-servere, hvoretter vi går bare videre til Nomad.

Å installere HashiCorps verktøy er veldig enkelt: i hovedsak flytter vi bare den binære filen til bin-katalogen, setter opp verktøyets konfigurasjonsfil og oppretter tjenestefilen.

Last ned Consul binærfil og pakk den ut i brukerens hjemmekatalog:

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/

Nå har vi en ferdig konsul-binær for videre konfigurasjon.

For å jobbe med Consul, må vi lage en unik nøkkel ved å bruke keygen-kommandoen:

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

La oss gå videre til å sette opp Consul-konfigurasjonen, lage en katalog /etc/consul.d/ med følgende struktur:

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

Bootstrap-katalogen vil inneholde en konfigurasjonsfil config.json - i den vil vi angi Consul-innstillingene. Dens innhold:

{
"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"]
}

La oss se på hoveddirektivene og deres betydning separat:

  • bootstrap: sant. Vi aktiverer automatisk tillegg av nye noder hvis de er tilkoblet. Jeg legger merke til at vi ikke angir det nøyaktige antallet forventede noder her.
  • server: sant. Aktiver servermodus. Konsul på denne virtuelle maskinen vil fungere som eneste server og master for øyeblikket, Nomads VM vil være klientene.
  • datasenter: dc1. Angi navnet på datasenteret for å opprette klyngen. Det må være identisk på både klienter og servere.
  • kryptere: din-nøkkelen. Nøkkelen, som også må være unik og matche på alle klienter og servere. Generert ved å bruke kommandoen consul keygen.
  • start_join. I denne listen angir vi en liste over IP-adresser som tilkoblingen skal gjøres til. For øyeblikket legger vi kun igjen vår egen adresse.

På dette tidspunktet kan vi kjøre konsul ved å bruke kommandolinjen:

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

Dette er en god måte å feilsøke på nå, men du vil ikke kunne bruke denne metoden fortløpende av åpenbare grunner. La oss lage en tjenestefil for å administrere Consul via systemd:

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

Innhold 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

Start Consul via systemctl:

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

La oss sjekke: tjenesten vår må kjøre, og ved å utføre kommandoen for konsulmedlemmer bør vi se serveren vår:

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

Neste trinn: installere Nginx og sette opp proxy og http-autorisasjon. Vi installerer nginx gjennom pakkebehandlingen og i /etc/nginx/sites-enabled katalogen lager vi en konfigurasjonsfil consul.conf med følgende innhold:

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";
    }
}

Ikke glem å lage en .htpasswd-fil og generere et brukernavn og passord for den. Denne varen er nødvendig for at nettpanelet ikke skal være tilgjengelig for alle som kjenner domenet vårt. Men når vi setter opp Gitlab, må vi forlate dette - ellers vil vi ikke kunne distribuere applikasjonen vår til Nomad. I mitt prosjekt er både Gitlab og Nomad kun på den grå nettet, så det er ikke noe slikt problem her.

På de resterende to serverne installerer vi Consul-agenter i henhold til følgende instruksjoner. Vi gjentar trinnene med den binære 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/

Analogt med den forrige serveren lager vi en katalog for konfigurasjonsfiler /etc/consul.d med følgende struktur:

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

Innholdet i config.json-filen:

{
    "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
     }

Lagre endringene og gå videre til å sette opp tjenestefilen, dens innhold:

/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 starter konsul på serveren. Nå, etter lansering, bør vi se den konfigurerte tjenesten i nsul-medlemmer. Dette vil bety at den har koblet seg til klyngen som klient. Gjenta det samme på den andre serveren, og etter det kan vi begynne å installere og konfigurere Nomad.

Mer detaljert installasjon av Nomad er beskrevet i den offisielle dokumentasjonen. Det er to tradisjonelle installasjonsmetoder: å laste ned en binær fil og kompilere fra kilden. Jeg velger den første metoden.

Note: Prosjektet utvikler seg veldig raskt, nye oppdateringer slippes ofte. Kanskje en ny versjon vil bli utgitt når denne artikkelen er ferdig. Derfor, før du leser, anbefaler jeg å sjekke den gjeldende versjonen av Nomad for øyeblikket og laste den ned.

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

Etter utpakking vil vi motta en Nomad binær fil som veier 65 MB - den må flyttes til /usr/local/bin.

La oss lage en datakatalog for Nomad og redigere tjenestefilen (den vil mest sannsynlig ikke eksistere i begynnelsen):

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

Lim inn følgende linjer der:

[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 imidlertid ikke hastverk med å lansere nomad - vi har ennå ikke opprettet konfigurasjonsfilen:

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 endelige katalogstrukturen vil være som følger:

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

Nomad.hcl-filen bør inneholde følgende konfigurasjon:

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

Innholdet i server.hcl-filen:

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
}

Ikke glem å endre konfigurasjonsfilen på den andre serveren - der må du endre verdien til http-direktivet.

Det siste på dette stadiet er å konfigurere Nginx for proxying og sette opp http-autorisasjon. Innhold i nomad.conf-filen:

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";
        }
        
}

Nå kan vi få tilgang til webpanelet via et eksternt nettverk. Koble til og gå til serversiden:

Sette opp en Nomad-klynge ved hjelp av Consul og integrering med Gitlab
Bilde 1. Liste over servere i Nomad-klyngen

Begge serverne vises vellykket i panelet, vi vil se det samme i utdataene fra nomade node status kommandoen:

Sette opp en Nomad-klynge ved hjelp av Consul og integrering med Gitlab
Bilde 2. Utgang av nomade node status kommando

Hva med konsul? La oss ta en titt. Gå til Consul-kontrollpanelet, til nodesiden:
Sette opp en Nomad-klynge ved hjelp av Consul og integrering med Gitlab
Bilde 3. Liste over noder i Consul-klyngen

Nå har vi en forberedt Nomad som jobber i samarbeid med Consul. I den siste fasen vil vi komme til den morsomme delen: å sette opp levering av Docker-containere fra Gitlab til Nomad, og også snakke om noen av dets andre særtrekk.

Opprette Gitlab Runner

For å distribuere docker-bilder til Nomad, vil vi bruke en egen løper med den binære Nomad-filen inni (her kan vi forresten merke oss en annen funksjon av Hashicorp-applikasjoner - individuelt er de en enkelt binær fil). Last den opp til runner-katalogen. La oss lage en enkel Dockerfile for den med følgende innhold:


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

I det samme prosjektet lager 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 et resultat vil vi ha et tilgjengelig bilde av Nomad-løperen i Gitlab-registeret, nå kan vi gå direkte til prosjektlageret, lage en pipeline og konfigurere Nomads nomadejobb.

Prosjektoppsett

La oss starte med jobbens fil for Nomad. Prosjektet mitt i denne artikkelen vil være ganske primitivt: det vil bestå av en oppgave. Innholdet i .gitlab-ci vil være som følger:

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

Her skjer distribusjonen manuelt, men du kan konfigurere den til å endre innholdet i prosjektkatalogen. Pipeline består av to stadier: bildemontering og distribusjon til nomad. I det første trinnet setter vi sammen et docker-bilde og skyver det inn i registeret vårt, og i det andre lanserer vi jobben vår 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" {}
                }
            }
        }
    }
}

Vær oppmerksom på at jeg har et privat register og for å kunne hente et docker-bilde må jeg logge på det. Den beste løsningen i dette tilfellet er å skrive inn en pålogging og passord i Vault og deretter integrere det med Nomad. Nomad støtter Vault. Men først, la oss installere de nødvendige retningslinjene for Nomad i selve Vault; de kan lastes ned:

# 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

Nå, etter å ha opprettet de nødvendige policyene, vil vi legge til integrasjon med Vault i oppgaveblokken i job.nomad-filen:

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

Jeg bruker autorisasjon etter token og registrerer den direkte her, det er også mulighet for å spesifisere token som en variabel når jeg starter nomadeagent:

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

Nå kan vi bruke nøklene med Vault. Operasjonsprinsippet er enkelt: vi lager en fil i Nomad jobb som vil lagre verdiene til variabler, for eksempel:

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 denne enkle tilnærmingen kan du konfigurere levering av containere til Nomad-klyngen og jobbe med den i fremtiden. Jeg vil si at jeg til en viss grad sympatiserer med Nomad - det er mer egnet for små prosjekter der Kubernetes kan forårsake ekstra kompleksitet og ikke vil realisere sitt fulle potensial. I tillegg er Nomad perfekt for nybegynnere – det er enkelt å installere og konfigurere. Men når jeg tester på noen prosjekter, støter jeg på et problem med de tidlige versjonene - mange grunnleggende funksjoner er rett og slett ikke der, eller de fungerer ikke som de skal. Jeg tror imidlertid at Nomad vil fortsette å utvikle seg og i fremtiden vil den få de funksjonene som alle trenger.

Forfatter: Ilya Andreev, redigert av Alexey Zhadan og Live Linux-teamet


Kilde: www.habr.com

Legg til en kommentar