python 如何通过 socks5 代理访问 k8s api client?

新手上路,请多包涵

更新一下背景:
源端是 k8s 的 pod,socks 服务器是 k8s 同命名空间的一个 pod,源端通过 svc name 访问 socks 服务器:proxy = "socks-server:1080"


不使用代理时访问 k8s apiclient 如下:这一类请求是可以成功的。

from urllib3.contrib.socks import SOCKSProxyManager
from kubernetes.client import api_client
from kubernetes.client.api import core_v1_api
from kubernetes import client

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)
# 查询命名空间,该步骤成功
result = api.list_namespace()

由于k8s使用的是rest client,所以没办法传递socks5代理,手动对实例化后的 rest client 赋值,结果是访问超时(无法连通):

# 省略导入信息

configuration = client.Configuration()
configuration.verify_ssl = False
configuration.api_key = {"authorization": "Bearer " + self.token}
c = api_client.ApiClient(configuration=configuration)
configuration.host = "xxx"
configuration.proxy = "socks5://xxx:1080"
# 该步骤设置socks代理
c.rest_client.pool_manager = SOCKSProxyManager(proxy_url=configuration.proxy)
api = core_v1_api.CoreV1Api(c)
# 查询命名空间,该步骤超时,无法连接
result = api.list_namespace()

通过以上方式发送请求依旧超时,查看socks代理服务器上的请求,发现tcp包里面没有host的信息。
请教下怎么通过 socks5 代理访问 k8s 的 api client,以上的方式是否有误?

阅读 2.1k
2 个回答

你的代码已经正确地设置了代理,但是可能需要进行一些调整以确保使用代理时能正确传递host信息。可以试一下下面的代码,通过在 ApiClient 类中重写 request 方法来添加代理支持:

from kubernetes.client import ApiClient
from kubernetes.client import Configuration
from kubernetes.client.api import CoreV1Api
from urllib3.contrib.socks import SOCKSProxyManager

class ApiClientWithSocksProxy(ApiClient):
    def __init__(self, configuration):
        super().__init__(configuration)
        self.pool_manager = SOCKSProxyManager(proxy_url=configuration.proxy, socket_options=self.pool_manager.connection_pool_kw['socket_options'])

# 省略导入信息

configuration = Configuration()
configuration.verify_ssl = False
configuration.api_key = {"authorization": "Bearer " + self.token}
configuration.host = "xxx"
configuration.proxy = "socks5://xxx:1080"

# 使用自定义的 ApiClient 类创建实例
c = ApiClientWithSocksProxy(configuration=configuration)

api = CoreV1Api(c)
# 查询命名空间,该步骤超时,无法连接
result = api.list_namespace()

这段代码创建了一个自定义的 ApiClientWithSocksProxy 类,继承自 ApiClient 并重写了 init 方法,以使用 SOCKSProxyManager 替换默认的连接池管理器。这样做可以确保在使用代理时能正确传递host信息。

可以考虑使用第三方库 socks 来实现通过 socks5 代理访问 k8s 的 api client。具体步骤如下:

  1. 安装 socks 库。
pip install PySocks
  1. 导入 socks 库并使用 socks.socksocket 替换默认的 socket 模块。
import socks
import socket
from kubernetes.client import api_client
from kubernetes.client.api import core_v1_api
from kubernetes import client

socks.set_default_proxy(socks.SOCKS5, "localhost", 1080)
socket.socket = socks.socksocket

注意:这里的代理地址应该根据实际情况进行修改。

  1. 创建 kubernetes 的 api client。
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)
# 查询命名空间,该步骤应该成功
result = api.list_namespace()

参考文档:https://github.com/Anorov/PySocks

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题