- Web開発においてREST APIを設計するのは大変な作業です。
- REST APIの代わりにgRPCを用いる事で、開発者の負担が減るかもしれません。
- このデモでは、Web開発でgRPCの導入を検討している方に対し、シンプルで理解しやすく実際に動かせるプログラムを提供します。
- webブラウザからgrpc-webを使ってgRPCサーバーにリクエストを投げるには、gRPCサーバーとwebブラウザの間にenvoy等のgRPC proxyが必要です。
- envoyは、kubernetesクラスタにインストールしたistioを適切に設定する事で、PODに対して自動的に挿入する事が出来ます。
- このデモでは、そのistioによって挿入されたenvoyに対してgRPC proxyとして動作するように設定します。
- gRPCサーバーを作る
- webブラウザ上で実行するgRPCクライアントを作る
- gRPCサーバーをkubernetes上にデプロイする
- 実行してみる
- clean up
既にgRPCサーバーのimageをdockerhubにpushしてあります。 今回はこのimageを使います。
このgRPCサーバーの仕様は以下の通りです。
- サーバーはmessageという文字列を受け取る
- サーバーは受け取ったmessageを2つ繋げた文字列を返す
- 例: サーバーが"hello"を受け取ったら"hellohello"を返す
- Listening PORT 9000
gRPCサーバーをコンパイルする場合は以下のコマンドを実行します。
protoc -I proto proto/echo.proto --go_out=plugins=grpc:proto
go build -o echo-server server/main.go
コンテナimageは以下のようにして作ります。
docker build -f ./docker/server.Dockerfile -t mmitou/echo-server:v1 .
サーバーが期待した通り実行出来る事を確認してみます。
$ docker run --rm -d -p 9000:9000 mmitou/echo-server:v1
$ grpcurl -proto proto/echo.proto -plaintext -d '{"message":"hello"}' localhost:9000 proto.EchoService.Echo
{
"message": "hellohello"
}
こちらも既にimageをdockerhubにpushしてあります。 今回はこのimageを使います。
クライアントは以下の手順でビルドします。
protoc -I proto/ proto/echo.proto \
--js_out=import_style=commonjs:proto \
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:proto
docker build -f docker/web-ui.Dockerfile -t mmitou/web-ui:v1 .
GKEでkubernetesクラスターを作ってistioをインストールします。
gcloud beta container clusters create sample-cluster --preemptible --addons=Istio
gcloud container clusters get-credentials sample-cluster
以下のコマンドでkubernetesクラスターにアプリケーションをデプロイします。
kubectl label namespace default istio-injection=enabled
kubectl apply -f istio/server.yaml
kubectl apply -f istio/web-ui.yaml
kubectl apply -f istio/istio.yaml
Serviceのname port に"grpc-web"と書くのが重要です。
istioはname portの値を見て、プロトコルを判断します。
apiVersion: v1
kind: Service
metadata:
name: server
labels:
app: server
spec:
ports:
- name: grpc-web # istio refers this value as protocol
port: 9000
selector:
app: server
以下のコマンドでistio-gatewayのIPアドレスを確認し、webブラウザでそのIPアドレスを開きます。
$ kubectl get service istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.7.245.96 34.84.25.68 15020:32183/TCP,80:32561/TCP,443:30846/TCP,31400:31742/TCP,15029:32088/TCP,15030:31197/TCP,15031:31861/TCP,15032:31313/TCP,15443:30914/TCP 8m13s
以下のようにwebブラウザのコンソールに"hellohello"と表示されていれば成功です。
以下のコマンドを実行して、kubernetesクラスターを削除します。
gcloud container clusters delete sample-cluster