Pripojenie ku klastru
Každá požiadavka ide cez Cluster — nemenného klienta, ktorý pozná URL apiservera a spôsob autentifikácie. Kubernetes::url() vytvorí prázdneho ad-hoc klienta, ktorého fluentne doplníte o tokeny, klientske certifikáty a CA:
use RoundlyConsulting\KubernetesApi\Facades\Kubernetes;
$cluster = Kubernetes::url('https://api.prod.example.com:6443')
->withToken(config('services.kubernetes.token'))
->withCertificate('/path/to/client.crt')
->withPrivateKey('/path/to/client.key')
->withCaCertificate('/path/to/ca.crt')
->withSslVerification()
->withManagerName('my-app'); // the field manager on resources this app writes
$cluster->withToken('other'); // returns a copy — $cluster still uses the original tokenKubernetes::url() od predvoleného klastra nič nededí — ani token, ani certifikát. Pri lokálnom vývoji môžete certifikáty vynechať a overovanie vypnúť; v produkcii to nikdy nerobte:
$cluster = Kubernetes::url('https://127.0.0.1:6443')
->withToken('local-dev-token')
->withoutSslVerification();url(), každé with…() / without…(), withManagerName(), withDefaultNamespace() aj namespace() vrátia nový klaster a ten, na ktorom ste ich zavolali, nechajú nezmenený — klienta z fasády tak nemôže iný volajúci presmerovať ani mu vymeniť prihlasovacie údaje.
Autentifikačné API
| Metóda (každá vracia kópiu) | Účinok |
|---|---|
url($url) | Základná URL apiservera, napr. https://api.prod.example.com:6443. |
withToken($token) | Bearer token posielaný s každou požiadavkou (#[SensitiveParameter], takže sa nikdy neobjaví v stack trace). Nahradí súbor s tokenom. |
withTokenFile($path) | Súbor s bearer tokenom, ktorý sa načíta pri každej požiadavke, takže sa prejaví aj rotovaný token. Už nastavený token slúži ako záloha, kým sa súbor nedá prečítať. |
withCertificate($path) / withPrivateKey($path) | Klientsky certifikát a kľúč pre vzájomné TLS. |
withCaCertificate($path) | CA, voči ktorej sa overuje certifikát apiservera. |
withSslVerification() / withoutSslVerification() | Zapína alebo vypína overovanie TLS — predvolene zapnuté. |
withManagerName($name) | Posiela sa ako fieldManager pri každom create, update, patch, scale a rollout restart a ako User-Agent každej požiadavky. |
withDefaultNamespace($namespace) | Mäkký predvolený namespace pre zdroje v namespace — na rozdiel od namespace() nič neodmieta. |
withRedirects() / withoutRedirects() | Povolí nasledovanie HTTP presmerovaní alebo povolenie zruší — predvolene vypnuté. |
withRedactedErrors() | Správy KubernetesException nesú len stav a dôvod. |
getUrl() · getToken() · getTokenFile() · hasToken() · shouldVerify() · getManagerName() · defaultNamespace() · followsRedirects() · redactsErrors() | Čítanie nastavení uvedených vyššie. getToken() vráti aktuálny obsah súboru s tokenom, inak samotný token. |
getPathToCertificate() · getPathToPrivateKey() · getPathToCaCertificate() | Čítanie ciest k certifikátom. |
Token sa posiela v hlavičke Authorization: Bearer, certifikát s kľúčom dostane HTTP klient pre vzájomné TLS a cesta k CA nahradí systémové úložisko dôveryhodných certifikátov. Meno managera sa posiela ako parameter fieldManager pri každom create, update, patch, scale a rollout restart, takže managedFields zaznamená vašu aplikáciu ako vlastníka toho, čo zapísala; posiela sa aj ako User-Agent. Server-side apply field managera potrebuje, preto bez mena managera použije kubernetes-api-for-laravel.
Súbory s tokenom a rotované tokeny
withTokenFile() nasmeruje klaster namiesto pevného tokenu na súbor s bearer tokenom. Súbor sa načíta znova pri každej HTTP požiadavke aj pri exec, takže rotovaný token — projektovaný token service accountu či tokenFile z kubeconfigu — sa prejaví bez reštartu; kým sa súbor nedá prečítať, slúži ako záloha token nastavený popri ňom:
// A token file is read again for every request, so a rotated token is picked up.
$cluster = Kubernetes::url('https://api.prod.example.com:6443')
->withTokenFile('/var/run/secrets/tokens/deployer')
->withCaCertificate('/path/to/ca.crt');
$cluster->getTokenFile(); // '/var/run/secrets/tokens/deployer'
$cluster->getToken(); // the file's current content
$cluster->withToken($token); // a fixed token replaces the token fileKlastre z vnútra klastra (in-cluster) takto fungujú samy: kubelet projektovaný token rotuje (pri 80 % jeho životnosti alebo každých 24 hodín) a klaster ho načíta znova, takže dlho bežiaci worker fronty, Horizonu či Octane nikdy nepošle zastaraný token.
Z kubeconfigu alebo z vnútra klastra
Klienta nasmerujete na klaster jedným riadkom namiesto ručného nastavovania URL a prihlasovacích údajov. fromKubeConfig() načíta kubeconfig, pre zvolený kontext nájde klaster a používateľa a vložené certifikáty zapíše do súkromných dočasných súborov — jeden na každý odlišný PEM, zmazané pri skončení PHP procesu. inCluster() načíta token a CA service accountu namountované do podu:
use RoundlyConsulting\KubernetesApi\Facades\Kubernetes;
// Current context from ~/.kube/config — or from every KUBECONFIG file, merged like kubectl:
$cluster = Kubernetes::fromKubeConfig();
// A specific context, optionally from an explicit kubeconfig path:
$cluster = Kubernetes::fromKubeConfig(context: 'local-dev');
$cluster = Kubernetes::fromKubeConfig(path: '/path/to/kubeconfig', context: 'staging');
// From in-cluster service-account mounts (when running inside a pod):
$cluster = Kubernetes::inCluster()->withManagerName('my-app');- Bez cesty sa všetky súbory z premennej prostredia KUBECONFIG zlúčia tak, ako ich zlučuje kubectl — chýbajúce súbory sa preskočia a platí prvý súbor, ktorý nastaví current-context alebo definuje klaster, používateľa či kontext s daným menom —, inak sa načíta ~/.kube/config. Bez kontextu sa použije current-context.
- Z používateľa loader číta statický token, tokenFile (načítaný pri každej požiadavke) a/alebo client-certificate s client-key; z klastra server, certificate-authority a insecure-skip-tls-verify. Každý certifikát môže byť cesta k súboru alebo vložený blok *-data; relatívne cesty (certificate-authority: certs/ca.crt, tokenFile) sa odvodzujú od adresára kubeconfigu, ktorý ich definuje, rovnako ako v kubectl.
- Používateľ, ktorý sa prihlasuje inak — cez exec plugin (v štýle EKS, GKE a AKS), auth-provider alebo meno a heslo —, vyhodí KubeConfigException s menom používateľa a spôsobom prihlásenia, namiesto aby sa načítal bez prihlasovacích údajov a každá požiadavka odišla anonymne. Token vydajte mimo aplikácie a použite zdroj url, alebo používateľovi nastavte tokenFile.
- Namespace z kontextu sa stane predvoleným namespace klastrov z fromKubeConfig() a connect() aj klastra so zdrojom kubeconfig, ktorý vlastný namespace nenastavuje: prednosť má namespace klastra, potom kontextu, potom default. Obmedzenie na namespace nikdy neprepíše.
- insecure-skip-tls-verify klastra musí byť boolean — true/false, prípadne yes/no, on/off či 1/0, v úvodzovkách aj bez nich. Čokoľvek iné vyhodí KubeConfigException namiesto hádania, takže „false“ v úvodzovkách nechá overovanie TLS zapnuté.
- inCluster() zostaví https://KUBERNETES_SERVICE_HOST:KUBERNETES_SERVICE_PORT (aj pre IPv6 hosty) a token načíta z /var/run/secrets/kubernetes.io/serviceaccount/token — a znova pri každej požiadavke, takže sa vždy pošle aktuálny rotovaný token. Overovanie TLS voči namountovanému ca.crt ostáva zapnuté — ak súbor chýba, vyhodí KubeConfigException, namiesto aby token poslal neoverenému apiserveru.
- Chýbajúci súbor, kontext, klaster či používateľ, neplatný YAML (hlásený len so súborom a riadkom, nikdy s obsahom), klaster bez URL servera, neplatné insecure-skip-tls-verify, neplatný base64, nečitateľný tokenFile, chýbajúce premenné prostredia v klastri, prázdny token alebo chýbajúca CA v klastri vyhodia KubeConfigException. Každý parameter loadera, ktorý nesie časť kubeconfigu, je #[SensitiveParameter], takže sa prihlasovacie údaje nikdy nedostanú do stack trace.
- Rovnaké zdroje fungujú aj v konfigurácii — 'source' => 'kubeconfig' alebo 'source' => 'in-cluster' pri položke v clusters (pozrite Pomenované klastre).
Pripojenie z objektu KubeConfig
Oba loadery vytvárajú hodnotový objekt KubeConfig — server, token a cesty k certifikátom, verify a k tomu tokenFile (načítaný pri každej požiadavke, token slúži ako záloha) a namespace (z kontextu). Kubernetes::connect() z neho vytvorí nový ad-hoc klaster, takže ho rovnako zostavíte aj z vlastného úložiska tajomstiev; Cluster::applyConfig() ho použije na kópii existujúceho klastra:
use RoundlyConsulting\KubernetesApi\DataTransferObjects\KubeConfig;
use RoundlyConsulting\KubernetesApi\Facades\Kubernetes;
$cluster = Kubernetes::connect(new KubeConfig(
server: 'https://api.staging.example.com:6443',
token: config('services.kubernetes.staging_token'),
clientCertificatePath: null,
clientKeyPath: null,
certificateAuthorityPath: storage_path('kubernetes/staging-ca.crt'),
verify: true,
tokenFile: null, // a token file re-read for every request; token is the fallback
namespace: 'shop', // becomes the new cluster's default namespace
));Presmerovania
Apiserver volanie API nikdy nepresmeruje, preto žiadna požiadavka presmerovanie nenasleduje, kým to nepovolíte — bežné požiadavky, zápisy aj streamy (watch, sledovanie logov); exec prijme len upgrade na WebSocket. Nasledované presmerovanie by znova poslalo bearer token, predložilo klientsky certifikát novému hostu, pri 307 či 308 zopakovalo telo zápisu (dáta secretu) a odpoveď cieľa by sa spracovala ako odpoveď apiservera.
- Odpoveď 3xx, ktorá sa dostane ku klientovi, vyhodí KubernetesException::redirectNotFollowed(). Správa uvedie stav a len pôvod cieľa (scheme://host[:port]) — nikdy jeho cestu, dotaz ani telo — a ping() vráti false.
- URL klastra, ktorá presmerúva, napríklad z http:// na https://, zlyhá s touto chybou: opravte URL alebo presmerovania povoľte.
- Pri každej požiadavke má prednosť povolenie na klastri, potom explicitné client.options.allow_redirects (globálna podoba, použitá tak, ako je zadaná), inak sú presmerovania vypnuté.
Jednému klastru ich povolíte cez withRedirects() alebo clusters.<name>.follow_redirects. Potom nasleduje presmerovania s predvolenými hodnotami Guzzle — najviac päť krokov a pri prechode na iný pôvod zahodí Authorization aj cookies. Povolenie je pravidlo transportu, nie prihlasovací údaj, preto ho applyConfig() zachová:
// Off by default: a 3xx throws KubernetesException instead of being followed.
$cluster = Kubernetes::url('https://proxy.example.com/k8s')
->withToken($token)
->withRedirects(); // opt this cluster in (Guzzle's defaults)
$cluster->followsRedirects(); // true
$cluster->withoutRedirects(); // a copy without the opt-inPrejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.