WebDisk
Chmura publiczna

CloudMonkey (cmk) w praktyce: Apache CloudStack z terminala

Data publikacji:

Blog WebDisk · kategoria: Chmura publiczna · czas czytania: ~17 minut

W skrócie:- cmk (CloudMonkey) to oficjalny klient wiersza poleceń Apache CloudStack — platformy, na której działa WebDisk Cloud. Panel i cmk wywołują to samo API z tymi samymi uprawnieniami; terminal dokłada powtarzalność i zapis w historii, panel wygrywa przy konsoli maszyny i przy pierwszym rozglądaniu się.- Konfiguracja to jeden profil i para kluczy API z panelu; pierwsze sensowne polecenie (list virtualmachines) wykonasz w kilka minut, a wynik w JSON albo CSV idzie wprost do skryptu lub arkusza.- Uczciwie: cmk nie jest infrastrukturą jako kodem — nie zna stanu docelowego i nie cofnie zmian. Opis środowiska w repozytorium to Terraform albo Ansible; cmk jest do zapytań, operacji jednorazowych i szybkiej automatyzacji. >Nie pracujesz z terminalem? Pomiń bloki poleceń — opis platformy, porównanie metod zarządzania i sekcja o granicach narzędzia czytają się bez nich.

Jest piątek, 17:40. Do wyłączenia na weekend zostały dwadzieścia cztery maszyny testowe — w panelu to dwadzieścia cztery razy ta sama sekwencja: znajdź, szczegóły, menu, „Stop”, potwierdź. W poniedziałek to samo w drugą stronę, tylko że dwie maszyny ktoś przeoczy i przechodzą cały weekend. Nikt nie zrobił błędu — narzędzia do oglądania i decydowania użyto do pracy taśmowej.

Pokazujemy tu drugą drogę: zarządzanie chmurą z terminala — od budowy API CloudStacka, przez cmk od instalacji po skrypty i pułapki, po uczciwe granice narzędzia i przegląd żywych klientów. Przykłady wykonasz na dowolnym CloudStacku, w tym w chmurze publicznej WebDisk — zakres poleceń zależy od roli twojego konta i od usług operatora.

Czym jest Apache CloudStack i co z tej architektury widzi klient

CloudStack to orkiestrator IaaS, nie hypervisor. Sam niczego nie wirtualizuje — steruje hypervisorami (oprogramowaniem uruchamiającym maszyny wirtualne na fizycznym serwerze): KVM, VMware vSphere, XenServer/XCP-ng. Dokłada warstwę, której hypervisory nie mają: wielodostępność, sieci, magazyn, ewidencję zużycia i jedno API. Licencja Apache 2.0, pełnoprawny projekt fundacji Apache od marca 2013 roku — bez copyleftu, bez „open core” jednego producenta.

Wewnętrznie platforma jest zhierarchizowana: region → strefa → pod → klaster → host. Klient widzi z tej drabiny jeden szczebel — strefę (zone), zwykle jedno centrum danych. Pody, klastry i hosty widzi tylko administrator operatora, i to celowo: nie wybierasz serwera, na którym wyląduje maszyna.

Primary storage trzyma wolumeny maszyn — uruchomionych i zatrzymanych — i stoi blisko hostów. Secondary storage jest zasobem całej strefy: szablony, obrazy ISO, snapshoty. Dlatego snapshot wolumenu trwa (dane wędrują między magazynami), a pierwsze uruchomienie maszyny ze świeżo zarejestrowanego szablonu jest wolniejsze niż kolejne.

Trzy typy maszyn systemowych, z którymi klient styka się na co dzień, działają w tle i nikt ich nie zamawia. SSVM obsługuje secondary storage. Console Proxy pośredniczy między przeglądarką a konsolą maszyny — dzięki niemu w panelu działa „Konsola”. Virtual Router realizuje usługi sieciowe: DHCP, DNS, source NAT, static NAT, przekierowanie portów, load balancing, zaporę i reguły ACL, VPN oraz endpoint metadanych dla cloud-inita. Architektonicznie to ważne: NAT, przekierowanie portów i load balancing nie są osobnymi bytami — sterujesz nimi tym samym API co maszynami. Jak są rozliczane, sprawdzisz w cenniku operatora.

Ostatnia rzecz, która zaskakuje w CLI: właścicielem zasobów jest konto, nie użytkownik. Użytkownicy to sposoby logowania; limity, rozliczenia i własność siedzą piętro wyżej. Osobnym pojemnikiem są projekty — z własnymi limitami i zużyciem, w API dostępne przez parametr projectid. Jeśli w panelu pracujesz w kontekście projektu, a w terminalu nie podasz projectid, zobaczysz inny zbiór maszyn. WebDisk Cloud działa na CloudStacku i KVM — o przeprowadzce z vSphere pisaliśmy przy okazji migracji z VMware do WebDisk Cloud.

Panel, API, CLI i IaC — cztery kształty tego samego dostępu

Wszystko, co robisz z CloudStackiem, przechodzi przez jeden punkt końcowy: ścieżkę /client/api na serwerze zarządzającym. Żądanie to zwykły HTTP GET albo POST z parametrem command; odpowiedź domyślnie w XML, a po dodaniu response=json — w JSON. Uwierzytelnia podpis HMAC-SHA1 liczony kluczem sekretnym na posortowanym i zamienionym na małe litery ciągu parametrów. Reszta narzędzi z tego artykułu to nakładki na to samo.

Nazwy poleceń są konsekwentne: czasownik + rzeczownikdeployVirtualMachine, listVirtualMachines, stopVirtualMachine, createNetwork, associateIpAddress, deleteSnapshot. Poleceń jest blisko dziewięciuset (migawka API w cmk 6.5.0 zna ich 880, z czego 370 asynchronicznych), ale zwykłe konto zobaczy wyraźnie mniej — lista zależy od roli i wersji platformy. Schemat jest na tyle regularny, że po dniu pracy zgaduje się te nazwy poprawnie. Dwie rzeczy od początku: część poleceń jest asynchroniczna — zwraca natychmiast identyfikator zadania (jobid), a nie wynik; i klucz API dziedziczy uprawnienia roli konta, więc CLI nie jest bocznym wejściem z większymi prawami.

Najważniejsze: interfejs graficzny nie ma uprzywilejowanego kanału do platformy. Panel — jakikolwiek — jest zwykłym klientem tego samego /client/api, a listę funkcji odkrywa poleceniem listApis; to samo polecenie napędza autouzupełnianie w cmk. Wniosek bywa odwrotny do intuicji: nowa możliwość platformy bywa w API wcześniej, niż dostanie własny formularz.

Stąd cztery metody zarządzania — nie poziomy zaawansowania, tylko kształty tego samego dostępu:

  • Panel — odkrywalność i kontekst. Rozwijane listy rozwiązują za ciebie UUID-y, formularze pilnują kolejności zależności, a konsola maszyny jest praktycznie tylko tutaj. Nie skaluje się i nie zostawia procedury.
  • Surowe API — pełna kontrola, zero zależności. Sam podpis to kilkadziesiąt linii kodu; kosztem jest reszta: paginacja, zadania asynchroniczne, zakres widoczności, kodowanie parametrów strukturalnych.
  • CLI (cmk i pokrewne) — powtarzalność bez pisania klienta; historia poleceń jest darmowym dziennikiem tego, co się wydarzyło.
  • IaC (Terraform, Ansible) — stan docelowy w repozytorium, przegląd zmian w pull requeście, odtworzenie środowiska od zera.

Warto znać dwa mechanizmy platformy. Operator może włączyć ograniczanie liczby wywołań API — skrypt odpytujący serwer w pętli potrafi go wyczerpać. Nowsze wydania CloudStacka mają webhooki: platforma sama wysyła powiadomienie HTTP przy zdarzeniach takich jak zmiana stanu maszyny, więc integracja nie musi polegać na odpytywaniu.

Czym jest cmk i dlaczego „cloudmonkey” oznacza dziś dwa różne narzędzia

To pierwsza przeszkoda, na której ludzie tracą godzinę: dwa narzędzia noszą tę samą nazwę. Starsze, cloudmonkey, jest w Pythonie i instaluje się przez pip. Nowsze, cmk, to napisany od nowa port w Go — pojedynczy plik wykonywalny, zgodny z CloudStackiem od wersji 4.9 wzwyż.

Wersji pythonowej nie należy dziś instalować: ostatnie wydanie na PyPI to 5.3.3.1 z 13 października 2021 roku — prawie pięć lat ciszy. Nikt nie ogłosił końca wsparcia, ale opis paczki sam odsyła do wersji w Go. Aktualne wydanie cmk to 6.5.0 z 26 sierpnia 2025 roku (stan na sierpień 2026); gałąź rozwojowa żyje, ale wydania wychodzą rzadko.

Przy przepisaniu na Go wypadły: format wyjścia XML, logowanie żądań do pliku i kolorowanie wyniku. W zamian jest jeden plik bez zależności — także dla Windows — i katalog konfiguracyjny ~/.cmk, celowo inny niż w starej wersji. Wysyłka żądań metodą POST weszła dla hasła i danych użytkownika w 6.4.0, a 6.5.0 uogólniła ją na wszystkie żądania i włączyła domyślnie (postrequest). Doszły też monit o kod uwierzytelniania dwuskładnikowego, wysyłanie szablonów i ISO oraz filtrowanie odwrotne parametrem exclude=.

Jak skonfigurować cmk w pięć minut?

Najprostsza droga to pobranie binarki z wydań projektu. Jest też formuła Homebrew (brew install cloudmonkey, polecenie nazywa się cmk), pakiet snap i obraz kontenera — w CI zawsze przypinaj konkretny tag, bo latest na Docker Hubie stoi nieaktualny od lat.

# Linux x86-64: pobierz do katalogu roboczego, zweryfikuj, dopiero potem instaluj
curl -fsSLO https://github.com/apache/cloudstack-cloudmonkey/releases/download/6.5.0/cmk.linux.x86-64
sha256sum cmk.linux.x86-64
sudo install -m 0755 cmk.linux.x86-64 /usr/local/bin/cmk
cmk version

Sumy kontrolne SHA-256 (i MD5) każdego pliku projekt publikuje w notatkach wydania — porównaj z nimi wynik sha256sum, zanim nadasz plikowi prawa wykonywania i wpuścisz go do katalogu systemowego. To binarka, która za chwilę dostanie twoje klucze API. Sprawdź przy okazji na stronie wydań, czy nie ma czegoś nowszego niż 6.5.0 — numer wersji jest wbity w adres pobierania.

Klucze API generujesz samodzielnie — parę „klucz API + klucz sekretny” i adres punktu końcowego API znajdziesz w panelu WebDisk Cloud, w ustawieniach użytkownika. Klucz sekretny to hasło: kto go ma, może w twojej chmurze to, co ty — pisaliśmy już, dlaczego długowieczne klucze statyczne są problemem.

Konfigurację ustawiaj poleceniami, nie edytorem tekstu — dlaczego, tłumaczy pułapka pierwsza.

cmk set profile moja-chmura # tworzy i włącza profil o tej nazwie
cmk set url <ADRES-PUNKTU-KONCOWEGO-API> # zwykle kończy się na /client/api
cmk set apikey <TWOJ-KLUCZ-API>
cmk set secretkey <TWOJ-KLUCZ-SEKRETNY>
cmk set output json # json | table | text | column | csv | default
cmk sync # pobiera listę API z serwera

Jedno zastrzeżenie: cmk zapisuje oba klucze otwartym tekstem w ~/.cmk/, więc katalog nigdy nie trafia do repozytorium ani do obrazu kontenera — dopisz go do .gitignore. Resztę konsekwencji, z rotacją klucza, zbiera pułapka szósta.

cmk sync to nie kosmetyka: buduje lokalną pamięć podręczną poleceń — stąd autouzupełnianie, lista parametrów i wiedza o tym, które polecenia są asynchroniczne. Pamięć jest osobna dla każdego profilu, więc po dodaniu drugiej chmury zrób sync i tam. Pierwszy test:

cmk list zones filter=id,name,networktype
cmk list virtualmachines listall=true filter=name,state,zonename

Bez argumentów cmk uruchamia powłokę interaktywną: historia, wyszukiwanie wstecz przez Ctrl+r, autouzupełnianie po Tab. Tab na parametrze kończącym się na id= wykonuje realne zapytanie do serwera i podpowiada UUID-y z nazwami zasobów — wygodne przy nauce, warte wyłączenia (set autocomplete false) na dużym środowisku.

Jak uruchomić maszynę wirtualną jednym ciągiem poleceń?

W CloudStacku wszystko identyfikują UUID-y, więc praca zaczyna się od rozpoznania. Poniżej kompletna ścieżka: cztery zapytania, klucz SSH, maszyna, adres publiczny, reguła dostępu.

# 1. Rozpoznanie środowiska — z tego bierzesz cztery identyfikatory
cmk list zones filter=id,name
cmk list serviceofferings filter=id,name,cpunumber,memory
cmk list templates templatefilter=executable zoneid=<ZONE-UUID> filter=id,name,ostypename
cmk list networks zoneid=<ZONE-UUID> filter=id,name,type,cidr

Parametr templatefilter w listTemplates jest obowiązkowy — executable oznacza „szablony, z których mogę uruchomić maszynę”.

# 2. Rejestracja klucza publicznego SSH (@ wczytuje zawartość pliku)
cmk register sshkeypair name=laptop publickey=@/home/uzytkownik/.ssh/id_ed25519.pub

# 3. Uruchomienie maszyny; userdata musi być zakodowana base64 — cmk nie robi tego za ciebie
cmk deploy virtualmachine \
  name=web-01 displayname=web-01 \
  serviceofferingid=<SO-UUID> \
  templateid=<TPL-UUID> \
  zoneid=<ZONE-UUID> \
  networkids=<NET-UUID> \
  keypair=laptop \
  userdata=$(base64 -w0 cloud-init.yaml) \
  startvm=true

Zwróć uwagę na rozszerzenie .pub: wysyłasz klucz publiczny, prywatny nigdy nie opuszcza twojej maszyny. I druga uwaga: zawartość cloud-init.yaml ląduje w argumentach procesu i w historii powłoki, więc hasła i tokeny przekaż mechanizmem systemu docelowego, a nie plikiem w wierszu poleceń.

Wymagalność parametrów deployVirtualMachine zmieniała się między wydaniami: od CloudStacka 4.21 wymagane są tylko serviceofferingid i zoneid (doszły volumeid i snapshotid, więc maszynę odtworzysz też z wolumenu albo snapshotu), w 4.20 i starszych templateid jest wymagany. Na swojej chmurze sprawdzisz to poleceniem cmk deploy virtualmachine -h — wypisze opis i listę pól wprost z serwera.

# 4. Publiczny adres IP i dostęp po SSH tylko z biura
cmk associate ipaddress zoneid=<ZONE-UUID> networkid=<NET-UUID>

cmk create portforwardingrule ipaddressid=<IP-UUID> protocol=TCP \
  publicport=22 privateport=22 virtualmachineid=<VM-UUID> \
  networkid=<NET-UUID> openfirewall=false

cmk create firewallrule ipaddressid=<IP-UUID> protocol=TCP \
  startport=22 endport=22 cidrlist=203.0.113.10/32

Ustawienie openfirewall=false jest świadome: regułę zapory dodajesz osobno, z konkretną listą adresów źródłowych, zamiast otwierać port dla całego internetu. Gotową maszynę warto od razu uzbroić w watchdoga — też kilka poleceń, tyle że wewnątrz systemu.

Reszta cyklu życia wygląda tak, jak podpowiada intuicja czasownik + rzeczownik:

cmk stop virtualmachine id=<VM-UUID>
cmk start virtualmachine id=<VM-UUID>
cmk reboot virtualmachine id=<VM-UUID>
cmk scale virtualmachine id=<VM-UUID> serviceofferingid=<NOWA-SO-UUID>
cmk change serviceforvirtualmachine id=<VM-UUID> serviceofferingid=<NOWA-SO-UUID>
cmk create snapshot volumeid=<VOL-UUID> name=przed-aktualizacja quiescevm=true
cmk destroy virtualmachine id=<VM-UUID> expunge=true

scale virtualmachine dotyczy maszyny działającej, change serviceforvirtualmachine — zatrzymanej; dostępność obu zależy od hypervisora i od operatora.

Polecenie zwróciło jobid. Jak poczekać na koniec operacji?

Większość poleceń zmieniających stan jest asynchroniczna: serwer oddaje identyfikator zadania i pracuje w tle. Status zadania ma trzy wartości: 0 — w toku, 1 — sukces, 2 — błąd.

Domyślnie cmk załatwia to za ciebie: ustawienie asyncblock jest włączone, więc narzędzie samo odpytuje serwer co dwie sekundy i pokazuje dopiero wynik końcowy — gotowy obiekt maszyny zamiast surowego jobid. Limit czasu daje ustawienie timeout (domyślnie 1800 sekund); po jego przekroczeniu dostajesz async API job query timed out.

Czasem chcesz odwrotnie: wystrzelić operację i nie czekać.

cmk set asyncblock false
cmk deploy virtualmachine ... # zwraca od razu identyfikator zadania
cmk query asyncjobresult jobid=<JOB-UUID> filter=jobstatus,jobresultcode

To też odpowiedź na klasyczny błąd początkującego: skrypt, który zaraz po deploy virtualmachine ustawia regułę NAT i dostaje błąd, bo maszyny jeszcze nie ma. Przy asyncblock=true problem znika; z własnym klientem HTTP pętlę odpytującą piszesz sam.

Jak zrobić z cmk narzędzie do raportów i skryptów

Dwa mechanizmy zamieniają CLI w źródło danych. Pierwszy to filter= — lista pól, które zostają w wyniku — oraz odwrotny exclude= (filtrowanie jest lokalne, szczegóły w pułapce piątej). Drugi to format wyjścia: globalnie przez set output, jednorazowo flagą -o.

# Raport do arkusza: wszystkie maszyny konta, wybrane kolumny, format CSV
cmk -o csv list virtualmachines listall=true \
    filter=name,state,zonename,cpunumber,memory > maszyny.csv

# To samo do dalszej obróbki w jq
cmk -o json list virtualmachines listall=true \
  | jq -r '.virtualmachine[] | [.name, .state, .zonename] | @tsv'

Parametr listall=true oznacza „pokaż wszystko, co wolno mi zobaczyć”; bez niego widzisz tylko zasoby własne. Piątkowa taśma z początku artykułu wygląda tak:

#!/usr/bin/env bash
# Zatrzymanie wszystkich działających maszyn, których nazwa zawiera "test"
set -euo pipefail # błąd cmk trafia na stdout, nie do JSON-a — stąd pipefail

ids=$(cmk -o json list virtualmachines listall=true state=Running keyword=test \
      | jq -r '.virtualmachine[].id')

for id in ${ids}; do
  printf 'zatrzymuję %s ... ' "${id}"
  if cmk stop virtualmachine id="${id}" >/dev/null; then
    echo "ok"
  else
    echo "BŁĄD" >&2
  fi
done

Zanim uruchomisz pętlę, obejrzyj samą listę identyfikatorów: keyword dopasowuje fragment nazwy, więc test złapie także latest-api czy protest-db — a to skrypt zatrzymujący cudze maszyny. Bezpieczniej filtrować po znaczniku (tags) niż po nazwie, a pierwsze uruchomienie zrobić z echo przed cmk stop. Dwie rzeczy są celowe: filtrowanie po stronie serwera (state=Running keyword=test) zamiast w jq, bo wtedy serwer nie wysyła danych, których i tak nie użyjesz, oraz sprawdzanie kodu wyjścia zamiast pola errortext — powód i zastrzeżenie w pułapce drugiej.

Sześć pułapek cmk, których nie ma w oficjalnej dokumentacji

1. Nie pisz ~/.cmk/config ręcznie. To najkosztowniejsza pomyłka. Ustawienia globalne cmk trzyma w bezimiennym bloku na górze pliku, bez nagłówka. Dopisana z dobrą wiarą sekcja [core] nie jest globalna — trafia do listy profili serwerów. Skutki są nieoczywiste: timeout wynosi wtedy zero, więc każde zadanie asynchroniczne kończy się komunikatem async API job query timed out, a pusta nazwa profilu daje failed to authenticate to make API call mimo poprawnych kluczy. Lekarstwo: ustawiaj wszystko przez cmk set ... i usuń dopisane sekcje.

2. Błędy trafiają na standardowe wyjście i nie są JSON-em. Nieudane wywołanie drukuje zwykły tekst i kończy proces kodem 1 — skrypt szukający pola errortext nie znajdzie go nigdy. Tam też idzie wyjście flagi -d, więc cmk -d ... | jq zawsze się wywróci. Jest jeden bolesny wyjątek: gdy cmk odrzuci polecenie własną walidacją (komunikat Missing required parameters), kończy się kodem 0. Literówka w nazwie parametru albo nieaktualna pamięć podręczna dają skrypt, który melduje „ok”, choć nie zrobił nic. Przy operacjach krytycznych sprawdzaj więc nie tylko kod wyjścia, ale i to, czy odpowiedź jest JSON-em.

3. set profile z literówką po cichu tworzy nowy profil — z domyślnym adresem localhost i danymi admin/password — i przełącza się na niego, co daje serię niezrozumiałych błędów połączenia. Polecenie switch profile, przełączające tylko na istniejące profile, czeka w gałęzi rozwojowej i nie ma go w 6.5.0.

4. Walidacja parametrów jest po stronie klienta, z pamięci podręcznej. Bez sync cmk korzysta z wbudowanej migawki listy API — w 6.5.0 odpowiada ona wydaniu 4.21 CloudStacka, wersji zaszytej w narzędziu, nie wersji twojej chmury — i prosi wtedy na wyjściu diagnostycznym o sync. Nieaktualna pamięć potrafi zablokować poprawne wywołanie komunikatem Missing required parameters albo zgłosić unknown command or API requested dla istniejącego polecenia. Po każdej aktualizacji chmury zrób cmk sync.

5. filter= filtruje lokalnie. Nie zmniejsza transferu ani obciążenia serwera, nie obsługuje ścieżek zagnieżdżonych, a podany razem z exclude= unieważnia ten drugi. Nie ma też automatycznej paginacji: page i pagesize podaje się razem, a kolejne strony zbiera twój skrypt.

6. Sekrety leżą w plikach otwartym tekstem. set apikey i set secretkey zapisują wartości do ~/.cmk/config, a wpisane w powłoce interaktywnej cmk — również do ~/.cmk/history. Od 6.5.0 oba pliki mają prawa 0600, ale treść pozostaje czytelna i wędruje do każdej kopii katalogu domowego. Klucze podane flagami -k/-s widać dodatkowo w historii powłoki i na liście procesów — wyczyść taki wpis albo poprzedź polecenie spacją, gdy masz włączone HISTCONTROL=ignorespace. Klucz, który wyciekł, unieważniasz, generując nowy w panelu — stary przestaje wtedy działać; rób to bez wahania przy każdym podejrzeniu: zmianie laptopa, odejściu osoby z zespołu, przypadkowym commicie. Przy błędzie weryfikacji certyfikatu nie wyłączaj jej ustawieniem verifycert — napraw zaufanie do urzędu certyfikacji; bez niej twoje klucze można przechwycić w locie. I drobiazg: cmk podpisuje żądanie parametrem expires ustawionym na piętnaście minut w przód (signatureversion=3), więc rozjechany zegar daje błąd uwierzytelnienia wyglądający jak zły klucz — sprawdź czas, zanim wygenerujesz nowe klucze.

Kiedy terminal jest złym pomysłem i czego cmk nie załatwi

Bez uników: bywa, że CLI jest wolniejsze i bardziej ryzykowne niż klikanie.

  • Praca eksploracyjna. Pytanie „co ja tu właściwie mam?” to w panelu jedno spojrzenie na listę ze statusami; w terminalu — trzy zapytania i mrużenie oczu.
  • Jedna operacja, wykonywana raz. Konfiguracja profilu i szukanie trzech UUID-ów trwa dłużej niż pięć kliknięć.
  • Konsola maszyny. Żaden terminal jej nie wyrenderuje — choć cmk create consoleendpoint virtualmachineid=<VM-UUID> zwróci adres do otwarcia w przeglądarce. Zepsuty fstab, przez który system nie wstaje, i tak naprawisz dopiero w oknie konsoli.
  • Operacje nieodwracalne. destroy virtualmachine ... expunge=true nie zapyta „na pewno?”. Panel zapyta.
  • Złożone konstrukty z zależnościami. Przy VPC z kilkoma warstwami, listami ACL i tunelem VPN formularz wymusza poprawną kolejność; CLI pozwoli zbudować to źle i dowiesz się później.
  • Środowisko, które ma być odtwarzalne. Tu odpowiedzią jest Terraform albo Ansible: cmk wykonuje polecenia, nie utrzymuje deklaracji. Tę drogę opisaliśmy osobno — zarządzanie CloudStackiem za pomocą Terraforma, od konfiguracji providera po klaster Kubernetes z kodu. Skrypt w bashu, który „prawie” jest infrastrukturą jako kodem, to najgorszy z możliwych światów.

Jest też granica po naszej stronie: rola konta klienta nie obejmuje poleceń administracyjnych operatora. Hostów, pul adresów, ofert usług ani parametrów strefy nie zobaczysz przez API — tu zostaje zgłoszenie do nas i żadne CLI tego nie skróci.

I granica zakresu: cmk zarządza zasobami platformy — maszynami, wolumenami, sieciami, adresami, szablonami — ale nie danymi w nich. Magazynem obiektowym zgodnym z S3 sterujesz narzędziami ekosystemu S3 (aws CLI, rclone, s5cmd), nie CloudMonkeyem. Wnętrze systemu operacyjnego to zadanie dla cloud-inita i Ansible.

Czym jeszcze zarządza się CloudStackiem? Stan ekosystemu na sierpień 2026

cmk jest klientem referencyjnym, ale nie jedynym. Daty pochodzą z repozytoriów i rejestrów pakietów, bo w tym ekosystemie „istnieje” i „jest utrzymywane” to dwie różne rzeczy:

  • cs (Python) — biblioteka i CLI w jednym, konfiguracja w ~/.cloudstack.ini, sama obsługuje zadania asynchroniczne. Domyślny wybór do skryptów w Pythonie; wydanie z czerwca 2026. Twarda zależność kolekcji Ansible.
  • cloudstack-cli (Ruby) — narzędzie operatorskie z operacjami wyższego poziomu: maszyna z regułami przekierowania jednym poleceniem, deklaratywne „stacki”, raporty. Rozwijane jednoosobowo, ale regularnie; wydanie z kwietnia 2026.
  • apache/cloudstack-go — oficjalne SDK w Go i fundament reszty ekosystemu (provider Terraform, kontrolery Kubernetes), najżywsza z bibliotek. Archiwalnego xanzy/go-cloudstack nie używaj w nowym kodzie.
  • Apache Libcloud (Python) — gdy kod ma być przenośny między CloudStackiem a innymi chmurami. Abstrakcja gubi jednak specyfikę platformy: projekty, domeny, VPC, oferty.
  • Java, PHP, Node.js, .NET — wprost: brak żywych klientów. Jclouds trafił do archiwum Apache w 2025 roku, reszta stoi na commitach sprzed lat. Zostaje własny cienki klient na surowym API albo wywoływanie cmk z zewnątrz.
  • Terraform i OpenTofu — provider cloudstack/cloudstack, wersja stabilna 0.6.0 z października 2025 (to w niej pojawiły się zasoby klastrów Kubernetes), kandydat 0.7.0-rc1 z sierpnia 2026 z migracją na plugin framework. Rozwijany pod Apache. Czyta plik konfiguracyjny CloudMonkeya, co jest wygodne lokalnie — ale w CI podawaj klucze zmiennymi środowiskowymi zamiast kopiować plik z sekretami obok kodu.
  • Ansible — kolekcja ngine_io.cloudstack, po roku ciszy mocno odświeżona: wydanie 3.0.0 w październiku 2025 i trzy kolejne w samym sierpniu 2026. Uwaga: w 3.0.0 moduły straciły przedrostek cs_. Jest też moduł api_request — furtka do dowolnego wywołania API bez liczenia podpisu.
  • Kubernetes — Cluster API Provider CloudStack do deklaratywnego zakładania klastrów, cloud controller manager do load balancerów i etykiet węzłów, sterownik CSI do wolumenów trwałych. Ten ostatni jest projektem społecznościowym, nie fundacji Apache — inaczej niż apache/cloudstack-go.
  • Packer i Vagrant — uczciwe ostrzeżenie: wtyczka Packera stoi na wydaniu z 2022 roku, wtyczka Vagranta jest porzucona od 2019. Obraz zbuduj czymkolwiek innym i zarejestruj poleceniem register template.
  • Pulumi — natywnego providera nie ma i nic na to nie wskazuje; jedyna droga to most do providera Terraform.

Najczęstsze pytania

Czym jest cmk i czym różni się od starego cloudmonkey? To dwie generacje tego samego narzędzia. cloudmonkey w Pythonie instalowany przez pip nie ma wydania od 13 października 2021 roku, a opis paczki sam odsyła do następcy. cmk to port w języku Go dystrybuowany jako pojedyncza binarka, aktualna wersja 6.5.0. Mają osobne katalogi konfiguracyjne (~/.cmk), więc mogą współistnieć — ale nowe wdrożenia rób wyłącznie na cmk.

Skąd wziąć klucz API i sekretny do WebDisk Cloud? Wygenerujesz je samodzielnie w panelu WebDisk Cloud, w ustawieniach swojego użytkownika. Tam też znajdziesz adres punktu końcowego API, który wpisujesz do profilu cmk. Klucze mają dokładnie te uprawnienia, które ma twoje konto.

Jak używać cmk w CI, nie zostawiając kluczy w pliku? Klucz i sekret trzymaj w zmiennych chronionych i maskowanych swojego systemu CI, a katalog ~/.cmk/ dopisz do .gitignore i nigdy nie pakuj go do obrazu kontenera. Do automatyki wystaw osobne konto albo osobny projekt z minimalną rolą — klucz nie ma węższych uprawnień niż konto, do którego należy. Obraz kontenera z cmk przypnij do konkretnego tagu; latest na Docker Hubie jest wieloletni.

Jakie parametry są obowiązkowe w deploy virtualmachine? Od CloudStacka 4.21 formalnie tylko serviceofferingid i zoneid — szablon stał się opcjonalny, bo maszynę można odtworzyć również z wolumenu lub snapshotu. W 4.20 i starszych templateid jest wymagany. W praktyce podajesz jeszcze networkids, name i keypair. Ostateczną odpowiedź dla twojej chmury daje cmk deploy virtualmachine -h uruchomione po wcześniejszym cmk sync.

Polecenie zwróciło jobid i nic więcej. Co dalej? To znaczy, że masz wyłączone asyncblock. Odpytaj zadanie poleceniem cmk query asyncjobresult jobid=<UUID> i sprawdź pole jobstatus: 0 to praca w toku, 1 sukces, 2 błąd. Domyślne set asyncblock true sprawia, że cmk czeka za ciebie i pokazuje dopiero wynik; górną granicą jest wtedy set timeout, domyślnie 1800 sekund.

Czy przez cmk założę klaster Kubernetes? Tak. W WebDisk Cloud usługa klastrów jest dostępna — sprawdzisz to poleceniem cmk list kubernetessupportedversions, a szczegóły oferty opisuje strona Kubernetes. Formalnie create kubernetescluster wymaga tylko name i zoneid, ale w praktyce podajesz też kubernetesversionid, serviceofferingid i size; skalowanie to cmk scale kubernetescluster id=<UUID> size=5. Samym klastrem od środka zarządzasz oczywiście przez kubectl, a deklaratywnie z zewnątrz — przez Cluster API. Na innych CloudStackach dostępność tej usługi zależy od operatora.

curl, cmk, Terraform czy Ansible — kiedy który? curl tylko wtedy, gdy debugujesz warstwę podpisu albo twój język nie ma żywego klienta. cmk do zapytań, operacji jednorazowych i szybkich skryptów. Ansible, gdy konfigurujesz maszyny imperatywnie w playbookach. Terraform, gdy środowisko ma być opisane w repozytorium i odtwarzalne od zera. Wszystkie cztery uderzają w ten sam punkt końcowy z tymi samymi uprawnieniami — wybierasz kształt pracy, nie poziom dostępu.

Zacznij od jednego zapytania

Najtańszy pierwszy krok to nie migracja procesów do skryptów, tylko jedno polecenie: pobierz binarkę, sprawdź sumę kontrolną, ustaw profil, zrób cmk sync i wypisz swoje maszyny do CSV. Kwadrans później będziesz wiedzieć, czy terminal pasuje do twojego sposobu pracy — a piątkowa taśma zamieni się w pętlę z tego artykułu, którą można obejrzeć w repozytorium i uruchomić z harmonogramu. Panel zostaje tam, gdzie jest naprawdę dobry: przy konsoli maszyny, przy pierwszym rozglądaniu się i przy operacjach, które robisz raz.

Za WebDisk Cloud stoi Mazura sp. z o.o., podmiot prawa polskiego: dane pozostają w Europie, a wsparcie odpowiada po polsku. Jeśli szacujesz koszty, konfiguracje Cloud PAYG zaczynają się od 28 zł netto miesięcznie za Small (2 vCPU, 4 GB RAM, 50 GB NVMe i publiczny adres IP) — stan na sierpień 2026, a wykorzystania zakupionych zasobów, w tym przepustowości, nie doliczamy. Napisz do nas, jeśli chcesz obgadać scenariusz automatyzacji.