首页 > 解决方案 > 使用 kubernetes 服务对代理地址进行 DNS 解析时无法路由到外部 http 代理

问题描述

我有一个用例,我们希望通过公司 HTTP 代理路由某些请求。根据指南,我能够成功配置外部访问。对于上下文,我添加了一个示例 ServiceEntry:


apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: proxy
spec:
  addresses:
    - 10.1.1.1
    - 10.1.1.2
  exportTo:
  - .
  hosts:
  - foo.proxy # this is technically ignored when protocol is TCP
  location: MESH_EXTERNAL
  ports:
  - name: tcp
    number: 3128
    protocol: TCP

当我们让应用程序自动解析到上述代理地址之一(即:主机文件条目)时,此方法有效。

为了提供自动 DNS 解析,我根据文档设置了没有选择器的 k8s 服务。在非 istio命名空间中,这允许我在foo.proxy.default.cluster.local没有主机文件条目的情况下按预期进行解析,例如:

curl -v --proxy foo.default.svc.cluster.local:3128 https://blah.com

但是,在具有现有 ServiceEntry(上图)的 istio 命名空间中,它会失败并显示404 Not Found. 日志显示:

2021-08-11T08:56:47.088919Z debug   envoy router    [C1114][S1115555414526221653] no cluster match for URL ''
2021-08-11T08:56:47.088928Z debug   envoy http  [C1114][S1115555414526221653] Sending local reply with details route_not_found

我能得到一些关于这可能出错的地方吗?

标签: kubernetesproxyistio

解决方案


经过一些试验和错误,使这项工作的解决方案如下:

  1. K8s 服务必须有一个命名端口

例如,我有:

apiVersion: v1
kind: Service
metadata:
  name: foo
spec:
  ports:
    - protocol: TCP
      port: 8080      

但它必须包括spec.ports.[].name

apiVersion: v1
kind: Service
metadata:
  name: foo
spec:
  ports:
    - protocol: TCP
      name: tcp # critial. alternatively prefix any name with protocol-<name>
      port: 8080      

这记录在: https ://istio.io/v1.9/docs/ops/configuration/traffic-management/protocol-selection/

为了完整起见,这里是 k8s Endpoints 示例:

apiVersion: v1
kind: Endpoints
metadata:
  name: foo
subsets:
  - addresses:
      - ip: 10.1.1.1
      - ip: 10.1.1.2
    ports:
      - port: 8080

端点metadata.name和服务metadata.name必须匹配。

现在到更有趣的部分。

  1. 为 VIP 创建一个服务条目。

我用以下内容替换了我原来的 ServiceEntry:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: foo-forward-proxy
spec:
  hosts:
  - foo.default.svc.cluster.local
  addresses:
  - 172.20.254.32 # my foo service ClusterIP
  location: MESH_EXTERNAL
  ports:
  - number: 8080
    name: tcp
    protocol: TCP
  resolution: STATIC
  endpoints:
  - address: 10.1.1.1
  - address: 10.1.1.2

这将 k8s 服务 IP 声明172.20.254.32为 VIP,其名称foo.default.svc.cluster.local恰好是服务名称。所有在端口 8080 上发往 VIP 的流量都将转发到端点。


推荐阅读