通过代理(CNTLM)代理 Kubernetes 出站流量

4
我正在尝试通过在主机上运行的CNTLM代理所有出站Kubernetes流量。一些背景信息:目前,我正在尝试在VM上设置Kubernetes集群,以用作项目的快速部署解决方案。不幸的是,所有不在公司网络中的出站流量都必须通过NTLM进行身份验证。在运行Kubernetes集群的主机上,CNTLM服务器运行在端口3128上。因此,我的目标是将来自Pod的所有流量重定向到主机:3128。我想到了以下几个想法:1. 修改主机的iptables以重新路由流量。对于基于Docker而不是Kubernetes的容器,这个方法效果很好(请参见https://hub.docker.com/r/ncarlier/redsocks/)。使用容器,您可以定义代理和白名单,这些白名单不应用于代理。这对于Kubernetes也适用吗?2. 另一个想法是启动一个Pod,将其他Pod的所有流量路由到该Pod。这个Pod充当CNTLM代理。不确定是否可行。机器设置:

Kubernetes在没有外部访问的情况下正常工作。

感谢任何帮助 :)

更新:

我已经尝试过像Artem Golenyaev提到的以下内容:

  • 编辑docker代理设置以使用代理(已重新加载+重启)
  • 编辑.bashrc +应用代理-

.bashrc的内容

export http_proxy=http://d050alapi138:3128
export HTTP_PROXY=$http_proxy
export https_proxy=$http_proxy
export HTTPS_PROXY=$http_proxy
printf -v lan '%s,' 53.190.251.237
printf -v service '%s,' 10.96.0.{1..253}
printf -v pool '%s,' 192.168.0.{1..253}
export no_proxy="${lan%,},${service%,},${pool%,},127.0.0.1";
export NO_PROXY=$no_proxy

/etc/systemd/system/docker.service.d/http-proxy.conf 的内容:

[Service]
Environment="HTTP_PROXY=http://d050alapi138:3128" "NO_PROXY=localhost,d050alapi138"

/etc/systemd/system/docker.service.d/https-proxy.conf 的内容:

[Service]
Environment="HTTPS_PROXY=http://d050alapi138:3128" "NO_PROXY=localhost,d050alapi138"

测试bash中代理是否工作:

d050alapi138:~ # curl google.de
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.de/">here</A>.
</BODY></HTML>

现在创建集群的脚本:
kubeadm init --apiserver-advertise-address=53.190.251.237 --service-cidr=10.96.0.0/16 --pod-network-cidr=192.168.0.0/24

export KUBECONFIG=/etc/kubernetes/admin.conf

kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml

kubectl taint nodes --all node-role.kubernetes.io/master-

节点启动后,我可以部署yml文件等内容。当我尝试在Pod内测试互联网连接时:
d050alapi138:~ # kubectl run my-shell2 --rm -i --tty --image ubuntu -- bash
If you don't see a command prompt, try pressing enter.
root@my-shell2-66df6fcdf4-4jhc8:/# apt-get update
0% [Connecting to archive.ubuntu.com (2001:67c:1360:8001::21)] [Connecting to security.ubuntu.com (2001:67c:1560:8001::11)]^C

它不起作用。首先,当我在容器内手动设置代理环境变量时,它可以工作。

root@my-shell2-66df6fcdf4-4jhc8:/# export http_proxy=http://d050alapi138:3128
root@my-shell2-66df6fcdf4-4jhc8:/# export https_proxy=$http_proxy
root@my-shell2-66df6fcdf4-4jhc8:/# apt-get update
Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:3 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
Get:4 http://archive.ubuntu.com/ubuntu bionic/universe Sources [11.5 MB]
0% [3 InRelease gpgv 74.6 kB] [4 Sources 0 B/11.5 MB 0%] [Waiting for headers]^C

也许这可以帮助理解我的问题。

你能解决这个问题吗?使用configMap作为envFrom可能是你的一个解决方案,你可以在这里找到更多信息。 - Mark
2个回答

0

您可以尝试使用常见解决方案“企业代理后面的Kubernetes”。

首先,您需要在所有节点上添加代理设置到Docker,以允许其下载映像。创建或修改/etc/systemd/system/docker.service.d/http-proxy.conf文件,并添加以下行(当然,您需要更改以下示例中的地址、端口和网络):

  • 对于HTTP代理:

    [Service]    
    Environment="HTTP_PROXY=<http://proxy.example.com>:<proxy_port>/" "NO_PROXY=localhost,127.0.0.1,<docker-registry.somecorporation.com>"
    
  • 对于HTTPS代理:

    [Service]    
    Environment="HTTPS_PROXY=<https://proxy.example.com>:<proxy_port>/" "NO_PROXY=localhost,127.0.0.1,<docker-registry.somecorporation.com>"
    

然后,您需要重新启动Docker守护进程:

systemctl daemon-reload
systemctl restart docker

其次,您需要在所有节点的.bashrc中添加代理设置,以将所需流量从这些节点转发到代理。以下是示例:

export http_proxy=<http://proxy.example.com>:<proxy_port>/
export HTTP_PROXY=$http_proxy
export https_proxy=<https://proxy.example.com>:<proxy_port>/
export HTTPS_PROXY=$http_proxy
printf -v lan '%s,' localip_of_machine 
printf -v pool '%s,' 192.168.0.{1..253}
printf -v service '%s,' 10.96.0.{1..253}
export no_proxy="${lan%,},${service%,},${pool%,},127.0.0.1";
export NO_PROXY=$no_proxy

此外,您需要使用自己的 http_proxy、https_proxy 和 no_proxy 设置。

如需更多信息,请访问以下链接:


1
我已经尝试过这个方法,但很遗憾它并没有起作用。我会更新我的问题,并附上我所做的步骤和结果。 - Eduard Marbach
你在所有节点上添加了代理设置吗?此外,你的本地机器IP地址看起来很奇怪,因为53.190.251.237看起来像是公共IP地址,但它应该是本地网络的IP地址。另外,请尝试检查Docker和Kubelet正在哪个用户下运行,并为这些用户添加代理设置。 - Artem Golenyaev

0

/etc/systemd/system/docker.service.d/http-proxy.conf中设置代理,这是Docker的代理设置。

你需要为正在运行的容器设置代理。 正如你所提到的,在容器内导出http代理后,连接就可以工作了。

你需要在主目录下创建一个文件,这样它将自动在容器内导出http代理。

~/.docker/config.json
{
        "proxies": {
                "default": {
                        "httpProxy": "<http://proxy.example.com>:<proxy_port>",
                        "httpsProxy": "<https://proxy.example.com>:<proxy_port>",
                        "noProxy": "${lan%,},${service%,},${pool%,},127.0.0.1"
                }
        }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接