基於阿里雲服務網格(ASM)的GRPC服務部署實踐

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"繼MicroServices之後,ServiceMesh是又一個推動軟件工業的革命性技術。其服務治理的方法論,不僅改變了技術實現的方式,也將深入影響社會分工。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"運行於數據平面的用戶服務與治理服務的各種規則徹底解耦。運行於控制平面的規則定義組件,將流量控制的具體規則推送給運行於數據平面的proxy,proxy通過對用戶服務的ingress和egress的實際控制,最終實現服務治理。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原本需要服務開發者編程實現的服務發現、容錯、灰度、流量複製等能力,被ServiceMesh非侵入的方式實現。此外,ServiceMesh還提供了訪問控制、認證授權等功能,進一步減輕了用戶服務的開發成本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"阿里雲提供的服務網格(ASM)(https://www.aliyun.com/product/servicemesh)是基於容器服務(https://www.aliyun.com/product/kubernetes)之上的託管版ServiceMesh,在提供完整的ServiceMesh能力的同時(ASM還在底層橫向拉通了阿里云云原生的各種能力,不在本篇講述範圍),免去了用戶搭建和運維ServiceMesh平臺istio的繁瑣工作。本篇將分享如何將我們自己的GRPC服務,託管到阿里雲的服務網格中。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1. grpc服務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"grpc協議相比http而言,既具備http跨操作系統和編程語言的好處,又提供了基於流的通信優勢。而且,grpc逐漸成爲工業界的標準,一旦我們的grpc服務可以mesh化,那麼更多的非標準協議就可以通過轉爲grpc協議的方式,低成本地接入服務網格,實現跨技術棧的服務通信。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"grpc服務的示例部分使用最普遍的編程語言Java及最高效的編程框架SpringBoot。示例的拓撲示意如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/13/13d2ce5d7f6a290ef93a9b2f75031de5.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1.1 springboot"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"common——proto2java"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"示例工程包含三個模塊,分別是"},{"type":"codeinline","content":[{"type":"text","text":"common"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"provider"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"consumer"}]},{"type":"text","text":"。其中,"},{"type":"codeinline","content":[{"type":"text","text":"common"}]},{"type":"text","text":"負責將定義grpc服務的protobuf轉換爲java的rpc模板代碼;後兩者對其依賴,分別實現grpc的服務端和客戶端。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"示例工程的protobuf定義如下,實現了兩個方法"},{"type":"codeinline","content":[{"type":"text","text":"SayHello"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"SayBye"}]},{"type":"text","text":"。"},{"type":"codeinline","content":[{"type":"text","text":"SayHello"}]},{"type":"text","text":"的入參是一個字符串,返回一個字符串;"},{"type":"codeinline","content":[{"type":"text","text":"SayBye"}]},{"type":"text","text":"只有一個字符串類型的出參。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"go"},"content":[{"type":"text","text":"syntax = \"proto3\";\nimport \"google/protobuf/empty.proto\";\npackage org.feuyeux.grpc;\n\noption java_multiple_files = true;\noption java_package = \"org.feuyeux.grpc.proto\";\n\nservice Greeter {\n rpc SayHello (HelloRequest) returns (HelloReply) {}\n rpc SayBye (google.protobuf.Empty) returns (HelloReply) {}\n}\n\nmessage HelloRequest {\n string name = 1;\n}\n\nmessage HelloReply {\n string reply = 1;\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"common"}]},{"type":"text","text":"構建過程使用"},{"type":"codeinline","content":[{"type":"text","text":"protobuf-maven-plugin"}]},{"type":"text","text":"自動生成rpc模板代碼。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"provider——grpc-spring-boot-starter"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"provider"}]},{"type":"text","text":"依賴"},{"type":"codeinline","content":[{"type":"text","text":"grpc-spring-boot-starter"}]},{"type":"text","text":"包以最小化編碼,實現grpc服務端邏輯。示例實現了兩套grpc方法,以在後文演示不同流量的返回結果不同。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第一套方法示意如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"@GRpcService\npublic class GreeterImpl extends GreeterImplBase {\n\n @Override\n public void sayHello(HelloRequest request, StreamObserver responseObserver) {\n String message = \"Hello \" + request.getName() + \"!\";\n HelloReply helloReply = HelloReply.newBuilder().setReply(message).build();\n responseObserver.onNext(helloReply);\n responseObserver.onCompleted();\n }\n\n @Override\n public void sayBye(com.google.protobuf.Empty request, StreamObserver responseObserver) {\n String message = \"Bye bye!\";\n HelloReply helloReply = HelloReply.newBuilder().setReply(message).build();\n responseObserver.onNext(helloReply);\n responseObserver.onCompleted();\n }\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第二套方法示意如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"@GRpcService\npublic class GreeterImpl2 extends GreeterImplBase {\n\n @Override\n public void sayHello(HelloRequest request, StreamObserver responseObserver) {\n String message = \"Bonjour \" + request.getName() + \"!\";\n HelloReply helloReply = HelloReply.newBuilder().setReply(message).build();\n responseObserver.onNext(helloReply);\n responseObserver.onCompleted();\n }\n\n @Override\n public void sayBye(com.google.protobuf.Empty request, StreamObserver responseObserver) {\n String message = \"au revoir!\";\n HelloReply helloReply = HelloReply.newBuilder().setReply(message).build();\n responseObserver.onNext(helloReply);\n responseObserver.onCompleted();\n }\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"consumer——RESTful"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"consumer"}]},{"type":"text","text":"的作用有兩個,一個是對外暴露RESTful服務,一個是作爲grpc的客戶端調用grpc服務端provider。示意代碼如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"@RestController\npublic class GreeterController {\n private static String GRPC_PROVIDER_HOST;\n\n static {\n GRPC_PROVIDER_HOST = System.getenv(\"GRPC_PROVIDER_HOST\");\n if (GRPC_PROVIDER_HOST == null || GRPC_PROVIDER_HOST.isEmpty()) {\n GRPC_PROVIDER_HOST = \"provider\";\n }\n LOGGER.info(\"GRPC_PROVIDER_HOST={}\", GRPC_PROVIDER_HOST);\n }\n\n @GetMapping(path = \"/hello/{msg}\")\n public String sayHello(@PathVariable String msg) {\n final ManagedChannel channel = ManagedChannelBuilder.forAddress(GRPC_PROVIDER_HOST, 6565)\n .usePlaintext()\n .build();\n final GreeterGrpc.GreeterFutureStub stub = GreeterGrpc.newFutureStub(channel);\n ListenableFuture future = stub.sayHello(HelloRequest.newBuilder().setName(msg).build());\n try {\n return future.get().getReply();\n } catch (InterruptedException | ExecutionException e) {\n LOGGER.error(\"\", e);\n return \"ERROR\";\n }\n }\n\n @GetMapping(\"bye\")\n public String sayBye() {\n final ManagedChannel channel = ManagedChannelBuilder.forAddress(GRPC_PROVIDER_HOST, 6565)\n .usePlaintext()\n .build();\n final GreeterGrpc.GreeterFutureStub stub = GreeterGrpc.newFutureStub(channel);\n ListenableFuture future = stub.sayBye(Empty.newBuilder().build());\n try {\n return future.get().getReply();\n } catch (InterruptedException | ExecutionException e) {\n LOGGER.error(\"\", e);\n return \"ERROR\";\n }\n }\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏需要注意的是"},{"type":"codeinline","content":[{"type":"text","text":"GRPC_PROVIDER_HOST"}]},{"type":"text","text":"變量,我們在"},{"type":"codeinline","content":[{"type":"text","text":"ManagedChannelBuilder.forAddress(GRPC_PROVIDER_HOST, 6565)"}]},{"type":"text","text":"中使用到這個變量,以獲得provider服務的地址。相信你已經發現,服務開發過程中,我們沒有進行任何服務發現能力的開發,而是從系統環境變量裏獲取這個值。而且,在該值爲空時,我們使用了一個hardcode值"},{"type":"codeinline","content":[{"type":"text","text":"provider"}]},{"type":"text","text":"。沒錯,這個值將是後文配置在isito中的provider服務的約定值。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1.2 curl&grpcurl"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本節將講述示例工程的本地啓動和驗證。首先我們通過如下腳本構建和啓動provider和consumer服務:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# terminal 1\nmvn clean install -DskipTests -U\njava -jar provider/target/provider-1.0.0.jar\n\n# terminal 2\nexport GRPC_PROVIDER_HOST=localhost\njava -jar consumer/target/consumer-1.0.0.jar"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們使用curl以http的方式請求consumer:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# terminal 3\n$ curl localhost:9001/hello/feuyeux\n\nHello feuyeux!\n\n$ curl localhost:9001/bye\n\nBye bye!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後我們使用"},{"type":"link","attrs":{"href":"https://github.com/fullstorydev/grpcurl","title":""},"content":[{"type":"text","text":"grpcurl"}]},{"type":"text","text":"直接測試provider:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"$ grpcurl -plaintext -d @ localhost:6565 org.feuyeux.grpc.Greeter/SayHello <springbootdemo","title":""},"content":[{"type":"text","text":"本示例工程"}]},{"type":"text","text":"。接下來,我將介紹如何將我們的grpc服務實例部署到阿里雲服務網格。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2. 服務網格實踐"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.1 託管集羣"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先使用阿里雲賬號登錄,進入容器服務控制檯(https://cs.console.aliyun.com),創建Kubernetes集羣-標準託管集羣。詳情見幫助文檔:"},{"type":"link","attrs":{"href":"https://help.aliyun.com/document_detail/85903.html","title":""},"content":[{"type":"text","text":"快速創建Kubernetes託管版集羣"}]},{"type":"text","text":"。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.2 服務網格"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進入服務網格控制檯(https://servicemesh.console.aliyun.com/),創建服務網格實例。詳情見幫助文檔:"},{"type":"link","attrs":{"href":"https://help.aliyun.com/document_detail/149552.html","title":""},"content":[{"type":"text","text":"服務網格 ASM > 快速入門 > 使用流程"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務網格實例創建成功後,確保數據平面已經添加容器服務集羣。然後開始數據平面的配置。"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b7/b7377c0a0e3d93ccc4c67a9c1b577aa0.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.3 數據平面"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"kubeconfig"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在執行數據平面的部署前,我們先確認下即將用到的兩個kubeconfig。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進入容器實例界面,獲取kubconfig,並保存到本地"},{"type":"codeinline","content":[{"type":"text","text":"~/shop/bj_config"}]},{"type":"text","text":"。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進入服務網格實例界面,點擊連接配置,獲取kubconfig,並保存到本地"},{"type":"codeinline","content":[{"type":"text","text":"~/shop/bj_asm_config"}]},{"type":"text","text":"。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"請注意,在數據平面部署過程中,我們使用"},{"type":"codeinline","content":[{"type":"text","text":"~/shop/bj_config"}]},{"type":"text","text":"這個kubeconfig;在控制平面的部署中,我們使用"},{"type":"codeinline","content":[{"type":"text","text":"~/shop/bj_asm_config"}]},{"type":"text","text":"這個kubeconfig。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"設置自動注入"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"kubectl \\\n--kubeconfig ~/shop/bj_config \\\nlabel namespace default istio-injection=enabled"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以通過訪問容器服務的命名空間界面https://cs.console.aliyun.com/#/k8s/namespace進行驗證。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"部署deployment和service"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"kubectl \\\n--kubeconfig ~/shop/bj_config \\\napply -f $DEMO_HOME/istio/kube/consumer.yaml\n\nkubectl \\\n--kubeconfig ~/shop/bj_config \\\napply -f $DEMO_HOME/istio/kube/provider1.yaml\n\nkubectl \\\n--kubeconfig ~/shop/bj_config \\\napply -f $DEMO_HOME/istio/kube/provider2.yaml"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以通過訪問容器服務的如下界面進行驗證:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"無狀態應用 https://cs.console.aliyun.com/#/k8s/deployment/list"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器組 https://cs.console.aliyun.com/#/k8s/pod/list"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務 https://cs.console.aliyun.com/#/k8s/service/list"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過如下命令,確認pod的狀態是否符合預期:"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"$ kubectl \\\n--kubeconfig ~/shop/bj_config \\\nget pod\n\nNAME READY STATUS RESTARTS AGE\nconsumer-v1-5c565d57f-vb8qb 2/2 Running 0 7h24m\nprovider-v1-54dbbb65d8-lzfnj 2/2 Running 0 7h24m\nprovider-v2-9fdf7bd6b-58d4v 2/2 Running 0 7h24m"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"入口網關服務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後,我們通過ASM管控臺配置入口網關服務,以對外公開"},{"type":"codeinline","content":[{"type":"text","text":"http"}]},{"type":"text","text":"協議的"},{"type":"codeinline","content":[{"type":"text","text":"9001"}]},{"type":"text","text":"端口和"},{"type":"codeinline","content":[{"type":"text","text":"grpc"}]},{"type":"text","text":"協議的"},{"type":"codeinline","content":[{"type":"text","text":"6565"}]},{"type":"text","text":"端口。"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/94/948f26283ef56598efbd1c4fbff3d59f.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"余文測試驗證環節將使用到這裏配置的入口網關IP "},{"type":"codeinline","content":[{"type":"text","text":"39.102.37.176"}]},{"type":"text","text":"。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.4 控制平面"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"部署Gateway"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"kubectl \\\n--kubeconfig ~/shop/bj_asm_config \\\napply -f $DEMO_HOME/istio/networking/gateway.yaml"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"部署Gateway的VirtualService"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"kubectl \\\n--kubeconfig ~/shop/bj_asm_config \\\napply -f $DEMO_HOME/istio/networking/gateway-virtual-service.yaml"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"部署VirtualService和DestinationRule"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"kubectl \\\n--kubeconfig ~/shop/bj_asm_config \\\napply -f $DEMO_HOME/istio/networking/provider-virtual-service.yaml\n\nkubectl \\\n--kubeconfig ~/shop/bj_asm_config \\\napply -f $DEMO_HOME/istio/networking/provider-destination-rule.yaml\n\nkubectl \\\n--kubeconfig ~/shop/bj_asm_config \\\napply -f $DEMO_HOME/istio/networking/consumer-virtual-service.yaml\n\nkubectl \\\n--kubeconfig ~/shop/bj_asm_config \\\napply -f $DEMO_HOME/istio/networking/consumer-destination-rule.yaml"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.5 流量驗證"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"完成grpc服務在ASM的部署後,我們首先驗證如下鏈路的流量:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/85/85da261e53e4c6409c911fd0d892567c.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"HOST=39.102.37.176\nfor ((i=1;i<=10;i++)) ; \ndo \ncurl ${HOST}:9001/hello/feuyeux\necho\ndone"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後再來驗證我如下鏈路的流量:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/66/6622268bc2ab693394ada12b7416c6cb.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# terminal 1\nexport GRPC_PROVIDER_HOST=39.102.37.176\njava -jar consumer/target/consumer-1.0.0.jar\n\n# terminal 2\nfor ((i=1;i<=10;i++)) ; \ndo \ncurl localhost:9001/bye\necho\ndone"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"到此,基於ASM的GRPC服務部署實踐分享完畢。歡迎技術交流。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章