Using SSH + Port-Forwarding for K8s CLI tools
While working with multiple Kubernetes clusters, I came across an annoyance of being unable to reach some of cluster's API endpoints directly from my workstation.
Some production K8s clusters I'm working with have their APIs only available within their respective environments (i.e. production K8s clusters), while others are available directly, via general corp VPN (i.e. non-prod K8s clusters).
Having to SSH to jumphost, or (through jumphost) to one of the nodes within the environment is annoying, and slows down cluster-related work, since YAML manifest changes made locally in my text editor of choice are not instantly available on the jumphost. One could use SSH-FS, or another method to continuously synchronize local changes, but there's an easier way. As a one-off it's easy to start an SSH connection to jumphost, with SSH's TCP Port-Forwarding to forward requests to K8s API via localhost port of choice. Scripting the process improves the experience, especially when frequently working with multiple clusters.
Inspired by AWS-Vault tool, I've made utility with similar usage pattern, which automates SSH Port-Forwarding setup for selected (configured) clusters. In this case, "vault" is a verb, synonymous to leap, jump, spring..
UPDATE:
k8s-vault
has been reimplemented in Crystal (and has no external dependencies, other than SSH client): https://github.com/anapsix/k8s-vault.cr
The whole thing is a BASH script with dependency on jq
, yq
, grep / ggrep
to parse KUBECONFIG
(~/.kube/config
), nc
to check connectivity to K8s API endpoint, and openssh-client
to establish connection to SSH jumphost.
Config file looks like this
## k8s-vault
k8s_api_timeout: 5 # in seconds
ssh_ttl: 10 # in seconds
ssh_forwarding_port:
random: true
static_port: 32845
clusters: # same as in your KUBECONFIG
prod:
enabled: true
ssh_jump_host: jumphost.prod.example.com
qa:
enabled: true
ssh_jump_host: jumphost.qa.example.com
dev:
enabled: false
ssh_jump_host: jumphost.dev.example.com
It works by extracting relevant config options from existing KUBECONFIG
, and generating new temporary one. Feeding it via environmental variable to instance of whatever CLI tool stated [by k8s-vault]. As long as that tool is capable of using KUBECONFIG
environment variable, K8s-Vault can be helpful.
The entire script is available as a GitHub Gist
The script is a POC, and may or may not be reimplemented in Go, Rust, or whatever other language I decide to play with.
UPDATE: It's been reimplemented in Crystal: https://github.com/anapsix/k8s-vault.cr