English Β· FranΓ§ais
Build a Talos Linux cluster (immutable, API-driven Kubernetes) on VirtualBox with
vagrant upplus one script. Single control plane or HA with 3 CPs and a VIP, then a full application layer (Cilium, Envoy Gateway, Longhorn, Vault, PostgreSQLβ¦).
Talos has no SSH and no package manager: the OS is immutable and driven entirely through
the talosctl API from the host. Vagrant therefore only creates and starts the VMs; all the
cluster configuration goes through talosctl.
The whole path, in three commands:
vagrant up # creates the VMs, they boot into maintenance mode
./talos/cluster-up.sh # config + etcd bootstrap + kubeconfig + health
./_k8s/platform-up.sh # application layer (assumes CNI=cilium, the default, see Β§9)| π Browsable docs | ops-nc.github.io/Vagrant-Talos β EN/FR switch, offline copy with make docs |
| π¦ Application layer | _k8s/README.md |
| β¬οΈ Talos / K8s upgrades | talos/UPGRADE.md |
| π Something broken? | TROUBLESHOOTING.md |
| Tool | Purpose | Install |
|---|---|---|
| VirtualBox 7 | hypervisor | https://www.virtualbox.org/ |
| Vagrant | VM creation | https://developer.hashicorp.com/vagrant |
talosctl |
driving the Talos cluster | curl -sL https://talos.dev/install | sh |
kubectl |
using the cluster | https://kubernetes.io/docs/tasks/tools/ |
helm |
_k8s/ addons |
https://helm.sh/docs/intro/install/ |
uv (optional) |
make docs |
https://docs.astral.sh/uv/ |
π‘ Keep
talosctlaligned withTALOS_VERSION. The binary version is what decides the generated configuration schema; a mismatch with the ISO produces obscure errors.
To pin talosctl to a specific version instead of taking the latest:
curl -Lo /tmp/talosctl https://github.com/siderolabs/talos/releases/download/v1.13.7/talosctl-linux-amd64
sudo install -m 0755 /tmp/talosctl /usr/local/bin/talosctlβΉοΈ The Talos ISO (
metal-amd64.iso) is downloaded automatically on the firstvagrant up, intoiso/. No Vagrant box or plugin to install: the "dummy communicator" (no SSH) and the emptypace/emptybox are handled by theVagrantfile.
β οΈ VirtualBox and KVM cannot share VT-x. If the KVM module is loaded,vagrant updies onVERR_VMX_IN_VMX_ROOT_MODEβ unload it first:TROUBLESHOOTING.md.
| Item | IP |
|---|---|
| Host (host-only) | 192.168.56.1 |
| Kubernetes API VIP | 192.168.56.5 |
talos-cp1 / cp2 / cp3 |
192.168.56.10 / .20 / .30 |
talos-w1 / w2 / w3 β¦ |
192.168.56.101 / .102 / .103 β¦ |
| LoadBalancer VIP (Cilium L2) | 192.168.56.200 |
The IPs are deterministic: each VM has a fixed MAC and a DHCP reservation on the
VirtualBox host-only network, created automatically by the Vagrantfile.
Every VM has 2 NICs: NIC1 = VirtualBox NAT (Internet) and NIC2 = host-only
192.168.56.x (cluster and API network).
βΉοΈ Interface naming: since Talos 1.5, NICs get predictable names (
enp0s3,enp0s8β¦), noteth0/eth1. The host-only NIC is thereforeenp0s8(VirtualBox NIC2 = PCI bus0000:00:08.0). The patches never target by name: the VIP is set throughbusPathand the node IP through the192.168.56.0/24subnet β robust whatever the naming scheme.
β οΈ The subnet is only half configurable.NETWORKdrives theVagrantfileandcluster-up.sh, but192.168.56.xis hard-coded intalos/patch-all.yaml(validSubnets),talos/patch-cp.yaml(vip.ip,advertisedSubnets) andtalos/cni-flannel.yaml(--iface-can-reach). ChangingNETWORKwithout editing those three files produces a silently broken cluster.
The topology lives in lab.env, the single source read by the Vagrantfile and by
talos/cluster-up.sh. Start from the versioned template (lab.env is gitignored):
cp lab.env.example lab.env| Variable | Template default | Purpose |
|---|---|---|
TALOS_VERSION |
v1.13.7 |
boot ISO and installer image |
INSTALLER_IMAGE |
Image Factory image | installer with extensions (iscsi for Longhorn) |
CONTROL_PLANES |
3 |
1 = single, 3 = HA with a VIP |
WORKERS |
3 |
number of workers |
CP_MEM / CP_CPU |
4096 / 2 |
control plane resources (never below 3072: etcd) |
WK_MEM / WK_CPU |
2048 / 2 |
worker resources |
CNI |
cilium |
cilium, calico, flannel or none (see Β§9) |
LAB_DOMAIN |
talos.lab.example.io |
UI domain (*.<domain>: wildcard TLS + HTTPRoute) |
SELF_SIGNED |
true |
TLS mode: true = wildcard signed by a local CA (openssl, no domain, no token), false = cert-manager + Let's Encrypt |
LAB_DNS_ZONE |
(empty β last 2 labels) | DNS zone of the ACME DNS-01 solver β SELF_SIGNED=false only |
LAB_ACME_EMAIL |
(empty β admin@<zone>) |
Let's Encrypt account (expiry notices) β SELF_SIGNED=false only |
LAB_ACME_ISSUER |
staging |
ACME issuer: staging (untrusted, huge quota) or prod (trusted, 5 certs/week) β SELF_SIGNED=false only |
CLOUDFLARE_API_TOKEN |
(empty) | cert-manager DNS-01 (_k8s/) β SELF_SIGNED=false only |
NETWORK |
192.168.56 |
host-only network |
CP_IP_START / CP_IP_STEP |
10 / 10 |
β .10, .20, .30 |
WK_IP_START / WK_IP_STEP |
101 / 1 |
β .101, .102, .103 |
LB_POOL_START / LB_POOL_END |
192.168.56.200 / .230 |
LoadBalancer IP range; the 1st one is the Gateway's, the wildcard DNS target |
Variables read by cluster-up.sh but missing from the template (all have a default):
VIP ($NETWORK.5), CLUSTER_NAME (talos-lab), INSTALL_DISK (/dev/sda),
OUT (_out), FORCE.
π‘ Create
lab.envanyway. Without it, theVagrantfileandcluster-up.shfall back to their internal defaults β both aligned onv1.13.7and onCNI=cilium, but you lose the Image Factory installer image (iscsi extensions), and therefore Longhorn. Keep theCNIvalue inlab.envin sync with what you actually want:cluster-up.shdecides what Talos lays down,platform-up.shdecides what Helm installs afterwards, and two disagreeing values give you two competing CNIs β a broken pod network.
β οΈ Do not lowerCP_MEMbelow3072. 2 GB control planes starve etcd as soon as the_k8s/addons stack up, and the cluster collapses under load βobservability/requires 4 GB explicitly. That is why the template ships4096.
π° What the default topology costs: 3 Γ 4 GB + 3 Γ 2 GB = 18 GB of RAM, 12 vCPU and ~6 Γ 20 GB of disk. A 16 GB host cannot run it β use the minimal lab below.
π‘ Minimal lab (2 VMs, ~6 GB). Enough for Talos itself and the base platform (
platform-up.sh); the data addons expect the default 3 workers (Longhorn replicates Γ3,observability/wants 4 GB control planes). Editlab.env:CONTROL_PLANES=1 WORKERS=1
β οΈ Edit the file, do not just export the variable.CONTROL_PLANES=1 vagrant uponly affectsvagrant:cluster-up.shre-readslab.envand would wait for control planes.20/.30that were never created. To override on the fly, pass the variable to both commands:CONTROL_PLANES=1 vagrant up && CONTROL_PLANES=1 ./talos/cluster-up.sh.
π
LAB_DOMAIN: the repo is public, so its default is neutral (talos.lab.example.io). The_k8s/manifests carry that domain; the*-up.shscripts replace it on the fly withLAB_DOMAIN(sed), without ever rewriting the versioned files. Put your domain inlab.env(see_k8s/README.md).
The 1st control plane is always talos-cp1 (192.168.56.10). The VirtualBox/Vagrant VM name
is identical to the Talos hostname (see Β§8).
vagrant up # the VMs boot from the ISO, in maintenance mode
./talos/cluster-up.sh # everything elsecluster-up.sh chains: config generation β apply to the nodes (with deterministic
hostnames) β etcd bootstrap β kubeconfig β health wait. It prints the exports you need and
a final kubectl get nodes.
export TALOSCONFIG="$PWD/_out/talosconfig"
export KUBECONFIG="$PWD/kubeconfig"
kubectl get nodes -o wideFor another topology, edit lab.env or override on the spot:
CONTROL_PLANES=1 WORKERS=2 ./talos/cluster-up.sh # single
CNI=flannel ./talos/cluster-up.sh # CNI laid down by Talos, no LB IPs
β οΈ NEVER re-runcluster-up.shon an already-installed cluster. Its maintenance mode wait polls the nodes with--insecure; an already-installed node (secure mode) never answers. The wait is bounded (WAIT_MAINTENANCE, 300 s) and then fails with an explicit message β but it still wasted five minutes and applied nothing. To grow a running cluster, see Β§6.1.
β οΈ NEVER regenerate_out/(norFORCE=1) on a running cluster:gen configproduces new secrets and new CAs, which breaks the existing cluster. Do it only after avagrant destroy.
π Understanding: the 6 steps by hand (what the script automates)
Useful to learn, to debug, or to resume halfway. The generation command is strictly the
script's own: --install-image included.
vagrant upThe VMs boot from the Talos ISO in maintenance mode and take their reserved IP. Check that a node answers:
talosctl -n 192.168.56.10 get disks --insecure # must list /dev/sdaset -a ; . ./lab.env ; set +a # loads TALOS_VERSION, INSTALLER_IMAGE, CNIβ¦
talosctl gen config talos-lab https://192.168.56.5:6443 \
--install-disk /dev/sda \
--install-image "$INSTALLER_IMAGE" \
--additional-sans 192.168.56.5,192.168.56.10,192.168.56.20,192.168.56.30 \
--config-patch @talos/patch-all.yaml \
--config-patch-control-plane @talos/patch-cp.yaml \
--config-patch-control-plane "@talos/cni-${CNI:-cilium}.yaml" \
--output-dir _out
export TALOSCONFIG="$PWD/_out/talosconfig"Produces _out/controlplane.yaml, _out/worker.yaml and _out/talosconfig. The
kube-apiserver endpoint is the VIP 192.168.56.5, in single as in HA.
β οΈ --install-imageis not optional. Without it you install the classic installer, without the system extensions β and Longhorn fails later oniscsiadm: not found. The value comes fromINSTALLER_IMAGE(lab.env).
β οΈ The CNI patch is not optional either. One file per intent βcni-cilium.yaml(the default),cni-calico.yaml,cni-flannel.yaml,cni-none.yamlβ hence the${CNI}above, read fromlab.envlikecluster-up.shdoes. Omitting the patch leaves Talos' default CNI in place, without the host-only VXLAN fix (see Β§9).
βΉοΈ The VIP serves only kube-apiserver (
:6443). For the Talos API (-e/--endpoints,:50000) always target real node IPs (e.g.192.168.56.10), never the VIP β that is the Talos recommendation.
# Control plane(s) β single: only .10; HA: .10, .20, .30
talosctl apply-config --insecure -n 192.168.56.10 --file _out/controlplane.yaml
# Workers (.101, .102, β¦ β independent of the number of CPs)
talosctl apply-config --insecure -n 192.168.56.101 --file _out/worker.yaml
talosctl apply-config --insecure -n 192.168.56.102 --file _out/worker.yamlEach node installs itself on /dev/sda, then reboots from disk.
βΉοΈ These commands leave the auto-generated hostname (
talos-xxxxx). For deterministic names,cluster-up.shadds to everyapply-configa--config-patchcarrying aHostnameConfigdocument (auto: "off"+hostname:).
talosctl config endpoint 192.168.56.10 # HA: add .20 .30
talosctl config node 192.168.56.10talosctl bootstrap -n 192.168.56.10
β οΈ bootstrapruns only once, on a single control plane. In HA, the other CPs join etcd automatically through discovery. If Talos answers "bootstrap is not available yet", etcd is still finishing its pre-state: retry.
talosctl kubeconfig -n 192.168.56.10 ./kubeconfig
export KUBECONFIG="$PWD/kubeconfig"
talosctl health --wait-timeout 10m -n 192.168.56.10 -e 192.168.56.10
talosctl -n 192.168.56.10 get members # members seen by discovery
kubectl get nodes -o wideA bare cluster does nothing useful. Everything else lives in _k8s/:
Cilium, Envoy Gateway, cert-manager, Longhorn, Vault, PostgreSQL, Prometheus/Loki, Kyverno,
Trivy, MinIOβ¦
./talos/cluster-up.sh # 1. cluster (CNI=cilium by default: Talos installs nothing)
./_k8s/platform-up.sh # 2. Cilium β Envoy Gateway β metrics-server β wildcard TLS
./_k8s/argocd/argocd-up.sh # 3. opt-in addonsAfter the bootstrap, the nodes stay NotReady until the CNI is installed β that is expected,
platform-up.sh handles it. See _k8s/README.md for the full dependency
chain and the list of addons.
β οΈ This layer requiresCNI=cilium(the default). It relies on aLoadBalancerService that actually gets an IP, which only Cilium's L2 announcement (ARP) provides here. Withflannel,calicoornone, the Gateway stays atEXTERNAL-IP <pending>and no UI is reachable. Details in Β§9.
βΉοΈ This whole subsection is for
SELF_SIGNED=falseonly. With the default (SELF_SIGNED=true),platform-up.shsigns the wildcard itself withopensslunder a local CA: no public DNS record and no Cloudflare token are needed, and the domain never has to exist outside your machine. All you do is make the name resolve locally β an/etc/hostsline pointing your subdomains at192.168.56.200β and, optionally, import_out/self-signed/ca.crtto silence the browser warning. See_k8s/self-signed/README.md. Read on only if you own a real domain and want a publicly trusted certificate.
This is the part everyone forgets, and nothing works without it. Two things to do once, outside the cluster.
a) A wildcard DNS record pointing at the Gateway IP.
Every lab UI is served through a single entry point β Envoy's LoadBalancer Service, which
takes the first IP of LB_POOL_START (192.168.56.200 by default). One record is
therefore enough for all the subdomains:
| Type | Name | Content | Proxy |
|---|---|---|---|
A |
*.talos.lab.example.io |
192.168.56.200 |
DNS only (π grey cloud) |
# the IP actually assigned (use this if you changed LB_POOL_START)
kubectl -n envoy-gateway-system get svc -o wide | grep LoadBalancer
# check resolution
dig +short argo.talos.lab.example.io # must answer 192.168.56.200
β οΈ The Cloudflare proxy (orange cloud) cannot work here. It would have to reach your origin from the Internet, but192.168.56.200is a private, non-routable IP. In orange you would get a522error. Stay on DNS-only: Envoy terminates TLS, not Cloudflare β hence the need for a publicly trusted certificate (Let's Encrypt, see point b).
βΉοΈ The lab is therefore only reachable from the host, or through access to the host-only network (Tailscale β see
_k8s/README.md). A public wildcard pointing at a private IP carries no exploitation risk, but it does publish the existence of the lab and its IP plan: your call.
π‘ With no DNS at all, you can test by short-circuiting resolution:
curl -sI --resolve argo.talos.lab.example.io:443:192.168.56.200 \ https://argo.talos.lab.example.io/
b) A Cloudflare API token for the DNS-01 challenge.
A wildcard cannot be validated over HTTP-01 (Let's Encrypt cannot reach a private IP), so
cert-manager uses DNS-01: it proves ownership by writing an _acme-challenge record, which
takes a token scoped to Zone/DNS/Edit + Zone/Zone/Read on your zone only β an All zones
token would let the lab rewrite the DNS of every domain you own. How to create it, and how the
certificate is then issued: _k8s/cert-manager/README.md.
Then in lab.env (gitignored β never in lab.env.example):
SELF_SIGNED=false # leave the default (true) and none of this is read
LAB_DOMAIN=talos.lab.example.io # your domain
LAB_DNS_ZONE=example.io # the Cloudflare zone (derived if empty)
LAB_ACME_EMAIL=you@example.io # Let's Encrypt expiry notices
LAB_ACME_ISSUER=staging # staging (default) | prod β see the warning below
CLOUDFLARE_API_TOKEN=<your-token>platform-up.sh creates the cloudflare-api-token Secret, substitutes the domain in the
manifests and waits for the certificate. Follow it with
kubectl -n envoy-gateway-system get certificate.
β οΈ prodcosts a quota slot on every rebuild, andstagingis the default on purpose. The wildcard lives only in etcd, sovagrant destroyburns it and the nextplatform-up.shasks for a brand new one. Let's Encrypt production allows 5 certificates per week for the same*.<LAB_DOMAIN>: the 6th rebuild fails with429 rateLimitedand the lab stays without TLS until the 168 h window slides. Useprodon a stable lab, not while iterating β and back the wildcard up before a destroy:kubectl -n envoy-gateway-system get secret wildcard-<your-domain-in-dashes>-tls \ -o yaml > _out/wildcard-tls.backup.yaml # contains the private key: _out/ is gitignored
vagrant status # VM status
vagrant halt # power off
vagrant up # power back on
vagrant destroy -f # delete everything (dedicated disks included)
β οΈ After adestroy, also delete the local Talos state before starting over:rm -rf _out kubeconfig.
β οΈ VirtualBox 7.x does not always clean up after adestroy, and the nextupthen fails onVERR_ALREADY_EXISTS. Purge the leftovers with./talos/virtualbox-cleanup.shβ details and precautions inTROUBLESHOOTING.md.
To grow an already running cluster, start the new VMs and apply the existing worker config to them (same secrets). Two rules:
- Do not regenerate
_out/(norFORCE=1): new secrets would break the cluster. - Do not re-run
cluster-up.sh: it would wait for maintenance mode on already-installed nodes and hang.
Example β going from 3 to 5 workers (talos-w4=.104, talos-w5=.105):
- Raise
WORKERSinlab.env(hereWORKERS=5). - Start only the new VMs:
vagrant up talos-w4 talos-w5
- Apply the existing worker config while pinning the hostname (Nth worker =
talos-w<N>):export TALOSCONFIG="$PWD/_out/talosconfig" WK_IP_START=101 ; WK_IP_STEP=1 # same values as lab.env for n in 4 5; do ip="192.168.56.$(( WK_IP_START + (n - 1) * WK_IP_STEP ))" until talosctl -n "$ip" get disks --insecure >/dev/null 2>&1; do sleep 5; done talosctl apply-config --insecure -n "$ip" --file _out/worker.yaml \ --config-patch "$(printf 'apiVersion: v1alpha1\nkind: HostnameConfig\nauto: "off"\nhostname: talos-w%s\n' "$n")" done
- The workers join automatically (their config already points at the VIP). Check:
kubectl get nodes -o wideβtalos-w4/talos-w5turnReady.
π‘ Removing a worker:
kubectl drain talos-w5 --ignore-daemonsets --delete-emptydir-data vagrant destroy -f talos-w5 kubectl delete node talos-w5then lower
WORKERSinlab.env.
βΉοΈ Adding control planes follows the same logic (VM +
apply-configofcontrolplane.yaml, hostnametalos-cp<N>); they join etcd through discovery, without re-runningbootstrap.
Symptoms and fixes have their own page, so this one stays about installing:
TROUBLESHOOTING.md β host and VirtualBox (VT-x/KVM conflict,
leftovers after a destroy), addressing and DHCP (stale leases, unreachable VIP), Talos nodes
(--insecure silence, KUBERNETES: n/a), cluster and pods (the NAT-NIC DNS trap, nodes staying
NotReady).
Addon-specific problems live in the _k8s/<addon>/README.md β index in _k8s/README.md.
- No SSH β a dummy communicator (in the
Vagrantfile) reports "ready" immediately so thatvagrant updoes not hang. - No Talos box β we start from the empty
pace/emptybox and boot themetal-amd64.isoISO (SATA DVD drive, BIOS, boot disk then DVD). - Deterministic IPs β fixed MAC per VM + host-only DHCP reservations
(
VBoxManage dhcpserver ... --fixed-address) created by abefore :uptrigger, stale leases purged β the node takes its reserved IP on the 1st DHCP. - Deterministic hostnames β
cluster-up.shapplies oneHostnameConfigdocument per node (auto: "off"+ fixedhostname:) instead of the auto-generated name (talos-xxxxx). The VirtualBox VMs carry the same name. - VIP / HA β
talos/patch-cp.yamlsets a VIP shared between control planes (election through etcd): the kube-apiserver endpoint stays stable even if a CP goes down. - Online discovery β
talos/patch-all.yamlenables thediscovery.talos.devservice and disables thekubernetesregistry, deprecated and incompatible with Kubernetes β₯ 1.32. - Default route through the NAT β deliberate (Internet access). What must be host-only is
the node's identity (kubelet
nodeIP, etcd, VIP), not the default route.
References: Talos Linux Β· siderolabs/talos Β· rgl/talos-vagrant Β· bjwschaap/vagrant-empty-box
CNI (in lab.env) expresses an intent, read in two places:
talos/cluster-up.shapplies thetalos/cni-<CNI>.yamlpatch, which fills incluster.network.cniin the control plane config. Talos installs flannel itself, atbootstrapβ withoutkubectl, by rendering an internal manifest._k8s/platform-up.shinstalls the CNI in every other case, through Helm.
CNI= |
Talos patch | Who installs | LoadBalancer IP |
|---|---|---|---|
cilium (default) |
cni-cilium.yaml β none |
platform-up.sh β _k8s/cilium/ |
β pool + L2 announcement (ARP) |
calico |
cni-calico.yaml β none |
platform-up.sh β _k8s/calico/ |
β BGP only |
flannel |
cni-flannel.yaml |
Talos, at bootstrap time | β |
none |
cni-none.yaml |
you | β |
CNI=calico ./talos/cluster-up.sh && ./_k8s/platform-up.sh| Cilium | Calico | Flannel | |
|---|---|---|---|
| Getting started | one script after the bootstrap | one script after the bootstrap | immediate, Talos does it all |
| Pod network + NetworkPolicy | β | β | |
LoadBalancer Services |
β L2 announcement | β MetalLB required | β |
_k8s/ layer (Envoy, HTTPS UIs) |
β | β unusable | |
| kube-proxy replacement | β possible | β | β |
| Network observability | Hubble | β | β |
In practice: keep cilium. It is the only choice that makes the lab usable end to end.
calico is there to compare CNIs and to work on NetworkPolicy; flannel for a bare
cluster, if you just want to explore Talos.
The Cilium install (chart pinned to 1.19.6, L2 pool, --set devices=enp0s8) is documented
and scripted in _k8s/cilium/README.md β that is the source of
truth, platform-up.sh calls it for you.
β οΈ Calico does not announceLoadBalancerService IPs. It can only do it over BGP, which assumes a peer router β non-existent on a VirtualBox host-only network. WithCNI=calicoyou therefore have to install MetalLB (L2 mode) and adjust_k8s/envoy-gateway/Envoy-Proxy.yml, which pinsloadBalancerClass: io.cilium/l2-announcer(platform-up.shstrips that line outside Cilium). Full procedure:_k8s/calico/README.md.
β οΈ Switching CNI on an existing cluster is not supported:vagrant destroy, then rebuild. Two coexisting CNIs fight over the pod network.
β οΈ The key point on the Cilium side is the same as for flannel: pin the host-only interface (enp0s8). Otherwise Cilium picks the default route NIC (the NAT) and the VTEPs are broken.
βΉοΈ The
kubelet.nodeIP.validSubnetsfix (talos/patch-all.yaml) still holds with Cilium: the nodes'INTERNAL-IP, the source of the VTEPs, is already on192.168.56.0/24.
Everything can be validated without touching a cluster:
make validate # script syntax + Vagrantfile + Talos config + doc links
make docs # regenerates docs/index.html from every README (EN + FR)
make help # lists the targetsmake validate-talos generates the config in a temporary directory, then feeds it to
talosctl validate --mode metal: no risk for _out/ nor for the cluster β unlike
FORCE=1 ./talos/cluster-up.sh, which regenerates the secrets and breaks a running cluster.
make validate-docs builds the docs into a throwaway directory and fails if a *.md link or
a cross-page anchor no longer resolves.
make validate-yaml parses every *.yaml / *.yml tracked by git.
On every pull request, the ci workflow re-runs three of these on a runner β shell syntax,
YAML, and the Vagrantfile β by calling the very same make targets, so a check cannot pass
in CI and fail on your machine. vagrant validate runs there with --ignore-provider, since a
runner has no VirtualBox.
This project is licensed under the Apache License 2.0 β see
LICENSE.
In short: use it, modify it, redistribute it, including commercially, as long as you keep the copyright notice and state your changes. It comes with no warranty: this is a lab, do not run it in production.
The license covers what this repo actually contains β the Vagrantfile, the talos/ and
_k8s/ scripts, the manifests and the documentation. It does not extend to the third-party
components those scripts download (Talos Linux, Cilium, Longhorn, Vault, Envoy Gateway,
chaoskubeβ¦), each of which keeps its own license.
