我有一个 Grpc 应用程序(java + maven)。 grpc 服务器和客户端都使用 istio 部署在 minikube 集群上。当 grpc 客户端尝试向服务器发出 grpc 调用时,会出现错误
SEVERE: Servlet.service() for servlet [ServerSubsetServlet] in context with path [/grpc_client] threw exception
io.grpc.StatusRuntimeException: UNAVAILABLE: Failed to find virtual host matching hostname: grpc-server-service.grpc-istio.svc.cluster.local:9090
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:271)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:252)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:165)
at com.example.grpcproto.GrpcIstioRoutingServerGrpc$GrpcIstioRoutingServerBlockingStub.getServerSubset(GrpcIstioRoutingServerGrpc.java:157)
at org.example.GrpcClientHandler.getServerSubset(GrpcClientHandler.java:39)
at org.example.ServerSubsetTestServlet.doGet(ServerSubsetTestServlet.java:23)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
服务器端目标规则和虚拟服务
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: grpc-server-destination
namespace: grpc-istio
spec:
host: grpc-server-service.grpc-istio.svc.cluster.local
subsets:
- name: server-1
labels:
server: server-1
- name: server-2
labels:
server: server-2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grpc-server-route
namespace: grpc-istio
spec:
hosts:
- grpc-server-service.grpc-istio.svc.cluster.local
http:
- match:
- headers:
SERVER:
exact: "server-1"
route:
- destination:
host: grpc-server-service.grpc-istio.svc.cluster.local
subset: server-1
- match:
- headers:
SERVER:
exact: "server-2"
route:
- destination:
host: grpc-server-service.grpc-istio.svc.cluster.local
subset: server-2
客户端部署yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpc-client
namespace: grpc-istio
labels:
name: grpc-client
spec:
replicas: 1
selector:
matchLabels:
app: grpc-client
template:
metadata:
labels:
app: grpc-client
annotations:
sidecar.istio.io/inject: 'true'
proxy.istio.io/config: 'holdApplicationUntilProxyStarts: true'
inject.istio.io/templates: 'grpc-agent'
spec:
containers:
- name: grpc-client
image: grpc-client:latest
imagePullPolicy: IfNotPresent
env:
- name: GRPC_SERVER_ADDRESS
value: "xds:///grpc-server-service.grpc-istio.svc.cluster.local:9090"
ports:
- containerPort: 8080
没有 envoy 代理 side car,GRPC 客户端和服务器能够使用通道进行通信,但是当部署 sidecar 容器并使用虚拟服务和目标规则进行请求路由时,客户端会收到上述错误
无法了解虚拟服务/DestinationRule 出了什么问题!!
预期行为:
安装就像我们可以点击 grpc 客户端一样,它也公开了 8080 端口用于 HTTP 调用, 当我们使用参数 server-1 或 server-2 进行 http 调用时,它会将 grpc 调用定向到具有相同相应标签的服务器
有2个不同标签的服务器部署 每个部署都有 2 个副本。
因此,当 grp 客户端在标头元数据中使用 server-1 发出请求时,调用应该转到带有 server: server-1 标签的 pod,同样,当使用 server-2 标头发出请求时,调用应该转到转到标签为 server: server-2
的 Pod---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpc-server-1
namespace: grpc-istio
labels:
name: grpc-server-1
server: server-1
spec:
replicas: 2
selector:
matchLabels:
app: grpc-server
template:
metadata:
labels:
app: grpc-server
server: server-1
annotations:
sidecar.istio.io/inject: 'true'
proxy.istio.io/config: 'holdApplicationUntilProxyStarts: true'
inject.istio.io/templates: 'grpc-agent'
spec:
containers:
- name: grpc-server
image: grpc-server:latest
imagePullPolicy: Never
env:
- name: SERVER
value: "SERVER_1"
ports:
- containerPort: 9090
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpc-server-2
namespace: grpc-istio
labels:
name: grpc-server-2
spec:
replicas: 2
selector:
matchLabels:
app: grpc-server
template:
metadata:
labels:
app: grpc-server
server: server-2
annotations:
sidecar.istio.io/inject: 'true'
proxy.istio.io/config: 'holdApplicationUntilProxyStarts: true'
inject.istio.io/templates: 'grpc-agent'
spec:
containers:
- name: grpc-server
image: grpc-server:latest
imagePullPolicy: Never
env:
- name: SERVER
value: "SERVER_2"
ports:
- containerPort: 9090
在客户端的部署规范中,我看到名为 GRPC_SERVER_ADDRESS 的内容被设置为
xds:///grpc-server-service.grpc-istio.svc.cluster.local:9090
,它仅在无代理模式下工作。在代理模式下(使用 Envoy sidecar),您需要删除 xds:///
前缀,以便访问通过 DNS 查找和 sidecar。