OpenShift多租户SDN下不联网跨命名空间访问服务问题咨询
嘿,我来帮你搞定这个OpenShift跨命名空间访问的难题!针对你用SDN多租户插件、不能加入项目网络的场景,我整理了两个可行的方案,帮你解决之前遇到的问题:
方案一:手动创建Endpoint + 无Selector Service
你之前尝试创建Endpoint但Service失败,核心原因是创建Service时必须显式指定type字段(哪怕用默认的ClusterIP也要写出来),而且要保证Endpoint和Service同名、端口匹配。具体步骤如下:
获取NS2服务的外部访问信息
先确认NS2的服务有外部可访问的IP和端口:- 如果用了NodePort:取任意集群节点的IP,加上服务的NodePort端口
- 如果用了LoadBalancer:取LoadBalancer分配的外部IP和服务端口
- 确保这个外部地址在集群内(NS1的Pod)可以正常访问
在NS1创建无Selector的ClusterIP Service
创建一个没有selector字段的Service,用来关联后续的Endpoint:apiVersion: v1 kind: Service metadata: name: ns2-service-proxy namespace: ns1 spec: ports: - name: http port: 8080 # NS1应用访问这个Service时用的端口 targetPort: 8080 # NS2服务实际监听的端口 type: ClusterIP # 必须显式指定,避免因默认值缺失报错在NS1创建对应Endpoint
Endpoint的名称必须和上面的Service完全一致,指向NS2服务的外部IP和端口:apiVersion: v1 kind: Endpoints metadata: name: ns2-service-proxy # 与Service同名,才能自动关联 namespace: ns1 subsets: - addresses: - ip: 192.168.1.100 # NS2服务的外部IP(比如节点IP/LoadBalancer IP) ports: - name: http port: 30080 # NS2服务的外部端口(比如NodePort)
完成后,NS1里的应用就可以通过ns2-service-proxy.ns1.svc.cluster.local:8080访问NS2的服务了。
方案二:修正ExternalName Service的用法
你用ExternalName时遇到“Application is not available”,问题出在Host头不匹配:OpenShift路由是基于Host头匹配的,但你的应用访问ExternalName Service时,请求的Host头是Service的内部域名(比如ns2-service-proxy.ns1.svc.cluster.local),而路由期望的是它自己的域名(比如ns2-service-route.apps.cluster.example.com),所以路由拒绝了请求。
修正方法如下:
创建正确的ExternalName Service
apiVersion: v1 kind: Service metadata: name: ns2-service-proxy namespace: ns1 spec: type: ExternalName externalName: ns2-service-route.apps.cluster.example.com # 路由域名(去掉http/https前缀) ports: - name: https port: 443 targetPort: 443 # 对应路由的端口(HTTP用80)访问时指定正确的Host头
让NS1的应用在请求时显式设置Host头为路由的域名。比如用curl测试:curl -H "Host: ns2-service-route.apps.cluster.example.com" https://ns2-service-proxy.ns1.svc.cluster.local如果是你自己开发的应用,在HTTP请求里添加Host头即可。
关键注意事项
- 无论用哪种方案,都要先确认NS2的服务通过外部地址/路由可以正常访问(比如在集群节点上curl测试)
- 用Endpoint方案时,不能用NS2的Pod IP,因为SDN多租户隔离了命名空间,NS1的Pod无法直接访问NS2的内部IP
- ExternalName方案只做DNS解析,不处理流量转发,所以必须保证请求的Host头和路由匹配
内容的提问来源于stack exchange,提问作者Vito Karleone

