使用 kubernetes 服务进行代理地址的 DNS 解析时无法路由到外部 http 代理
Unable to route to external http proxy when using a kubernetes service for DNS resolution of proxy addresses
我有一个用例,我们希望通过企业 HTTP 代理路由某些请求。根据 this 指南,我能够成功配置外部访问。对于上下文,我添加了一个示例 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 Service without selectors。在 non 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
我能得到一些关于这可能出错的地方的指示吗?
经过反复试验,使这项工作的解决方案如下:
- 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 端点示例:
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
必须匹配。
现在进入更有趣的部分。
- 为 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
声明为名称为 foo.default.svc.cluster.local
的 VIP,恰好是服务名称。所有发往端口 8080 上的 VIP 的流量都将转发到端点。
我有一个用例,我们希望通过企业 HTTP 代理路由某些请求。根据 this 指南,我能够成功配置外部访问。对于上下文,我添加了一个示例 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 Service without selectors。在 non 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
我能得到一些关于这可能出错的地方的指示吗?
经过反复试验,使这项工作的解决方案如下:
- 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 端点示例:
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
必须匹配。
现在进入更有趣的部分。
- 为 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
声明为名称为 foo.default.svc.cluster.local
的 VIP,恰好是服务名称。所有发往端口 8080 上的 VIP 的流量都将转发到端点。