Connect to a Cluster Through a Bastion Host
You can run a Kubernetes cluster without public IP addresses on its master nodes. This makes the cluster more secure, because the nodes aren't reachable directly from the internet. To manage such a cluster, use a bastion host: a cloud server with a public IP that is connected to the cluster's private network.
You connect to the bastion host over SSH and manage the cluster with kubectl. Requests to the cluster API travel over the private network, so you don't need to expose the API to the internet.
Requirements Copy link
The cluster and the bastion host must be in the same private network. This lets the bastion host reach the cluster API at its private address without going through the internet.
Check the Cluster's Private Network Copy link
To find out which network the cluster belongs to, open the dashboard:
- Go to the Kubernetes section and click the cluster.
- Open the Network tab.
- The network name is shown in the Private Network section.
Create a Bastion Host Copy link
The bastion host must be reachable from the internet through a public IP and connected to the same private network as the Kubernetes cluster.Â
- Go to Cloud Servers and click Create Server.
- Select an image and a configuration. A minimal configuration is enough for a small number of SSH connections.
- Select the same region as the cluster.
- Select the Public IP option, or choose one of the IPv4 addresses available on your account.
- Select the private network the cluster belongs to.
- Finish creating the server. For more details, see Create Cloud Servers.
Once the server is created, note its public IP. You'll use it to connect to the bastion host over SSH.
The bastion host's private IP must belong to the same network as the cluster API address. For example, in the 192.168.0.0/24 network, the bastion host can have the private IP 192.168.0.10 and the cluster API can have 192.168.0.20.
Install kubectl on the Bastion Host Copy link
Install kubectl on the bastion host by following our kubectl guide.
Download kubeconfig Copy link
Download the kubeconfig file of the cluster:
- Go to the Kubernetes section and click the cluster.
- On the Dashboard tab, click the download the configuration file link.

The examples below assume the kubeconfig file is saved at ~/Downloads/kubeconfig.yaml. Replace the path with your own.
Check the API address in kubeconfig. On your local computer, run:
grep server ~/Downloads/kubeconfig.yamlThe server field must contain the private IP of the cluster API, for example https://192.168.0.20:6443.
Copy kubeconfig to the Bastion Host Copy link
-
Connect to the bastion host from your local computer:
ssh user@public_IPYou can find the connection details on your server's Dashboard.
-
On the bastion host, create a directory for the configuration and set its permissions:
mkdir -p ~/.kube
chmod 700 ~/.kube-
Keep the SSH session open. In another terminal window on your local computer, copy
kubeconfigto the server:
scp ~/Downloads/kubeconfig.yaml user@public_IP:~/.kube/hostman-cluster.yamlUse the same user that created the directory. The configuration will be saved to ~/.kube/hostman-cluster.yaml in that user's home directory.
-
Go back to the SSH session. If you already have a
~/.kube/configfile you want to keep, save it under a different name first. Otherwisemv -iwill ask you to confirm replacing it. -
Rename the file to config and make it readable and writable only by its owner:
mv -i ~/.kube/hostman-cluster.yaml ~/.kube/config
chmod 600 ~/.kube/configkubectl uses ~/.kube/config by default, so you don't need to specify the path in commands.
Verify the Connection Copy link
On the bastion host, run:
kubectl get nodesIf the command returns a list of nodes, the connection is set up. Run any further kubectl commands on the bastion host.
If the command fails, check the following:
- Timeout: check the private network and the address in the
serverfield. - Restricted outbound traffic on the bastion host: allow outgoing TCP connections to the API's private IP on port 6443.
Unauthorizederror: make sure you're using thekubeconfigof the right cluster and that its credentials are valid.