3sky's notes

Minimalistyczny blog o TI.

Cloud-init z DigitalOcean

2021-09-20 4 min czytania 3sky

Witam

Kolejny artykuł z serii zbuduj coś sam. Ostatni był skupiony na Kubernetesie. Teraz postaram się zbudować odrobine inny projekt poboczny. Zawsze chcialem się nauczyć SaltStacka. Będąc szczerym, jestem ogromnym fanem Ansibla, który jest nudny, ale dziala. Czasami jednak mam problem z synchronizacją kont moich deweloperów. Dodatkowo tworzenie wielu użytkowników oraz śledzenie ich ustawień bez obsługi stanów jest trudne. W związku z tym zdecydowałem się na rozpoznanie nowego narzędzia. Dodatkowo cloud-init z DigitalOcean API brzmi jak zabawa.

Komponenty

Brak SaltStacka na ten moment, jedynie ustawienie infrastruktury.

Ustawienie środowiska

Żeby zbudować naszą infrastrukturę nie potrzebujemy wielu elementów. Pierwszym z nich jest Access Token. DigitalOcean dostarcza świetną dokumentację, więc odysłam do niej. Kiedy już dostaniemy token, kolejnym krokiem będzie uzyskanie nazwy regiony w którym chcemy zbudować nasz serwer. Możemy to zrobić za pomocą API, doctl lub po prostu wyszukać w Google. Osobiście bardzo lubie CLI, które dostarcza DigitalOcean, które dodatkowo posiada autouzupełnianie w ZSH(hurra!)

$ doctl compute region list
Slug    Name               Available
nyc1    New York 1         true
sfo1    San Francisco 1    false
nyc2    New York 2         false
ams2    Amsterdam 2        false
sgp1    Singapore 1        true
lon1    London 1           true
nyc3    New York 3         true
ams3    Amsterdam 3        true
fra1    Frankfurt 1        true
tor1    Toronto 1          true
sfo2    San Francisco 2    false
blr1    Bangalore 1        true
sfo3    San Francisco 3    true

Jesteśmy zainteresowani zmienną slug. W moim przypadku będzie to fra1, ponieważ znajduje się w Polsce. Na szczęście Ty możesz wybrać co tylko chcesz. Konfiguracja jest gotowa, teraz możemy się zabrać za “zakodowanie” czegoś.

Cloud-init

Czemu cloud-init? Ponieważ to popularny mechanizm skryptów startowych. Może być użyty w AWS, DO lub OpenStacku. Jest względnie prosty, startuje prawie w czasie podnoszenia się serwera wirtualnego i co jest ważne nie wymaga żadnego gotowego obrazu maszyny. Nie zrozum mnie źle, niezmienna infrastruktura jest świetna. Czasem po prostu chcemy taniego rozwiązania (brak kosztów przestrzeni dyskowej), lub gdy czas startu nie jest najważniejszy cloud-init, okazuję się bardzo przydatny.

Zawartość pliku

#cloud-config
# stworzenie użytkownika z 
# kluczami ssh, uprawnieniami, itd
users:
  - name: kuba
    ssh-authorized-keys:
      - [email protected] AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAILjtneTPZiRcjxcM2xiAvvk1BvZGyBibtTx0i+szJutMAAAABHNzaDo= jakub.wolynko@yubi
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash

# następnie upgrade pakietów
package_update: true
package_upgrade: true
package_reboot_if_required: true

# poprawa konfiguracji ssh
write_files:
  - path: /etc/ssh/sshd_config
    content: |
         Port 31
         Protocol 2
         HostKey /etc/ssh/ssh_host_ecdsa_key
         HostKey /etc/ssh/ssh_host_ed25519_key
         UsePrivilegeSeparation yes
         KeyRegenerationInterval 3600
         ServerKeyBits 1024
         SyslogFacility AUTH
         LogLevel INFO
         LoginGraceTime 120
         PermitRootLogin no
         StrictModes yes
         RSAAuthentication yes
         PubkeyAuthentication yes
         IgnoreRhosts yes
         RhostsRSAAuthentication no
         HostbasedAuthentication no
         PermitEmptyPasswords no
         ChallengeResponseAuthentication no
         X11Forwarding no
         X11DisplayOffset 10
         PrintMotd no
         PrintLastLog yes
         TCPKeepAlive yes
         AcceptEnv LANG LC_*
         UsePAM yes
         AllowUsers kuba

# instalacja salt-master i salt-ssh
runcmd:
  - systemctl restart ssh
  - curl -fsSL -o /usr/share/keyrings/salt-archive-keyring.gpg https://repo.saltproject.io/py3/ubuntu/20.04/amd64/latest/salt-archive-keyring.gpg
  - echo "deb [signed-by=/usr/share/keyrings/salt-archive-keyring.gpg arch=amd64] https://repo.saltproject.io/py3/ubuntu/20.04/amd64/latest focal main" | tee /etc/apt/sources.list.d/salt.list
  - apt-get update -y
  - apt-get install salt-ssh salt-master -y

Terraformation

Terraform to branżowy standard. Możemy go używać z API DigitalOcean, GCP, czy nawer CloudFlare API. Niektórzy ludzie preferują CloudFormation, inni Pulumi lub Azure ARM. Osobiście lubie terrafom’a. Jest stabilny i działa. Mechanizm bucketów jest przydatny w sytuacji, gdy pracujemy w zespole. Czemu więc go nie używać?

Content

Będąc szczerym, projekt jest bardzo mały. Wszystko umieściłem w jednym pliku o nazwię main.tf

terraform {

  required_version = ">= 1.0.6"

  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

variable "do_token" {
  type = string
}

provider "digitalocean" {
  token = var.do_token
}

resource "digitalocean_droplet" "droplet" {
  image      = "ubuntu-20-04-x64"
  name       = "saltmaster"
  region     = "FRA1"
  size       = "s-1vcpu-1gb"
  monitoring = true
  tags       = ["salt", "edu", "terrafom"]
  user_data  = "${file("cloud-init.yaml")}"
}

output "public_ip" {
  description = "Droplet public IP"
  value       = digitalocean_droplet.droplet.ipv4_address
}

Dodatkowo, musimy gdzieś umieścić do_token. Dla przykładu w pliku o nazwie sample.tfvars lub jako argument wywołania komendy. Oba rozwiązania mają swoje wady i zalety. Plik jest łatwy w użyciu, trzeba jednak pamiętać, aby dodać go do .gitignore.

Jedna komenda później

Na koniec dni musimy uruchomić nasz Terraformowy projekt:

terraform init && terraform plan -var-file=sample.tfvar

Jeżeli wszystko jest ok, możemy zbudować naszą infrastrukturę.

terrafom apply -var-file=sample.tfvars -auto-approve

Zalogowanie na nową maszynę.

ssh kuba@$(tf output -raw public_ip) -p 31

Teraz możliwe jest sprawdzenie logów cloud-init. Mogę założyć, że niektóre aktualziacje wciąż trwają.

sudo tail -f /var/logs/cloud-init.log

Podsumowanie

Nie ma repozytorium dla tego projektu. Jego struktura jest prosta.

.
├── cloud-init.yaml
├── main.tf
└── sample.tfvars

Najbardziej interesującym narzędziem w tym artykule jest cloud-init, który to może być bardzo pomocny w wielu przypadkach. Możemy go użyć do zbudowania infrastruktury chmurowej, małego wewnętrzengo projektu, a nawet przebudować całą flotę maszyn wirtualnych na OpenStacku. W mojej opinii, ważne jest, aby każda osoba związana z DevOps’em była choć zaznajomiona z tą koncepcją. Nawet jeżeli nie użyje tego na produkcji. Terraform to terraform, nie ma tu nic do dodania. DigitalOcean jest proste, dostępne cenowo i stabilne. Co będzie następne? Postaram się skupić na SaltStacku.