# Talos: cirrus edge node Single-node Talos control plane that runs only sish. Talos and Kubernetes are managed by hand with `talosctl`/`kubectl` (no Flux). | File | | |---|---| | `controlplane.yaml` | Base config, **unmodified** output of `talosctl gen config` (gitignored, contains the cluster PKI) | | `worker.yaml` | Generated worker config, unused on a single node (gitignored) | | `talosconfig` | Admin client config for `talosctl` (gitignored) | | `patches/*.yaml` | Every change to the base config | ```sh export TALOSCONFIG=talos/talosconfig # run from the repo root N="-n 10.20.5.130 -e 10.20.5.130" ``` ## Base config + patches The base file is never edited by hand; all changes live in `patches/`. The node's config is therefore always `controlplane.yaml` + `patches/*.yaml`, which keeps changes reviewable and lets a newly generated base (new node, new Talos defaults) get the same changes by reapplying the patches. `talosctl patch mc` merges a patch into the node's live config; it does not touch the local files. | Patch | Purpose | |---|---| | `control-plane-scheduling.yaml` | Drops the control-plane `NoSchedule` taint so sish can run on the only node | | `unprivileged-ports.yaml` | `ip_unprivileged_port_start=22`: sish (non-root, hostNetwork) binds :22/:80/:443 | | `firewall.yaml` | Ingress firewall, default block (see below) | Apply a single patch (dry run first; use `--mode try` for anything that can lock you out, it reverts automatically unless re-applied): ```sh talosctl $N patch mc --patch @talos/patches/.yaml --mode no-reboot --dry-run talosctl $N patch mc --patch @talos/patches/.yaml --mode no-reboot ``` Check that the node matches the files (expect `No changes.`): ```sh talosctl machineconfig patch talos/controlplane.yaml \ $(for p in talos/patches/*.yaml; do printf -- '--patch @%s ' "$p"; done) | talosctl $N apply-config --file /dev/stdin --dry-run ``` ## Firewall Default action `block`. Loopback and replies to outgoing connections are always allowed. | Open | Source | | |---|---|---| | 22, 80, 443, 2222, 20000-20099 tcp | anyone | sish (2222 = connector SSH, rest = forwards) | | 6443, 50000 tcp | anyone | Kubernetes API, Talos API (both client-cert authenticated) | | 53 udp/tcp | pod network `10.244.0.0/16` | CoreDNS forwards to the Talos host DNS | Closed: flannel VXLAN 4789/udp, etcd 2379-2383, kubelet 10250, kube-proxy 10256, trustd 50001 (open it to the node network only when a second node joins). The sish ports must match `port-bind-range` in `kubernetes/base/sish/config.yml`. To add a raw TCP port outside 20000-20099, change both files together. ## New node ```sh talosctl gen config https://:6443 --install-disk -o talos/ talosctl machineconfig patch talos/controlplane.yaml \ $(for p in talos/patches/*.yaml; do printf -- '--patch @%s ' "$p"; done) | talosctl apply-config --insecure -n --file /dev/stdin talosctl --talosconfig talos/talosconfig config endpoint talosctl --talosconfig talos/talosconfig -n bootstrap talosctl --talosconfig talos/talosconfig -n kubeconfig ``` Back up `controlplane.yaml` and `talosconfig` outside this folder: they are the only copy of the cluster PKI and admin credentials.