Use a SOCKS5 Proxy to Access the Kubernetes API

    This page shows how to use a SOCKS5 proxy to access the API of a remote Kubernetes cluster. This is useful when the cluster you want to access does not expose its API directly on the public internet.

    You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using or you can use one of these Kubernetes playgrounds:

    Your Kubernetes server must be at or later than version v1.24. To check the version, enter kubectl version.

    You need SSH client software (the ssh tool), and an SSH service running on the remote server. You must be able to log in to the SSH service on the remote server.

    Task context

    Note: This example tunnels traffic using SSH, with the SSH client and server acting as a SOCKS proxy. You can instead use any other kind of proxies.

    • You have a client computer, referred to as local in the steps ahead, from where you’re going to create requests to talk to the Kubernetes API.
    • The Kubernetes server/API is hosted on a remote server.
    • You will use SSH client and server software to create a secure SOCKS5 tunnel between the local and the remote server. The HTTPS traffic between the client and the Kubernetes API will flow over the SOCKS5 tunnel, which is itself tunnelled over SSH.

    graph LR; subgraph local[Local client machine] client([client])— local
    traffic .-> local_ssh[Local SSH
    SOCKS5 proxy]; end local_ssh[SSH
    SOCKS5
    proxy]— SSH Tunnel —>sshd subgraph remote[Remote server] sshd[SSH
    server]— local traffic —>service1; end client([client])-. proxied HTTPs traffic
    going through the proxy .->service1[Kubernetes API]; classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; class ingress,service1,service2,pod1,pod2,pod3,pod4 k8s; class client plain; class cluster cluster;

    JavaScript must be enabled to view this content

    Figure 1. SOCKS5 tutorial components

    This command starts a SOCKS5 proxy between your client machine and the remote server. The SOCKS5 proxy lets you connect to your cluster’s API server.

    • -D 1080: opens a SOCKS proxy on local port :1080.
    • -N: Do not execute a remote command. Useful for just forwarding ports.
    • username@kubernetes-remote-server.example: the remote SSH server where the Kubernetes cluster is running.

    Client configuration

    To explore the Kubernetes API you’ll first need to instruct your clients to send their queries through the SOCKS5 proxy we created earlier.

    1. export https_proxy=socks5h://localhost:1080

    When you set the https_proxy variable, tools such as curl route HTTPS traffic through the proxy you configured. For this to work, the tool must support SOCKS5 proxying.

    Note: In the URL , localhost does not refer to your local client computer. Instead, it refers to the endpoint on the remote server known as localhost. The curl tool sends the hostname from the HTTPS URL over SOCKS, and the remote server resolves that locally (to an address that belongs to its loopback interface).

    To use the official Kubernetes client with a proxy, set the proxy-url element for the relevant cluster entry within your ~/.kube/config file. For example:

    1. apiVersion: v1
    2. clusters:
    3. - cluster:
    4. certificate-authority-data: LRMEMMW2 # shortened for readability
    5. server: https://<API_SERVER_IP_ADRESS>:6443 # the "Kubernetes API" server, in other words the IP address of kubernetes-remote-server.example
    6. proxy-url: socks5://localhost:1080 # the "SSH SOCKS5 proxy" in the diagram above (DNS resolution over socks is built-in)
    7. name: default
    8. contexts:
    9. - context:
    10. name: default
    11. current-context: default
    12. kind: Config
    13. preferences: {}
    14. users:
    15. - name: default
    16. user:
    17. client-certificate-data: LS0tLS1CR== # shortened for readability
    18. client-key-data: LS0tLS1CRUdJT= # shortened for readability

    If the tunnel is operating and you use kubectl with a context that uses this cluster, you can interact with your cluster through that proxy. For example:

    1. NAMESPACE NAME READY STATUS RESTARTS AGE
    2. kube-system coredns-85cb69466-klwq8 1/1 Running 0 5m46s

    Stop the ssh port-forwarding process by pressing CTRL+C on the terminal where it is running.

    Further reading