OpenShift集群内虚拟机中运行的应用无法外部访问,求解决方案
OpenShift 4.14 单节点集群中虚拟机应用的外部访问方案
核心原因
普通Pod+Service+Route的方式不生效,是因为虚拟机不属于K8s原生Pod对象,Service的标签选择器无法关联虚拟机;手动创建Endpoint时若配置有误,也会导致访问失败。以下是经过验证的可行方案:
方案一:手动创建Endpoint + Service + Route
这是最灵活的方式,适用于需要自定义服务配置的场景:
创建Endpoint
指定虚拟机的集群内部可达IP和服务端口(此处为80),需与后续Service同名同命名空间:apiVersion: v1 kind: Endpoints metadata: name: vm-nginx-svc namespace: <你的命名空间> subsets: - addresses: - ip: <虚拟机集群内部IP> ports: - port: 80 name: http protocol: TCP创建无选择器的Service
由于没有标签选择器,Service会自动关联同名的Endpoint,单节点集群推荐使用NodePort类型:apiVersion: v1 kind: Service metadata: name: vm-nginx-svc namespace: <你的命名空间> spec: ports: - port: 80 targetPort: 80 name: http protocol: TCP type: NodePort创建Route关联Service
通过Route将Service暴露到集群外部:apiVersion: route.openshift.io/v1 kind: Route metadata: name: vm-nginx-route namespace: <你的命名空间> spec: to: kind: Service name: vm-nginx-svc port: targetPort: http # 可选:配置TLS终止 tls: termination: edge
方案二:通过OpenShift Virtualization原生暴露服务
利用Kubevirt(OpenShift Virtualization核心组件)自动生成Service和Endpoint,无需手动配置:
编辑虚拟机的VirtualMachine或VirtualMachineInstance资源,添加expose字段:
apiVersion: kubevirt.io/v1 kind: VirtualMachine metadata: name: <你的虚拟机名称> namespace: <你的命名空间> spec: template: spec: # 添加服务暴露配置 expose: - port: 80 targetPort: 80 serviceType: NodePort protocol: TCP name: http # 保留原有虚拟机配置 domain: cpu: cores: 1 resources: requests: memory: 1Gi networks: - name: default pod: {}
保存后,Kubevirt会自动创建对应的Service,之后直接为该Service创建Route即可完成外部暴露。
常见失败排查点
如果仍无法访问,检查以下内容:
- 虚拟机内部防火墙是否开放80端口(如
firewalld或iptables规则) - 集群节点防火墙是否开放NodePort端口范围(默认30000-32767)
- Endpoint的IP是否为虚拟机的集群内部可达IP(而非虚拟机内部私有IP)
- Service的
targetPort与Endpoint的port是否完全匹配 - Route的
targetPort是否与Service的端口名称/编号一致
内容的提问来源于stack exchange,提问作者ashraf minhaj
相关产品推荐
相关产品推荐

