pythonkubernetesurllib3socks5

How does python access the apiClient of k8s through socks5 proxy


Accessing k8s apiclient is successful without using a proxy, as follows:

configuration = client. Configuration()
configuration.verify_ssl = False
configuration.host = "xxx"
configuration.api_key = {"authorization": "Bearer " + self.token}
c = api_client. ApiClient(configuration=configuration)
api = core_v1_api.CoreV1Api(c)
# Query the namespace, the step is successful
result = api.list_namespace()

However, since k8s api is automatically generated, the socks proxy cannot be directly set:https://github.com/kubernetes-client/python/issues/1064

Since k8s uses restClient, there is no way to pass the socks5 proxy. Currently, this method is used to connect, but it is invalid:

configuration = client. Configuration()
configuration.verify_ssl = False
configuration.api_key = {"authorization": "Bearer " + self.token}
configuration.host = "xxx"
c = api_client. ApiClient(configuration=configuration)
proxy = "socks5://xxx:1080"
c.rest_client.pool_manager = self.build_socks_proxy_manager(configuration)
api = core_v1_api.CoreV1Api(c)
# Query namespace, this step timed out, unable to connect
result = api.list_namespace()

def build_socks_proxy_manager(self, configuration, pools_size=4, maxsize=None):
  # skip some initialization steps
  return SOCKSProxyManager(num_pools=pools_size,
                    maxsize=maxsize,
                    cert_reqs = cert_reqs,
                    ca_certs=ca_certs,
                    cert_file=configuration.cert_file,
                    key_file=configuration.key_file,
                    proxy_url=configuration.proxy,
                    **addition_pool_args)

Updated based on larsks answer:

configuration = client. Configuration()
configuration.verify_ssl = False
configuration.api_key = {"authorization": "Bearer " + self.token}
configuration.host = "xxx"
c = api_client. ApiClient(configuration=configuration)
proxy = "socks5://xxx:1080"
c.rest_client.pool_manager = SOCKSProxyManager(proxy_url=proxy)
api = core_v1_api.CoreV1Api(c)
# Query namespace, this step still timed out, unable to connect
result = api.list_namespace()

Solution

  • You're setting configuration.host to the socks5:// url, but that doesn't make any sense (the socks5:// url is the address of the proxy, not the remote server).

    You would expect to set configuration.proxy, except that this will fail when you call create an ApiClient.

    If you set the pool_manager after instantiating the client object it seems to work. That is, if I have a socks5 proxy running on localhost:2080, the following code will connect via the proxy:

    import os
    from kubernetes import client, config
    from urllib3.contrib.socks import SOCKSProxyManager
    
    configuration = client.Configuration()
    configuration.verify_ssl = False
    configuration.api_key = {
        "authorization": "Bearer ...",
    }
    configuration.host = "https://api.example.com:6443"
    c = client.ApiClient(configuration=configuration)
    c.rest_client.pool_manager = SOCKSProxyManager(proxy_url="socks5h://localhost:2080")
    api = client.CoreV1Api(c)
    print(api.list_namespaced_pod('example-namespace'))