Virtual Service未按预期生效:限制仅通过third访问first失败求助
你遇到的问题核心在于VirtualService 是用来做流量路由的,不是访问控制,而且直接访问 ClusterIP 时,你的 VirtualService 规则根本不会生效。下面具体拆解原因和解决办法:
1. 为什么直接访问 ClusterIP 能绕过规则?
你的 VirtualService 指定的 hosts 是 aks-helloworld-first,这意味着只有当请求的 Host 头是这个服务名时,Istio 才会应用你定义的路由规则。而你在 second Pod 里执行 curl -v http://10.67.251.251 时,请求的 Host 是 ClusterIP 地址,完全匹配不到 VirtualService 的 hosts 配置,Istio 会直接按照 Kubernetes Service 的默认逻辑转发流量,自然能访问到 first Pod。
2. 为什么用服务名访问时,second 也能访问?
假设你用服务名 curl aks-helloworld-first 访问,这时候 VirtualService 会生效,但它的逻辑是:匹配到 sourceLabels 为 helloworld-third 的请求,路由到 first;没有匹配到的请求,Istio 会走默认路由(也就是直接转发到 first)。VirtualService 不会自动拒绝未匹配的请求,它只是补充路由规则,而非做权限限制。
正确的解决方案:结合 AuthorizationPolicy 做访问控制
要实现「仅允许 third Pod 访问 first」,你需要添加 Istio 的 AuthorizationPolicy 来限制访问权限,同时确保请求通过服务名访问(让规则能正确识别目标服务)。
步骤1:添加 AuthorizationPolicy
创建一个拒绝所有未授权访问的策略,只允许带有 app: helloworld-third 标签的 Pod 访问 aks-helloworld-first 服务:
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: restrict-first-access spec: selector: matchLabels: app: helloworld-first # 目标是 first Pod 的标签 action: ALLOW rules: - from: - source: labels: app: helloworld-third # 仅允许来自 third Pod 的请求 to: - operation: methods: ["*"] # 允许所有 HTTP 方法
步骤2:确保请求通过服务名访问
之后在测试时,应该使用服务名而非 ClusterIP 访问,比如在 second Pod 里执行:
curl -v http://aks-helloworld-first
这时候请求会被 AuthorizationPolicy 拦截,返回 403 禁止访问;而在 third Pod 里执行同样的命令则能正常访问。
补充:如果必须用 ClusterIP 访问?
如果业务场景中必须直接用 ClusterIP 访问,你需要调整 AuthorizationPolicy 的目标为 Kubernetes Service 对应的资源,或者在 VirtualService 中添加 ClusterIP 到 hosts(但不推荐,因为 ClusterIP 可能变化)。更稳妥的方式是始终通过服务名访问,这也是 Kubernetes 和 Istio 推荐的服务发现方式。
内容的提问来源于stack exchange,提问作者inza

