gRPC是Google开源的一个高性能RPC通信框架,通过Protocol Buffers作为其IDL,可以在不同语言开发的平台上使用,同时基于HTTP/2协议实现,继而提供了连接多路复用、头部压缩、流控等特性,极大地提高了客户端与服务端的通信效率。
在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的方法,就像它是本地对象一样,使您更容易创建分布式应用程序和服务。与许多 RPC 系统一样,gRPC 基于定义服务的思想,指定可以远程调用的方法及其参数和返回类型。在服务端,服务端实现这个接口并运行一个 gRPC 服务器来处理客户端调用。在客户端,客户端有一个存根(在某些语言中仅称为客户端),它提供与服务器相同的方法。
下面我们在演示下在tke上部署一个grpc的demo,然后通过nginx-ingress来实现对grpc服务的转发。注意下面的所有资源都部署在weixnie这个命名空间下,如果需要部署到自己的命名空间,需要修改下yaml。
1. 部署grpc-server
可以参考yaml部署下grpc-server
代码语言:javascript复制apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: grpc-service
qcloud-app: grpc-service
name: grpc-service
namespace: weixnie
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: grpc-service
qcloud-app: grpc-service
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
k8s-app: grpc-service
qcloud-app: grpc-service
spec:
containers:
- image: ccr.ccs.tencentyun.com/niewx-k8s/grpc:latest
imagePullPolicy: Always
name: grpc-service
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 250m
memory: 256Mi
securityContext:
privileged: false
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: qcloudregistrykey
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
2. 配置ingress转发grpc服务
Ingress Nginx暴露gRPC服务的时候,暂时只支持TLS(HTTPS)的方式,而不能通过普通HTTP方式,所以我们要配置TLS secret。
这里获取证书的方式有2种,一种可以用命令生成
代码语言:javascript复制openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=grpc.example.com/O=grpc.example.com"
还有一种就是去腾讯云上申请一年有效的证书
证书生成好之后,我们用secret配置下证书
代码语言:javascript复制kubectl create secret tls grpc-secret --cert tls.crt --key tls.key -n weixnie
然后创建下ingress
代码语言:javascript复制apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx-intranet
nginx.ingress.kubernetes.io/backend-protocol: GRPC
name: grpc-ingress
namespace: weixnie
spec:
rules:
- host: grpc.example.com
http:
paths:
- backend:
serviceName: grpc-service
servicePort: 50051
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- grpc.example.com
secretName: grpc-secret
注意ingress.class配置成自己的class名称,nginx-ingress实现grpc转发,必须要配置上这个注解nginx.ingress.kubernetes.io/backend-protocol:GRPC
3. 测试grpc服务访问
创建好ingress后,我们来用grpcurl来测试访问下,如果你本地没有grpcurl这个工具,可以通过下面yaml起一个grpcurl工具pod,然后在容器里用grpcurl 去测试
代码语言:javascript复制apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: grpcurl
qcloud-app: grpcurl
name: grpcurl
namespace: weixnie
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: grpcurl
qcloud-app: grpcurl
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
k8s-app: grpcurl
qcloud-app: grpcurl
spec:
containers:
- args:
- 70d
command:
- sleep
image: ccr.ccs.tencentyun.com/niewx-k8s/grpcurl:latest
imagePullPolicy: Always
name: grpcurl
resources: {}
securityContext:
privileged: false
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
hostAliases:
- hostnames:
- grpc.example.com
ip: 172.16.0.14
imagePullSecrets:
- name: qcloudregistrykey
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
因为grpc.example.com这个域名没有配置解析,所以需要在容器里面配置下host,将域名解析到nginx-ingress控制器入口serivce的ip上。
pod起来后,我们直接到容器测试下
代码语言:javascript复制# 查看gRPC服务端提供的所有服务:
# grpcurl -insecure grpc.example.com:443 list
# 查看helloworld.Greeter服务的接口方法
# grpcurl -insecure grpc.example.com:443 list helloworld.Greeter
# 描述SayHello方法的具体协议参数
# grpcurl -insecure grpc.example.com:443 describe helloworld.Greeter.SayHello
# 调用SayHello方法并传递name参数
# grpcurl -insecure -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter.SayHello
# grpcurl -insecure -d '{"name": "world"}' grpc.example.com:443 helloworld.Greeter.SayHello
这里测试调用成功