Configurando un clúster Nomad usando Consul e integrando con Gitlab

Introdución

Recentemente, a popularidade de Kubernetes foi crecendo rapidamente; cada vez son máis os proxectos que o implementan. Quería tocar un orquestrador como Nomad: é perfecto para proxectos que xa utilizan outras solucións de HashiCorp, por exemplo, Vault e Consul, e os proxectos en si non son complexos en canto a infraestruturas. Este material conterá instrucións para instalar Nomad, combinando dous nodos nun clúster, así como para integrar Nomad con Gitlab.

Configurando un clúster Nomad usando Consul e integrando con Gitlab

Banco de probas

Un pouco sobre o banco de probas: utilízanse tres servidores virtuais coas características de 2 CPU, 4 RAM, SSD de 50 Gb, unidos nunha rede local común. Os seus nomes e enderezos IP:

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

Instalación de Nomad, Cónsul. Creando un clúster Nomad

Imos comezar coa instalación básica. Aínda que a configuración foi sinxela, describireina en aras da integridade do artigo: creouse esencialmente a partir de borradores e notas para un acceso rápido cando fose necesario.

Antes de comezar a práctica, comentaremos a parte teórica, xa que nesta fase é importante comprender a estrutura futura.

Temos dous nodos nómades e queremos combinalos nun clúster, e no futuro tamén necesitaremos a escala automática do clúster; para iso necesitaremos Consul. Con esta ferramenta, agrupar e engadir novos nodos convértese nunha tarefa moi sinxela: o nodo Nomad creado conéctase ao axente Consul e, a continuación, conéctase ao clúster Nomad existente. Polo tanto, ao principio instalaremos o servidor Consul, configuraremos a autorización http básica para o panel web (non ten autorización por defecto e pódese acceder a un enderezo externo), así como os propios axentes Consul nos servidores Nomad, despois de que só procederemos a Nomad.

Instalar as ferramentas de HashiCorp é moi sinxelo: esencialmente, só movemos o ficheiro binario ao directorio bin, configuramos o ficheiro de configuración da ferramenta e creamos o seu ficheiro de servizo.

Descarga o ficheiro binario de Consul e descomprimelo no directorio persoal do usuario:

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/

Agora temos un binario cónsul preparado para máis configuración.

Para traballar con Consul, necesitamos crear unha clave única usando o comando keygen:

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

Pasemos a configurar a configuración de Consul, creando un directorio /etc/consul.d/ coa seguinte estrutura:

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

O directorio de arranque conterá un ficheiro de configuración config.json - nel estableceremos a configuración de Consul. O seu contido:

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

Vexamos por separado as principais directivas e os seus significados:

  • bootstrap: verdade. Activamos a adición automática de novos nodos se están conectados. Observo que non indicamos aquí o número exacto de nós esperados.
  • servidor: verdade. Activa o modo servidor. Consul nesta máquina virtual actuará como o único servidor e mestre polo momento, a VM de Nomad será os clientes.
  • centro de datos: dc1. Especifique o nome do centro de datos para crear o clúster. Debe ser idéntico tanto en clientes como en servidores.
  • cifrar: a túa chave. A clave, que tamén debe ser única e coincidir en todos os clientes e servidores. Xerado mediante o comando consul keygen.
  • comezar_unir. Nesta lista indicamos unha lista de enderezos IP aos que se realizará a conexión. Polo momento só deixamos o noso propio enderezo.

Neste punto podemos executar consul usando a liña de comandos:

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

Esta é unha boa forma de depurar agora, non obstante, non poderás usar este método de forma continua por razóns obvias. Imos crear un ficheiro de servizo para xestionar Consul mediante systemd:

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

Contido do ficheiro 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

Iniciar Consul mediante systemctl:

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

Comprobamos: o noso servizo debe estar en execución, e ao executar o comando dos membros do cónsul deberíamos ver o noso servidor:

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

Próxima etapa: instalar Nginx e configurar o proxy e a autorización http. Instalamos nginx a través do xestor de paquetes e no directorio /etc/nginx/sites-enabled creamos un ficheiro de configuración consul.conf co seguinte contido:

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

Non esquezas crear un ficheiro .htpasswd e xerar un nome de usuario e contrasinal para el. Este elemento é necesario para que o panel web non estea dispoñible para todos os que coñezan o noso dominio. Non obstante, ao configurar Gitlab, teremos que abandonar isto; se non, non poderemos implementar a nosa aplicación en Nomad. No meu proxecto, tanto Gitlab como Nomad só están na web gris, polo que non hai tal problema aquí.

Nos dous servidores restantes instalamos axentes Consul segundo as seguintes instrucións. Repetimos os pasos co ficheiro binario:

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/

Por analoxía co servidor anterior, creamos un directorio para os ficheiros de configuración /etc/consul.d coa seguinte estrutura:

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

Contido do ficheiro 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
     }

Garda os cambios e continúa coa configuración do ficheiro de servizo, o seu contido:

/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

Lanzamos consul no servidor. Agora, despois do lanzamento, deberíamos ver o servizo configurado nos membros de nsul. Isto significará que se conectou correctamente ao clúster como cliente. Repita o mesmo no segundo servidor e despois podemos comezar a instalar e configurar Nomad.

A instalación máis detallada de Nomad descríbese na súa documentación oficial. Existen dous métodos de instalación tradicionais: descargar un ficheiro binario e compilar desde a fonte. Vou escoller o primeiro método.

Nota: O proxecto está a desenvolverse moi rapidamente, moitas veces lánzanse novas actualizacións. Quizais se publique unha nova versión cando este artigo estea rematado. Por iso, antes de ler, recoméndoche comprobar a versión actual de Nomad neste momento e descargala.

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

Despois de desempaquetar, recibiremos un ficheiro binario Nomad cun peso de 65 MB; debe moverse a /usr/local/bin.

Imos crear un directorio de datos para Nomad e editar o seu ficheiro de servizo (o máis probable é que non exista ao principio):

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

Pega alí as seguintes liñas:

[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

Non obstante, non temos présa por lanzar Nomad - aínda non creamos o seu ficheiro de configuración:

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

A estrutura final do directorio será a seguinte:

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

O ficheiro nomad.hcl debería conter a seguinte configuración:

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

Contido do ficheiro 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
}

Non esquezas cambiar o ficheiro de configuración no segundo servidor; alí terás que cambiar o valor da directiva http.

A última cousa nesta fase é configurar Nginx para proxy e configurar a autorización http. Contido do ficheiro 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";
        }
        
}

Agora podemos acceder ao panel web a través dunha rede externa. Conéctate e vai á páxina de servidores:

Configurando un clúster Nomad usando Consul e integrando con Gitlab
Imaxe 1. Lista de servidores do clúster Nomad

Ambos servidores móstranse correctamente no panel, veremos o mesmo na saída do comando de estado do nodo nómada:

Configurando un clúster Nomad usando Consul e integrando con Gitlab
Imaxe 2. Saída do comando de estado do nodo nómada

E o cónsul? Imos botarlle unha ollada. Vaia ao panel de control de Consul, á páxina de nós:
Configurando un clúster Nomad usando Consul e integrando con Gitlab
Imaxe 3. Lista de nodos do clúster Consul

Agora temos un Nomad preparado que traballa en conxunto co Cónsul. Na fase final, chegaremos á parte divertida: configurar a entrega de contedores Docker de Gitlab a Nomad, e tamén falar sobre algunhas das súas outras características distintivas.

Creando Gitlab Runner

Para implementar imaxes docker en Nomad, utilizaremos un corredor separado co ficheiro binario Nomad dentro (aquí, por certo, podemos observar outra característica das aplicacións Hashicorp: individualmente son un único ficheiro binario). Cargao no directorio do corredor. Imos crear un Dockerfile sinxelo para el co seguinte contido:


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

No mesmo proxecto creamos .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}

Como resultado, teremos unha imaxe dispoñible do corredor Nomad no Rexistro de Gitlab, agora podemos ir directamente ao repositorio do proxecto, crear un Pipeline e configurar o traballo nómada de Nomad.

Configuración do proxecto

Imos comezar co ficheiro do traballo para Nomad. O meu proxecto neste artigo será bastante primitivo: consistirá nunha tarefa. O contido de .gitlab-ci será o seguinte:

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

Aquí o despregamento prodúcese manualmente, pero pode configuralo para cambiar o contido do directorio do proxecto. O pipeline consta de dúas etapas: a montaxe da imaxe e o seu despregamento a nómade. Na primeira fase, montamos unha imaxe docker e introducímola no noso Rexistro e, na segunda, lanzamos o noso traballo en 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" {}
                }
            }
        }
    }
}

Teña en conta que teño un Rexistro privado e para extraer correctamente unha imaxe do docker necesito iniciar sesión nel. A mellor solución neste caso é introducir un inicio de sesión e un contrasinal en Vault e despois integralo con Nomad. Nomad admite de forma nativa Vault. Pero primeiro, imos instalar as políticas necesarias para Nomad no propio Vault; pódense descargar:

# 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

Agora, unha vez creadas as políticas necesarias, engadiremos a integración con Vault no bloque de tarefas do ficheiro job.nomad:

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

Eu uso autorización por token e rexistroo directamente aquí, tamén hai a opción de especificar o token como variable ao iniciar o axente nómada:

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

Agora podemos usar as claves con Vault. O principio de funcionamento é sinxelo: creamos un ficheiro no traballo Nomad que almacenará os valores das variables, por exemplo:

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
}

Con este enfoque sinxelo, pode configurar a entrega de contedores ao clúster Nomad e traballar con el no futuro. Direi que ata certo punto simpatizo con Nomad: é máis axeitado para pequenos proxectos nos que Kubernetes pode causar complexidade adicional e non realizará todo o seu potencial. Ademais, Nomad é perfecto para principiantes: é fácil de instalar e configurar. Non obstante, ao probar algúns proxectos, atopo un problema coas súas primeiras versións: moitas funcións básicas simplemente non están alí ou non funcionan correctamente. Non obstante, creo que Nomad seguirá desenvolvéndose e no futuro adquirirá as funcións que todo o mundo precisa.

Autor: Ilya Andreev, editado por Alexey Zhadan e o equipo de Live Linux


Fonte: www.habr.com

Engadir un comentario