Worked example and make target for the kvm-ssh Secret

docs/kvm-provider.md walks through key generation, ssh-copy-id,
ssh-keyscan under the address the operator dials, and the Secret from
the private key plus ~/.ssh/kvm_known_hosts. make kvm-ssh-secret runs
the same as an apply with KVM_SSH_KEY / KVM_KNOWN_HOSTS overrides and
refuses a .pub, the classic mistake. README mirrors the short form.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-10 19:13:51 +00:00
co-authored by Claude Fable 5.1
parent cc0606d24f
commit c5ebb2e044
3 changed files with 54 additions and 14 deletions
+33 -11
View File
@@ -43,20 +43,42 @@ ssh virt@nas1.home.lan ip link show br0
## Cluster-side setup
1. Create the SSH Secret. `known_hosts` must contain every host's key
(`ssh-keyscan -H nas1.home.lan >> known_hosts`); without it, set
1. Create the SSH Secret from a key pair dedicated to the operator and a
`known_hosts` file holding every host's key. The worked example below
uses `~/.ssh/proxy-operator_ed25519` and `~/.ssh/kvm_known_hosts`,
the same paths the integration test and `make kvm-ssh-secret` default
to.
```sh
# once: a key pair for the operator; the .pub goes on every host
ssh-keygen -t ed25519 -f ~/.ssh/proxy-operator_ed25519 -N '' -C proxy-operator
ssh-copy-id -i ~/.ssh/proxy-operator_ed25519.pub virt@nas1.home.lan
# once per host: its host key, under the address the *operator* will
# dial (hosts[].address), which may differ from what your laptop uses
ssh-keyscan -H nas1.home.lan >> ~/.ssh/kvm_known_hosts
# the Secret: the PRIVATE key (not the .pub) plus known_hosts
kubectl -n egress-proxies-operator-system create secret generic kvm-ssh \
--from-file=id_ed25519=$HOME/.ssh/proxy-operator_ed25519 \
--from-file=known_hosts=$HOME/.ssh/kvm_known_hosts
```
`make kvm-ssh-secret` runs that last command as an apply, so it also
updates an existing Secret; override the paths with
`KVM_SSH_KEY=... KVM_KNOWN_HOSTS=...`. Putting the `.pub` in the
Secret is the classic mistake: the operator then fails at startup
with a "not a private key" error. Without `known_hosts`, set
`insecureIgnoreHostKey: true` and accept that a MITM could hand you a
fake hypervisor.
```sh
kubectl -n egress-proxies-operator-system create secret generic kvm-ssh \
--from-file=id_ed25519=$HOME/.ssh/proxy-operator_ed25519 \
--from-file=known_hosts=./known_hosts
```
`config/manager/manager.yaml` mounts it (optional) at
`/etc/proxy-operator/kvm`; the deployment starts fine without it as
long as no `kvm` provider is configured.
`config/manager/manager.yaml` mounts the Secret (optional) at
`/etc/proxy-operator/kvm` as two files, `id_ed25519` and
`known_hosts`, which is what `sshKeyFile` and `knownHostsFile` in the
provider config point at. The deployment starts fine without the
Secret as long as no `kvm` provider is configured. Rotating the key:
re-run the command (or the make target) and restart the manager; it
reads both files once at startup.
2. Add a provider entry to the providers config
(`config/manager/providers_config.yaml` in-cluster; full sample in