Consul'u kullanarak Nomad kümesi kurma ve Gitlab ile entegrasyon

Giriş

Son zamanlarda Kubernetes'in popülaritesi hızla artıyor - giderek daha fazla proje bunu uyguluyor. Nomad gibi bir orkestratöre değinmek istedim: Vault ve Consul gibi HashiCorp'un diğer çözümlerini halihazırda kullanan projeler için mükemmeldir ve projelerin kendisi de altyapı açısından karmaşık değildir. Bu materyal, Nomad'ı kurma, iki düğümü bir kümede birleştirme ve Nomad'ı Gitlab ile entegre etme talimatlarını içerecektir.

Consul'u kullanarak Nomad kümesi kurma ve Gitlab ile entegrasyon

deneme standı

Test tezgahı hakkında biraz bilgi: 2 CPU, 4 RAM, 50 Gb SSD özelliklerine sahip, ortak bir yerel ağda birleştirilmiş üç sanal sunucu kullanılıyor. İsimleri ve IP adresleri:

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

Nomad'ın kurulumu, Konsolos. Nomad kümesi oluşturma

Temel kurulumla başlayalım. Kurulum basit olmasına rağmen, makalenin bütünlüğü adına bunu anlatacağım: esasen gerektiğinde hızlı erişim için taslaklardan ve notlardan oluşturuldu.

Uygulamaya başlamadan önce teorik kısmı tartışacağız çünkü bu aşamada gelecekteki yapıyı anlamak önemlidir.

İki göçebe düğümümüz var ve bunları bir kümede birleştirmek istiyoruz ve gelecekte otomatik küme ölçeklendirmeye de ihtiyacımız olacak - bunun için Consul'a ihtiyacımız olacak. Bu araçla, kümeleme ve yeni düğümler eklemek çok basit bir görev haline gelir: oluşturulan Nomad düğümü Consul aracısına bağlanır ve ardından mevcut Nomad kümesine bağlanır. Bu nedenle, başlangıçta Consul sunucusunu kuracağız, web paneli için temel http yetkilendirmesini (varsayılan olarak yetkilendirmesizdir ve harici bir adresten erişilebilir) ve ayrıca Nomad sunucularında Consul temsilcilerinin kendilerini yapılandıracağız. sadece Nomad'a doğru ilerleyeceğiz.

HashiCorp'un araçlarını kurmak çok basittir: aslında ikili dosyayı bin dizinine taşıyoruz, aracın yapılandırma dosyasını ayarlıyoruz ve hizmet dosyasını oluşturuyoruz.

Consul ikili dosyasını indirin ve kullanıcının ana dizinine açın:

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/

Artık daha fazla yapılandırma için hazır bir konsolos ikili programımız var.

Consul ile çalışmak için keygen komutunu kullanarak benzersiz bir anahtar oluşturmamız gerekir:

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

Aşağıdaki yapıya sahip bir /etc/consul.d/ dizini oluşturarak Consul yapılandırmasını ayarlamaya geçelim:

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

Bootstrap dizini bir yapılandırma dosyası config.json içerecektir - içinde Consul ayarlarını ayarlayacağız. Onun içerikleri:

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

Ana direktiflere ve anlamlarına ayrı ayrı bakalım:

  • çizme atkısı: doğru. Yeni düğümlerin bağlı olması halinde otomatik olarak eklenmesini sağlıyoruz. Burada beklenen düğümlerin tam sayısını belirtmediğimizi unutmayın.
  • sunucu: doğru. Sunucu modunu etkinleştirin. Bu sanal makinedeki Consul şu anda tek sunucu ve master olarak görev yapacak, Nomad'ın VM'si ise istemciler olacak.
  • veri merkezi: dc1. Kümeyi oluşturmak için veri merkezinin adını belirtin. Hem istemcilerde hem de sunucularda aynı olmalıdır.
  • şifrelemek: senin anahtarın. Aynı zamanda benzersiz olması ve tüm istemcilerde ve sunucularda eşleşmesi gereken anahtar. Consul keygen komutu kullanılarak oluşturulmuştur.
  • start_join. Bu listede bağlantının kurulacağı IP adreslerinin bir listesini belirtiyoruz. Şu anda sadece kendi adresimizi bırakıyoruz.

Bu noktada komut satırını kullanarak consul'u çalıştırabiliriz:

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

Bu artık hata ayıklamanın iyi bir yoludur, ancak bariz nedenlerden dolayı bu yöntemi sürekli olarak kullanamayacaksınız. Consul'u systemd aracılığıyla yönetmek için bir hizmet dosyası oluşturalım:

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

consul.service dosyasının içeriği:

[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

Consul'u systemctl aracılığıyla başlatın:

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

Şimdi kontrol edelim: Hizmetimiz çalışıyor olmalı ve consul member komutunu çalıştırarak sunucumuzu görmeliyiz:

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

Sonraki aşama: Nginx'in kurulması ve proxy ve http yetkilendirmesinin ayarlanması. Nginx'i paket yöneticisi aracılığıyla kuruyoruz ve /etc/nginx/sites-enabled dizininde aşağıdaki içeriğe sahip bir consul.conf yapılandırma dosyası oluşturuyoruz:

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

Bir .htpasswd dosyası oluşturmayı ve bunun için bir kullanıcı adı ve şifre oluşturmayı unutmayın. Bu öğe, web panelinin alan adımızı bilen herkesin kullanımına açık olmaması için gereklidir. Ancak Gitlab'ı kurarken bundan vazgeçmek zorunda kalacağız - aksi takdirde uygulamamızı Nomad'a dağıtamayacağız. Benim projemde hem Gitlab hem de Nomad sadece gri web üzerinde olduğu için burada böyle bir sorun yok.

Geriye kalan iki sunucuya Consul Agent'ları aşağıdaki talimatlara göre kuruyoruz. Adımları ikili dosyayla tekrarlıyoruz:

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/

Önceki sunucuya benzer şekilde, /etc/consul.d yapılandırma dosyaları için aşağıdaki yapıya sahip bir dizin oluşturuyoruz:

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

Config.json dosyasının içeriği:

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

Değişiklikleri kaydedin ve servis dosyasını ve içeriğini kurmaya devam edin:

/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

Sunucuda consul'u başlatıyoruz. Artık lansmandan sonra nsul üyelerinde yapılandırılmış hizmeti görmeliyiz. Bu, kümeye istemci olarak başarıyla bağlandığı anlamına gelecektir. İkinci sunucuda da aynı işlemi tekrarlayın ve ardından Nomad'ı kurmaya ve yapılandırmaya başlayabiliriz.

Nomad'ın daha ayrıntılı kurulumu resmi belgelerinde açıklanmaktadır. İki geleneksel kurulum yöntemi vardır: ikili dosya indirmek ve kaynaktan derlemek. İlk yöntemi seçeceğim.

Dikkat: Proje çok hızlı gelişiyor, sıklıkla yeni güncellemeler yayınlanıyor. Belki bu makale tamamlandığında yeni bir sürüm yayınlanacaktır. Bu nedenle okumadan önce Nomad'ın güncel sürümünü kontrol edip indirmenizi tavsiye ederim.

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

Paketi açtıktan sonra 65 MB ağırlığında bir Nomad ikili dosyası alacağız - bu dosyanın /usr/local/bin dizinine taşınması gerekiyor.

Nomad için bir veri dizini oluşturalım ve servis dosyasını düzenleyelim (büyük olasılıkla başlangıçta mevcut olmayacaktır):

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

Aşağıdaki satırları oraya yapıştırın:

[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

Ancak nomad'ı başlatmak için acelemiz yok - henüz yapılandırma dosyasını oluşturmadık:

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

Son dizin yapısı aşağıdaki gibi olacaktır:

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

nomad.hcl dosyası aşağıdaki yapılandırmayı içermelidir:

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

Server.hcl dosyasının içeriği:

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
}

İkinci sunucudaki yapılandırma dosyasını değiştirmeyi unutmayın; orada http yönergesinin değerini değiştirmeniz gerekecektir.

Bu aşamadaki son şey, Nginx'i proxy için yapılandırmak ve http yetkilendirmesini ayarlamaktır. nomad.conf dosyasının içeriği:

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

Artık web panelimize harici bir ağ üzerinden erişebiliyoruz. Bağlanın ve sunucular sayfasına gidin:

Consul'u kullanarak Nomad kümesi kurma ve Gitlab ile entegrasyon
Resim 1. Nomad kümesindeki sunucuların listesi

Her iki sunucu da panelde başarıyla görüntüleniyor, nomad node status komutunun çıktısında da aynı şeyi göreceğiz:

Consul'u kullanarak Nomad kümesi kurma ve Gitlab ile entegrasyon
Resim 2. Göçebe düğüm durumu komutunun çıktısı

Peki ya Konsolos? Hadi bir göz atalım. Consul kontrol paneline, düğümler sayfasına gidin:
Consul'u kullanarak Nomad kümesi kurma ve Gitlab ile entegrasyon
Resim 3. Consul kümesindeki düğümlerin listesi

Artık Konsül ile birlikte çalışan hazırlıklı bir Göçebemiz var. Son aşamada işin eğlenceli kısmına geçeceğiz: Docker konteynerlerinin Gitlab'dan Nomad'a teslimatını ayarlamak ve ayrıca diğer bazı ayırt edici özelliklerinden bahsetmek.

Gitlab Runner'ı Oluşturma

Docker görüntülerini Nomad'a dağıtmak için, içinde Nomad ikili dosyası bulunan ayrı bir çalıştırıcı kullanacağız (bu arada, burada Hashicorp uygulamalarının başka bir özelliğine dikkat çekebiliriz - bunlar ayrı ayrı tek bir ikili dosyadır). Runner dizinine yükleyin. Bunun için aşağıdaki içeriğe sahip basit bir Docker dosyası oluşturalım:


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

Aynı projede .gitlab-ci.yml dosyasını oluşturuyoruz:

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}

Sonuç olarak, Gitlab Registry'de Nomad runner'ın mevcut bir görüntüsüne sahip olacağız, artık doğrudan proje deposuna gidebilir, bir Pipeline oluşturabilir ve Nomad'ın nomad işini yapılandırabiliriz.

Proje kurulumu

Nomad için iş dosyasıyla başlayalım. Bu makaledeki projem oldukça ilkel olacak: tek bir görevden oluşacak. .gitlab-ci'nin içeriği aşağıdaki gibi olacaktır:

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

Burada dağıtım manuel olarak gerçekleşir, ancak bunu proje dizininin içeriğini değiştirecek şekilde yapılandırabilirsiniz. İşlem hattı iki aşamadan oluşur: görüntü birleştirme ve nomad'a dağıtımı. İlk aşamada bir docker imajı oluşturup Registry'mize gönderiyoruz, ikinci aşamada ise Nomad'da işimizi başlatıyoruz.

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

Lütfen özel bir Kayıt Defterim olduğunu ve bir liman işçisi görüntüsünü başarıyla çekmek için oturum açmam gerektiğini unutmayın. Bu durumda en iyi çözüm, Vault'a bir kullanıcı adı ve şifre girmek ve ardından bunu Nomad ile entegre etmektir. Nomad, Vault'u yerel olarak destekler. Ancak önce Nomad için gerekli politikaları Vault'a yükleyelim; bunlar indirilebilir:

# 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

Artık gerekli politikaları oluşturduktan sonra job.nomad dosyasındaki görev bloğuna Vault ile entegrasyon ekleyeceğiz:

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

Yetkilendirmeyi belirteçle kullanıyorum ve doğrudan buraya kaydediyorum, ayrıca göçebe aracıyı başlatırken belirteci değişken olarak belirtme seçeneği de var:

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

Artık anahtarları Vault ile kullanabiliriz. Çalışma prensibi basittir: Nomad işinde değişkenlerin değerlerini saklayacak bir dosya oluştururuz, örneğin:

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
}

Bu basit yaklaşımla konteynerlerin Nomad kümesine teslimini yapılandırabilir ve gelecekte onunla çalışabilirsiniz. Nomad'a bir dereceye kadar sempati duyduğumu söyleyeceğim - Kubernetes'in ek karmaşıklığa neden olabileceği ve tam potansiyelini gerçekleştiremeyeceği küçük projeler için daha uygundur. Ayrıca Nomad yeni başlayanlar için mükemmeldir; kurulumu ve yapılandırması kolaydır. Ancak bazı projeleri test ederken, ilk sürümlerinde bir sorunla karşılaştım; birçok temel işlev orada değil veya düzgün çalışmıyor. Ancak Nomad'ın gelişmeye devam edeceğine ve gelecekte herkesin ihtiyaç duyduğu fonksiyonları kazanacağına inanıyorum.

Yazar: Ilya Andreev, Alexey Zhadan ve Live Linux ekibi tarafından düzenlendi


Kaynak: habr.com

Yorum ekle