-1

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()

1 Answers1

1

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'))
larsks
  • 277,717
  • 41
  • 399
  • 399
  • First of all thank you.My host here is a virtual address, and the socks proxy will resolve it from the virtual address. I updated the proxy of the configuration to the socks proxy address, but I still can't connect after updating according to your method. – robin_zhang Apr 12 '23 at 03:36
  • Note that you should be using `socks5h://` instead of `socks5://` (this pushes DNS resolution to the proxy). What happens if you use this code *exactly*, replacing only the host address, the proxy address, and the bearer token? – larsks Apr 12 '23 at 12:30
  • Thanks. I discovered through packet capture that the TLS protocol failed because the CA was unknown and the connection was reset. It finally succeeded after explicitly specifying verify_ssl = False when setting up SOCKSProxyManager. – robin_zhang Apr 13 '23 at 13:05