gRPC 服务通过 Istio 网格通信

网络 通信技术
本文通过gRCP服务消费方mesha和gRPC服务提供方meshb,验证其部署在Istio网格的通信过程。通过该示例可以将外部注册中心接入网格,不再困难。

[[433796]]

引言

本文通过gRCP服务消费方mesha和gRPC服务提供方meshb,验证其部署在Istio网格的通信过程。通过该示例可以将外部注册中心接入网格,不再困难。

一、Isito配置提点

在Kubernetes集群中已安装了Isito,并查验下面几个参数是否正确设置。

istio-config.yaml内容

  1. --- 
  2. apiVersion: install.istio.io/v1alpha1 
  3. kind: IstioOperator 
  4. spec: 
  5.   profile: default 
  6.   values
  7.     global
  8.       logging: 
  9.         leveldefault:debug 
  10.   meshConfig: 
  11.     accessLogFile: /dev/stdout 
  12.     defaultConfig: 
  13.       holdApplicationUntilProxyStarts: true 
  14.       proxyMetadata: 
  15.         ISTIO_META_DNS_CAPTURE: "true" 
  16.         ISTIO_META_DNS_AUTO_ALLOCATE: "true" 
  17.   components: 
  18.     pilot: 
  19.       hub: istio 
  20.       tag: 1.10.4 

关键参数说明

参数 说明
holdApplicationUntilProxyStarts 默认false,设置为true表示业务容器需在sidecar Proxy容器启动完毕后启动
ISTIO_META_DNS_CAPTURE 默认false,设置为true表示开启DNS代理,DNS的请求将被转发到sidecar
ISTIO_META_DNS_AUTO_ALLOCATE 默认false,设置为true表示DNS代理将自动为ServiceEntrys分配IP,不需要指定

执行如下命令生效配置

  1. istioctl install -y -f istio-config.yaml 

通过如下命令验证生效后的配置

  1. kubectl describe IstioOperator installed-state -n istio-system >> istioOperator.conf 

二、示例说明

定义Proto

通过简单方法SayHello完成client与server通信。

  1. syntax = "proto3"
  2.  
  3. option java_multiple_files = true
  4. option java_package = "com.melon.test.client.grpc"
  5. option java_outer_classname = "HelloMesh"
  6.  
  7. package meshgrpc; 
  8.  
  9. service Mesher { 
  10.  
  11.   rpc SayHello (HelloRequest) returns (HelloReply) {} 
  12.  
  13. message HelloRequest { 
  14.   string name = 1; 
  15.  
  16. message HelloReply { 
  17.   string message = 1; 

服务消费方mesha

  1. @RestController 
  2. public class MeshSender { 
  3.  
  4.     @GetMapping("demo"
  5.     public String meshWorker(){ 
  6.  
  7.          String target = "dns:///AppMeshClient.mesh:50000"
  8.         // String  target = "127.0.0.1:50000"
  9.         ManagedChannel channel = ManagedChannelBuilder.forTarget(target) 
  10.                 .usePlaintext() 
  11.                 .build(); 
  12.         MesherGrpc.MesherBlockingStub blockingStub = MesherGrpc.newBlockingStub(channel); 
  13.         HelloRequest request = HelloRequest.newBuilder().setName("mesh demo!").build(); 
  14.         HelloReply reply = blockingStub.sayHello(request); 
  15.         System.out.println(reply.getMessage()); 
  16.         return reply.getMessage(); 
  17.  
  18.     } 

服务提供方meshb

  1. @Component 
  2. public class MeshReceiver { 
  3.  
  4.  
  5.   @PostConstruct 
  6.   public void receiverWorker() throws IOException { 
  7.     int port = 50000; 
  8.     Server server = ServerBuilder.forPort(port) 
  9.       .addService(new MeshBService()) 
  10.       .build() 
  11.       .start(); 
  12.     System.out.println("Server started."); 
  13.   } 
  14.  
  15.   class  MeshBService extends MesherGrpc.MesherImplBase { 
  16.  
  17.     public void sayHello(HelloRequest request, 
  18.                          io.grpc.stub.StreamObserver<HelloReply> responseObserver) { 
  19.  
  20.       System.out.println("receiver client message: " + request.getName()); 
  21.       HelloReply reply = HelloReply.newBuilder().setMessage("I'm from server " + request.getName()).build(); 
  22.       responseObserver.onNext(reply); 
  23.       responseObserver.onCompleted(); 
  24.     } 
  25.   } 
  26.  

镜像推送

  1. <plugin> 
  2.   <groupId>com.google.cloud.tools</groupId> 
  3.   <artifactId>jib-maven-plugin</artifactId> 
  4.   <version>3.1.4</version> 
  5.   <configuration> 
  6.     <from
  7.       <image> 
  8.         harbor.x.x/x/java:8u212-full 
  9.       </image> 
  10.       <auth> 
  11.         <username>${harbor.username}</username> 
  12.         <password>${harbor.password}</password
  13.       </auth> 
  14.     </from
  15.     <to
  16.       <image>x.x.x/x/${project.name}</image> 
  17.       <auth> 
  18.         <username>${harbor.username}</username> 
  19.         <password>${harbor.password}</password
  20.       </auth> 
  21.       <tags> 
  22.         <tag>${project.version}</tag> 
  23.         <tag>latest</tag> 
  24.       </tags> 
  25.     </to
  26.     <container> 
  27.       <ports> 
  28.         <port>x</port> 
  29.       </ports> 
  30.       <creationTime>USE_CURRENT_TIMESTAMP</creationTime> 
  31.     </container> 
  32.   </configuration> 
  33. </plugin> 

 

 

 

说明:通过maven插件jib,执行命令如下命令「mvn compile jib:build」将镜像推到harbor仓库

三、gRPC服务提供方部署

设置meshb服务的Deployment

  1. --- 
  2. apiVersion: apps/v1 
  3. kind: Deployment 
  4. metadata: 
  5.   name: meshb 
  6.   labels: 
  7.     app: meshb 
  8. spec: 
  9.   selector: 
  10.     matchLabels: 
  11.       app: meshb 
  12.   replicas: 1 
  13.   template: 
  14.     metadata: 
  15.       labels: 
  16.         app: meshb 
  17.     spec: 
  18.       imagePullSecrets: 
  19.         - name: xxxx #仓库名称 
  20.       containers: 
  21.         - name: meshb 
  22.           image: x.x.x.x/x/meshb:latest 
  23.           imagePullPolicy: Always 
  24.           ports: 
  25.             - containerPort: 50000 

执行下面命令生效

  1. kubectl apply -f meshb.yaml 
  2. deployment.apps/meshb created 

查看运行状态正常

  1. # kubectl get pods 
  2. NAME                                READY   STATUS    RESTARTS   AGE 
  3. meshb-565945d794-wcb8z              2/2     Running   0          9m19s 

查看启动日志启动成功

  1. # kubectl logs meshb-565945d794-wcb8z -n default 
  2.  
  3.  Server started. 
  4. 2021-11-05 09:21:19.828  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8181 (http) with context path '' 
  5. 2021-11-05 09:21:19.847  INFO 1 --- [           main] com.melon.test.MeshbApplication          : Started MeshbApplication in 3.859 seconds (JVM running for 4.344) 

备注:至此gRPC服务提供方已部署完成。

四、gRPC服务消费方部署

设置mesha服务的Deployment

  1. --- 
  2. apiVersion: apps/v1 
  3. kind: Deployment 
  4. metadata: 
  5.   name: mesha 
  6.   labels: 
  7.     app: mesha 
  8. spec: 
  9.   selector: 
  10.     matchLabels: 
  11.       app: mesha 
  12.   replicas: 1 
  13.   template: 
  14.     metadata: 
  15.       labels: 
  16.         app: mesha 
  17.     spec: 
  18.       imagePullSecrets: 
  19.         - name: middleware 
  20.       containers: 
  21.         - name: mesha 
  22.           image: harbor.hellobike.cn/base/mesha:latest 
  23.           ports: 
  24.             - containerPort: 7171 
  25.           imagePullPolicy: Always 
  26. --- 
  27. apiVersion: v1 
  28. kind: Service 
  29. metadata: 
  30.   name: mesha 
  31. spec: 
  32.   selector: 
  33.     app: mesha 
  34.   type: LoadBalancer 
  35.   ports: 
  36.     - name: web 

执行命令部署

  1. # kubectl apply -f mesha.yaml 
  2.  
  3. deployment.apps/mesha created 
  4.  
  5. service/mesha created 

查看服务状态

  1. # kubectl get service 
  2. NAME                      TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE 
  3. mesha                     LoadBalancer   10.x.61.x    <pending>     7171:30514/TCP   20s 

查看Pod运行状态

  1. # kubectl get pods 
  2. NAME                                READY   STATUS     RESTARTS   AGE 
  3. mesha-b559fc4f4-m9752               2/2     Running    0          87s 

备注:至此服务消费方已部署完成。

四、服务调用验证

通过域名访问

  1. http://x.x.x.x:30514/demo 

页面打印如下错误

查看日志发现域名无法解析:

  1. kubectl logs -f mesha-b559fc4f4-m9752  -n default 
  2.  
  3. 2021-11-05 09:01:37.372  WARN 1 --- [ault-executor-0] io.grpc.internal.ManagedChannelImpl      : [Channel<1>: (dns:///AppMeshClient.mesh:50000)] Failed to resolve name. status=Status{code=UNAVAILABLE, description=Unable to resolve host AppMeshClient.mesh, cause=java.lang.RuntimeException: java.net.UnknownHostException: AppMeshClient.mesh: Name or service not known 
  4.  at io.grpc.internal.DnsNameResolver.resolveAll(DnsNameResolver.java:436) 
  5.  at io.grpc.internal.DnsNameResolver$Resolve.resolveInternal(DnsNameResolver.java:272) 
  6.  at io.grpc.internal.DnsNameResolver$Resolve.run(DnsNameResolver.java:228) 
  7.  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 
  8.  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 
  9.  at java.lang.Thread.run(Thread.java:748) 
  10. Caused by: java.net.UnknownHostException: AppMeshClient.mesh: Name or service not known 
  11.  at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) 
  12.  at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:929) 
  13.  at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1324) 
  14.  at java.net.InetAddress.getAllByName0(InetAddress.java:1277) 
  15.  at java.net.InetAddress.getAllByName(InetAddress.java:1193) 
  16.  at java.net.InetAddress.getAllByName(InetAddress.java:1127) 
  17.  at io.grpc.internal.DnsNameResolver$JdkAddressResolver.resolveAddress(DnsNameResolver.java:646) 
  18.  at io.grpc.internal.DnsNameResolver.resolveAll(DnsNameResolver.java:404) 
  19.  ... 5 more 

通过ServiceEntry映射服务提供方IP

查看服务提供方meshb的IP为x.x.0.17

  1. # kubectl get pods -o wide 
  2. NAME                                READY   STATUS    RESTARTS   AGE     IP             NODE                NOMINATED NODE   READINESS GATES 
  3. mesha-b559fc4f4-m9752               2/2     Running   0          140m    x.x.1.117   k8s-servicemesh-3   <none>           <none> 
  4. meshb-565945d794-wcb8z              2/2     Running   0          118m    x.x.0.17    k8s-servicemesh-1   <none>           <none> 

meshb-service-entry.yaml内容

  1. apiVersion: networking.istio.io/v1alpha3 
  2. kind: ServiceEntry 
  3. metadata: 
  4.   name: meshb 
  5. spec: 
  6.   endpoints: 
  7.     - address: x.x.0.17 
  8.   hosts: 
  9.     - AppMeshClient.mesh 
  10.   location: MESH_INTERNAL 
  11.   ports: 
  12.     - name: grpc 
  13.       number: 50000 
  14.       protocol: grpc 
  15.   resolution: STATIC 

执行如下命令ServiceEntry生效

  1. kubectl apply -f meshb-service-entry.yaml 
  2. serviceentry.networking.istio.io/meshb created 

再访问页面发现已经正常

备注:至此服务消费方在网格中向服务提供方发起调用。

五、日志校验追踪

查看服务消费方mesha日志

  1. kubectl logs -f mesha-b559fc4f4-m9752  -n default 
  2.  
  3. I'm from server mesh demo! 

备注:服务消费方mesha从服务提供方meshb返回的信息。

查看服务提供方meshb日志

  1. # kubectl logs -f meshb-565945d794-wcb8z -n default 
  2.  
  3. 2021-11-05 09:21:19.828  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8181 (http) with context path '' 
  4. 2021-11-05 09:21:19.847  INFO 1 --- [           main] com.melon.test.MeshbApplication          : Started MeshbApplication in 3.859 seconds (JVM running for 4.344) 
  5. receiver client message: mesh demo! 

备注:服务提供方meshb收到了服务消费方mesha的请求。

查看服务消费方mesha的envoy日志

  1. kubectl logs -f -l app=mesha -c istio-proxy -n default 
  2. 2021-11-05T10:25:17.772317Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012 
  3. 2021-11-05T10:52:35.856445Z warning envoy config StreamAggregatedResources gRPC config stream closed: 14, transport is closing 
  4. 2021-11-05T10:52:36.093048Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012 
  5. [2021-11-05T11:06:23.510Z] "GET /demo HTTP/1.1" 500 - via_upstream - "-" 0 287 37 36 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36" "49cd74d8-86eb-4ef5-bd71-8236d188c2f9" "10.69.31.156:30514" "10.166.1.117:7171" inbound|7171|| 127.0.0.6:41007 10.166.1.117:7171 10.166.0.0:20826 - default 
  6. 2021-11-05T11:22:58.633956Z warning envoy config StreamAggregatedResources gRPC config stream closed: 14, transport is closing 
  7. 2021-11-05T11:22:59.100387Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012 
  8. [2021-11-05T11:27:23.842Z] "POST /meshgrpc.Mesher/SayHello HTTP/2" 200 - via_upstream - "-" 17 33 371 319 "-" "grpc-java-netty/1.28.0" "79f2edbd-9c31-4265-87fb-38a594d9383b" "AppMeshClient.mesh:50000" "10.166.0.17:50000" outbound|50000||AppMeshClient.mesh 10.166.1.117:51914 240.240.0.63:50000 10.166.1.117:40544 - default 
  9. [2021-11-05T11:27:23.527Z] "GET /demo HTTP/1.1" 200 - via_upstream - "-" 0 26 729 728 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36" "859344b6-012d-4457-a391-2b4d13aa3e35" "10.69.31.156:30514" "10.166.1.117:7171" inbound|7171|| 127.0.0.6:47065 10.166.1.117:7171 10.166.0.0:2410 - default 

查看服务消费方meshb的envoy日志

  1. # kubectl logs -f -l app=meshb -c istio-proxy -n default 
  2. 2021-11-05T09:57:12.490428Z warning envoy config StreamAggregatedResources gRPC config stream closed: 14, transport is closing 
  3. 2021-11-05T09:57:12.765887Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012 
  4. 2021-11-05T10:24:48.767511Z warning envoy config StreamAggregatedResources gRPC config stream closed: 14, transport is closing 
  5. 2021-11-05T10:24:48.914475Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012 
  6. 2021-11-05T10:57:52.604281Z warning envoy config StreamAggregatedResources gRPC config stream closed: 14, transport is closing 
  7. 2021-11-05T10:57:52.757736Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012 
  8. 2021-11-05T11:26:56.551824Z warning envoy config StreamAggregatedResources gRPC config stream closed: 14, transport is closing 
  9. 2021-11-05T11:26:56.987345Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012 
  10. [2021-11-05T11:27:23.844Z] "POST /meshgrpc.Mesher/SayHello HTTP/2" 200 - via_upstream - "-" 17 33 333 316 "-" "grpc-java-netty/1.28.0" "79f2edbd-9c31-4265-87fb-38a594d9383b" "AppMeshClient.mesh:50000" "10.166.0.17:50000" inbound|50000|| 127.0.0.6:44221 10.166.0.17:50000 10.166.1.117:51914 - default 

登陆mesha的Pod中验证

  1. kubectl describe pod/mesha-b559fc4f4-m9752 -n default 
  2. [12:04:44root@mesha-b559fc4f4-m9752 /] C:2 
  3. # curl -v AppMeshClient.mesh 
  4. * About to connect() to AppMeshClient.mesh port 80 (#0) 
  5. *   Trying 240.240.0.63... 
  6. * Connected to AppMeshClient.mesh (240.240.0.63) port 80 (#0) 
  7. > GET / HTTP/1.1 
  8. User-Agent: curl/7.29.0 
  9. > Host: AppMeshClient.mesh 
  10. > Accept: */* 
  11. < HTTP/1.1 503 Service Unavailable 
  12. < content-length: 91 
  13. < content-type: text/plain 
  14. date: Fri, 05 Nov 2021 12:04:59 GMT 
  15. < server: envoy 
  16. Connection #0 to host AppMeshClient.mesh left intact 
  17. upstream connect error or disconnect/reset before headers. reset reason: connection failure 

备注:登陆mesha的Pod,通过访问域名AppMeshClient.mesh,发现其自动分配IP「240.240.0.63」并指向sidecar「envoy」,即会把业务容器的流量通过DNS Proxy重定向到sidecar。

说明:通过查看服务消费方日志、服务提供方日志以及其数据面enovy日志,说明其调用在istio网格中进行。

本文转载自微信公众号「瓜农老梁」,可以通过以下二维码关注。转载本文请联系瓜农老梁公众号。

 

责任编辑:武晓燕 来源: 瓜农老梁
相关推荐

2022-11-24 14:21:27

微服务ISTIO

2024-09-27 10:05:02

2023-11-01 08:08:22

k8s服务网格

2023-05-08 07:05:26

2022-07-01 18:36:17

云服务网络

2020-11-04 08:00:57

虚拟机stio网格

2021-09-30 07:03:12

gRPC服务Grpcurl

2021-10-26 00:10:18

信息EnvoyServiceEntr

2018-11-07 10:00:00

微服务Service MesIstio

2018-08-28 18:11:40

华为云

2021-12-05 23:14:24

微服务GolanggRPC

2022-12-22 08:00:00

Istio 1.16网络环境

2020-06-04 07:48:08

Istio服务注册API Server

2024-12-04 08:50:03

2021-07-12 06:23:38

抓包gRpcRPC 框架

2023-06-18 19:21:04

技术架构服务网格

2019-08-29 08:00:00

微服务架构服务网格

2023-11-20 07:19:33

2019-09-25 07:17:42

KubernetesIstio测试
点赞
收藏

51CTO技术栈公众号