kubernetes - 使用 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
我能得到一些关于这可能出错的地方吗?
解决方案
经过一些试验和错误,使这项工作的解决方案如下:
- 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
必须匹配。
现在到更有趣的部分。
- 为 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 的流量都将转发到端点。
推荐阅读
- apache-kafka - 在本地计算机上设置多代理集群时出错
- javascript - 使用带有附件的 SendGrid 的 Azure 函数 (JS)
- pattern-matching - setoid_rewrite 在模式匹配场景中失败
- c# - 修改存储在并发容器中的元素时需要同步对象吗?
- php - Laravel 5.4:在 Eloquent 中使用 groupBy 关系 whereHas
- javascript - 剔除复选框 - 仅将选中的值推送到数组中
- database - 如何强制 PostgreSQL 外键与主键长度相同?
- javascript - SAP UI5如何刷新表中的模型数据
- java - 在 Spring 数据 mongodb 中从同一个 POJO 创建两个集合
- ios - “此时无法安装此应用程序”CFBundleIdentifier 错误