代理 kubernetes 通过代理 (CNTLM) 的传出流量

Posted

技术标签:

【中文标题】代理 kubernetes 通过代理 (CNTLM) 的传出流量【英文标题】:Proxy kubernetes outgoing traffic via Proxy (CNTLM) 【发布时间】:2018-08-15 09:04:32 【问题描述】:

我正在尝试通过在主机上运行的 CNTLM 代理所有传出的 kubernetes 流量。

一点上下文:目前我正在尝试在 VM 上设置一个 kubernetes 集群,以用作项目的快速部署解决方案。遗憾的是,所有不在公司网络中的出站流量都必须通过 NTLM 进行身份验证。在运行 kubernetes 集群的主机上,cntlm 服务器在 3128 端口上运行。

所以我想要实现的是来自 pod 的所有流量都重定向到 host:3128。我想到的是以下想法:

修改主机的 iptables 以重新路由流量。这对于没有 Kubernetes 的基于 docker 的容器非常有效。 (见https://hub.docker.com/r/ncarlier/redsocks/)。使用该容器,您可以定义您的代理以及一个不应应用于代理的白名单。 Kubernetes 也可以这样做吗?

另一个想法是启动一个 Pod,来自其他 Pod 的所有流量都将路由到该 Pod。这个 pod 充当 CNTLM 代理。不确定这是否可能。

机器设置:

SLE12 SP2 Kubernetes 通过 kubeadm (Tut: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/) 网络插件:运河

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-

节点启动,我可以部署 ymls 等,当我尝试测试 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 可能是您的解决方案,您可以找到更多信息here 【参考方案1】:

您可以尝试使用称为“企业代理背后的 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 使用自己的设置。

欲了解更多信息,您可以访问以下链接:

HTTP/HTTPS proxy in Docker Example of configuring Kubernetes behind the corporate proxy

【讨论】:

我也试过这个,但遗憾的是它不起作用。我用我已经完成的步骤和结果来更新我的问题。 所有节点都添加代理设置了吗?另外,你有本地机器的奇怪 IP 地址,因为53.190.251.237 看起来像一个公共 IP 地址,但它应该是来自本地网络的 IP 地址。此外,尝试检查 Docker 和 Kubelet 正在运行的用户,并为这些用户添加代理设置。【参考方案2】:

/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"
                
        

【讨论】:

以上是关于代理 kubernetes 通过代理 (CNTLM) 的传出流量的主要内容,如果未能解决你的问题,请参考以下文章

yum repo 的 url 中带有 cntlm 代理和基本身份验证参数的空服务器响应

ubuntu12.04如何设置代理上网(需要域账户密码那种)?

为啥 CNTLM 要求输入密码?

在公司代理服务器后面安装Visual Studio 2017

企业代理背后的 Apache

通过 AWS 上的 ELB 在 Kubernetes 上公开单个 Kafka 代理