Matkani pilven kansalaiseksi
Olin jo pitkään halunnut tehokkaan työpöytäkoneen pilveen niin, että maksaisin laskentatehosta vain käyttäessäni sitä. Halusin palata työkalujeni, projektieni ja asetusteni pariin pitämättä koko konetta käynnissä käyttökertojen välillä.
Vibe-koodaus tarjosi keinon rakentaa tällainen ympäristö ja hallita sitä. Samalla se antoi uuden syyn tarvita sitä: paikan, jossa koodausagentti voisi työskennellä oikeassa kehitysympäristössä.
Minulla oli projektille aikaa satunnaisina hetkinä, useimmiten vain puhelin käden ulottuvilla. Ympäristön piti sopia tähän tapaan työskennellä. Saatoin antaa ohjeita, tarkastaa tuloksia ja jatkaa projektia seuraavan sopivan hetken tullen.
Kokonaisuudeksi muodostui pieni jatkuvasti käytettävissä oleva kone UpCloudissa ja tarpeen mukaan käynnistettävä työpöytäkone Verdassa. Työpöytäkoneen laskentaresurssit voitiin poistaa ja levy säilyttää. Seuraava instanssi käynnistyisi samalta levyltä siihen ympäristöön, jonka olin jättänyt.
Artikkelin sisältö
01Codex pienellä jatkuvasti käytettävissä olevalla virtuaalikoneella
Codex on pääasiallinen käyttöliittymä ympäristön rakentamiseen ja hallintaan. Se kirjoittaa asetustiedostoja ja skriptejä, suorittaa komentoja, tarkastaa tuloksia ja ottaa SSH-yhteyksiä muihin koneisiin. Lähes kaikki työ tehdään sen kautta.
Lähtökohtana oli codex-min, pieni Debian-virtuaalikone UpCloudissa. Sen palvelupaketti maksoi 3 euroa kuukaudessa ja sisälsi yhden virtuaalisen suorittimen, 1 Gt muistia ja 10 Gt levytilaa. Se ajaa Codexia ja hallintatyökaluja riippumatta Verdan suuremmasta koneesta. Codex käynnistyy koneen mukana, ja etäohjauksen kautta ympäristöön voi palata myöhemmin.
Tämä kone suorittaa agentin komennot ja säilyttää sen työtiedostot. Se ei tarvitse hallitsemansa koneen resursseja: SSH mahdollistaa komentojen suorittamisen etänä, ja palveluntarjoajien API-rajapinnat hoitavat infrastruktuurin hallinnan.
02Molempien palveluntarjoajien API-yhteydet
UpCloudin ja Verdan API-tunnuksilla hallintatyökalut voivat tarkastella resursseja sekä tehdä pyytämiäni käyttöönotto- ja elinkaaritoimia.
Näin Codex voi käsitellä ympäristön molempia tasoja. API-rajapinnan kautta se voi tarkastella instanssia tai pyytää valtuutettua infrastruktuurimuutosta. SSH:n kautta se voi määrittää käyttöjärjestelmän asetuksia ja suorittaa komentoja instanssin sisällä. Minä valitsen, milloin maksullinen laskenta käynnistetään ja mitä konetyyppiä käytetään.
Codex toimii myös verda-desktop-koneella, jossa se voi käyttää suoraan valitun instanssin resursseja.
03Yhteys Androidista
Puhelimessani ConnectBot kirjautuu SSH-avaimella ilman palvelimen käyttäjätilin salasanan syöttämistä. Julkinen avain on asennettu palvelimille, ja yksityinen avain pysyy puhelimessa. Hallintakoneella on oma SSH-avain yhteyksiin sen hallitsemille koneille.
SSH-yhteys Androidista codex-min-koneelle on suora. SSH-yhteydet sekä Androidista että codex-min-koneelta verda-desktop-koneelle kulkevat Tailscalen kautta. Näin Verdan konetta voi käyttää pysyvällä laitenimellä julkisen IP-osoitteen vaihtuessa.
SSH todentaa edelleen yhteyden. Tailscale tarjoaa verkkoyhteyden ja laitteiden osoitteet. Sen laiteidentiteetti säilyy Verdan levyllä, joten korvaava kone voi liittyä verkkoon samalla nimellä.
04Pysyvä levy, vaihdettavat laskentaresurssit
Verdan ympäristössä käyttöjärjestelmä, asennetut työkalut, projektit ja asetukset säilyvät pysyvällä järjestelmälevyllä. Laskentainstanssi voidaan poistaa levyä poistamatta. Seuraava instanssi käynnistyy olemassa olevalta levyltä.
Voin valita, millaiset laskentaresurssit liitän levyyn seuraavaa käyttökertaa varten. Edullinen CPU-vaihtoehto tarjoaa jo 4 vCPU:ta ja 16 Gt muistia. Toisessa päässä on peto: 22 vCPU:ta, 120 Gt keskusmuistia ja A100, jossa on 80 Gt GPU-muistia.
Kun virtuaalikonetta ei ole luotuna, maksan Verdassa vain tallennustilasta.
Verdan hallintakoodi ajetaan codex-min-koneella. Verdan API-yhteys käyttää asiakastunnistetta ja asiakassalaisuutta:
credentials = {
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
}API on oma HTTP-asiakkaamme. Tässä on tiivistetty versio, joka käyttää Pythonin standardikirjastoa ja saa tunnukset alustajan argumenttina. Se hoitaa tokenin uusimisen, JSON-pyynnöt ja resurssiluetteloiden sivutuksen:
import json
import time
import urllib.request
import uuid
class API:
def __init__(self, credentials):
self.credentials = credentials
self.token = None
self.expiry = 0
def request(self, method, endpoint, data=None, token=None):
headers = {"Content-Type": "application/json"}
if token:
headers["Authorization"] = "Bearer " + token
request = urllib.request.Request(
"https://api.verda.com/v1" + endpoint,
method=method,
headers=headers,
data=json.dumps(data).encode() if data is not None else None,
)
with urllib.request.urlopen(request, timeout=30) as response:
body = response.read()
try:
result = json.loads(body) if body else None
except json.JSONDecodeError:
result = str(uuid.UUID(body.decode().strip()))
return result, response.headers
def call(self, method, endpoint, data=None):
if self.token is None or time.time() >= self.expiry:
result, _ = self.request("POST", "/oauth2/token", {
**self.credentials,
"grant_type": "client_credentials",
})
self.token = result["access_token"]
self.expiry = time.time() + max(0, result["expires_in"] - 60)
return self.request(method, endpoint, data, self.token)[0]
def listing(self, endpoint):
items = []
page = 1
while True:
result = self.call("GET", f"{endpoint}?page={page}&pageSize=100")
if not result:
return items
items.extend(result)
page += 1Luontipyynnön vastaus voi olla myös pelkkä UUID, jonka vastauksen käsittely tunnistaa. Elinkaariskripti lisää näiden operaatioiden ympärille uudelleenyritysten ja tilan hallinnan.
Seuraavaksi luodaan asiakasolio ja ladataan tallennettu elinkaaritila:
api = API(credentials)
state = load()API tarjoaa konetyyppien luettelon, tämänhetkisen saatavuuden ja olemassa olevat levyt. Skripti löytää säilytetyn levyn tallennetun tunnisteen perusteella ja käyttää levyn sijaintia:
types = api.call("GET", "/instance-types")
availability = api.call("GET", "/instance-availability")
volumes = api.listing("/volumes")
disk = next(d for d in volumes if d["id"] == state["disk_id"])
location = disk["location"]A100-koneen käynnistyspyynnössä valitaan 1A100.22V. CPU-vaihtoehto käyttää tyyppiä CPU.4V.16G. Olemassa olevan levyn tunniste annetaan image-kentässä, jolloin uusi instanssi käynnistyy kyseiseltä levyltä:
requested_kind = "1A100.22V"
plan = {
"instance_type": requested_kind,
"hostname": "verda-desktop",
"description": "Persistent development desktop",
"location_code": location,
"image": disk["id"],
"is_spot": False,
"ssh_key_ids": register_keys(api, public_keys()),
}
result = api.call("POST", "/instances", plan)Pyyntö sisältää myös rekisteröityjen SSH-avainten tunnisteet. Ennen pyynnön lähettämistä varsinainen ohjausohjelma tarkastaa kapasiteetin saatavuuden ja levyn liitostilan, ottaa automaattisen siivouksen käyttöön ja tallentaa istunnon aikarajan.
05Saldon täydentäminen käsin ja automaattinen poistaminen
Tärkein vaatimus oli, ettei huomion herpaantuminen jättäisi kallista työpöytäkonetta käyntiin määräämättömäksi ajaksi. Käyttämättömien tai liian pitkään käynnissä olleiden instanssien automaattinen poistaminen oli alusta asti välttämätöntä.
Sekä UpCloudin että Verdan kohdalla minulle oli olennaista, että pystyin valitsemaan tilin saldon täydentämisen vain käsin.
Ohjausohjelma toimii codex-min-koneella, joten se on käytettävissä myös Verdan koneen sammuttua. Se pyytää siivousta, varmistaa laskentainstanssin poistumisen ja tarkastaa levyn säilymisen. Epäonnistunutta siivousta voidaan yrittää uudelleen myöhemmällä tarkastuskerralla.
Poistopyyntö kohdistuu laskentainstanssiin ja jättää poistettavien levyjen listan tyhjäksi, jolloin järjestelmälevy säilyy:
api.call("PUT", "/instances", {
"id": state["instance_id"],
"action": "delete",
"volume_ids": [],
})Tavallinen käytäntö sallii kolmekymmentä minuuttia ilman vahvistettua aktiivisuutta. Ehdoton enimmäisaika on kaksitoista tuntia, ja tarkastus tehdään viiden minuutin välein. Enimmäisaika pätee, vaikka kone näyttäisi yhä aktiiviselta. Aktiivisuuden seuranta huomioi SSH-istunnot ja Codexin työn. Pelkkä käynnissä oleva Codex-taustaprosessi ei riitä aktiivisuudeksi: seuranta käyttää myös todellisten työtapahtumien aikaleimoja havaitakseen tarkastusten välillä valmistuneen työn.
Lopputuloksessa Codex ja hallintatyökalut pysyvät käytettävissä pienellä virtuaalikoneella, työympäristö säilyy levyllä ja suuremmat laskentaresurssit varataan niitä tarvitseville käyttökerroille.