本文主要是介绍【翻译】Kubernetes Ingress gRPC实例与Dune报价服务,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
特邀文章,最初发表在Kong的博客上,作者是Kong的首席开发者倡导者Viktor Gamov
API有各种不同的形状和形式。在本教程中,我将向你展示一个Kubernetes Ingress gRPC实例。我将解释如何将gRPC服务部署到Kubernetes,并使用Kong的Kubernetes Ingress控制器提供对该服务的外部访问。
为了让你对即将上映的根据Frank Herbert的书改编的真人电影《沙丘》有一点期待,我创建了一个提供沙丘语录的Kubernetes服务。这可以说是有史以来最杰出的科幻书之一......你怎么看?让我知道@GAMUSSA在Twitter上。
在我们深入研究代码之前,让我们回顾一下一些基础知识。
gRPC如何与Kong一起工作?
gRPC是一个程序性框架,最初由谷歌在2015年开发。gRPC以HTTP2协议为传输基础,以Protobuf为接口定义语言,近年来被越来越多的人采用。gRPC有一些传统REST API难以企及的能力,比如双向流和高效的二进制编码。
Kong支持TCP流,可以代理任何建立在TCP或TLS之上的协议。我们认为,对gRPC的原生支持会让越来越多的用户群利用Kong来统一管理他们的REST和gRPC服务。
现在我们已经涵盖了基础知识,让我们来看看我的Dune报价服务的Protobuf定义。
Protobuf的定义
我的Protobuf定义包含一个使用两种方法的报价服务。一种方法是在任何gRPC请求上提供一个简单的报价。该方法不需要任何输入参数,所以我们将使用Protobuf的空类型。作为一个返回,它将有一个包含消息字段的报价信息。
而我这里的另一个方法是一个GetQuoteStream方法,它也不需要提供任何参数。在这种情况下,我也使用了一个空类型。但在这种情况下,我将返回这些结果的一个流。
syntax = "proto3"; package io.kong.developer.quoteservice; import "google/protobuf/empty.proto"; option java_multiple_files = true; option java_package = "io.kong.developer.quoteservice"; service QuoteService { rpc GetQuote(google.protobuf.Empty) returns (QuoteMessage) ; rpc GetQuoteStream(google.protobuf.Empty) returns (stream QuoteMessage) ; } message QuoteMessage{ string message = 1; }
我是用Java来生成服务的服务器端实现的。然而,你可以利用这个proto文件,用你使用的任何语言实现这个服务。
Protobuf带有不同语言的各种工具,包括一些支持你选择的语言的代码生成器。
让我们来看看我们的Dune报价服务的部署。
Kubernetes部署回顾
我在部署中使用相同的镜像,但我的活动服务将使用版本3。
--- apiVersion: apps/v1 kind:Deployment metadata: name: dune-quote-service spec: replicas:1 selector: matchLabels: app: dune-quote-service template: metadata: labels: app: dune-quote-service spec: containers: - image: gamussa/reactive-quote-service:0.0.3 imagePullPolicy:Always name: dune-quote-service ports: - containerPort: 9001 env: - name: GRPC_SERVER_PORT value:"9001" - name: GRPC_SERVER_SECURITY_ENABLED value:"true" - name: GRPC_SERVER_SECURITY_CERTIFICATECHAIN value:"file:/mnt/grpc-cert-chain/server.crt" - name: GRPC_SERVER_SECURITY_PRIVATEKEY value:"file:/mnt/grpc-pk/server.key" volumeMounts: - mountPath:/mnt/grpc-cert-chain name: grpc-cert-chain - mountPath:/mnt/grpc-pk name: grpc-pk volumes: - name: grpc-ert-chain secret: secretName: grpc-ert-chain - name: grpc-pk secret: secretName: grpc-pk
我的应用程序将在9001端口上运行GRPC_SERVER。这个端口将提供给服务,以便在我的Kubernetes集群中公开这个端口。
我的服务已经启用了安全功能。而且我确实在gRPC服务器的私钥中提供了一些证书。
name: dune-quote-service ports: - containerPort: 9001 env: - name: GRPC_SERVER_PORT value:"9001" - name: GRPC_SERVER_SECURITY_ENABLED value:"true" - name: GRPC_SERVER_SECURITY_CERTIFICATECHAIN value:"file:/mnt/grpc-cert-chain/server.crt" - name: GRPC_SERVER_SECURITY_PRIVATEKEY value:"file:/mnt/grpc-pk/server.key"。
我在这个例子中使用了一个自签的TLS证书。你需要使用一个由你在生产用例中信任的认证机构签署的证书。
我创建了这些秘密。之后,我把这些秘密作为文件挂载在我的部署中。
volumeMounts: - mountPath:/mnt/grpc-cert-chain name: grpc-cert-chain - mountPath:/mnt/grpc-pk 名称:grpc-pk
服务回顾
我的服务将使用9001端口作为我的目标端口。请注意第6行,在那里我有限制:konghq.com/protocol。它将响应gRPC这个协议,因为我的服务已经启用了安全功能,我需要通知我的Kong Gateway我的服务能理解gRPCS协议。
--- apiVersion: v1 kind: Service metadata: annotations: konghq.com/protocol: grpcs name: dune-quote-service labels: app: dune-quote-service spec: ports: - name: grpc port:目标端口:9001 选择器:应用:Dune-quote-service
最后但并非最不重要的是,我需要创建一个接入点。
入口设置
你会看到一些熟悉的东西,比如与我的开源Kong Ingress Controller相对应的ingress.class。现在,我在这里也有一个注释:konghq.com/protocols
--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: dune-quote-service annotations: konghq.com/protocols: grpc,grpcs kubernetes.io/ingress.class: kong kubernetes.io/tls-acme:"true" cert-manager.io/cluster-issuer: letsencrypt-prod spec: tls: - secretName: kong.gamov.dev hosts: - kong.gamov.dev rules: - host: kong.gamov.dev http: paths: - pathType:/ pathType:具体实施的后端: 服务: 名称: dune-quote-service 端口: 数量: 9001
这是一个入口配置,允许Kong Gateway了解我们期待什么样的入站客户。在本例中,我们为gRPCS创建这个入口,因为我们期待gRPC客户端连接到该服务。我们正在使用gRPC或gRPCS协议。
在部署Kubernetes服务之前,我们需要设置Kong Ingress Controller和Kubernetes cert-manager。
Ingress控制器和Cert管理器的设置
我已经安装了Kong Ingress Controller。如果你还没有,请跟随我之前的入门教程。
我将我的集群配置为使用cert-manager。我将使用由LetsEncrypt颁发的证书。在Kong的文档中,有一个cert-manager的入门指南,允许你配置Kong的Ingress控制器和你的API网关,以使用自动颁发的TLS证书。
接下来,我们需要遵循Kubernetes cert-manager文档。
然后,我们就可以向认证机构申请TLS证书了。而后,应用程序将使用443端口的TLS与外部客户通信。
这就是为什么我有这个注释,kubernetes.io/tls-acme,为我的集群使用一个自动的证书管理扩展启用。我使用LetsEncrypt服务器的生产版本来接收证书。
kubernetes.io/tls-acme。"true" cert-manager.io/cluster-issuer: letsencrypt-prod
下一件事是配置我的ingress。我需要指定我的入口使用TLS,并为这个域名签发一个证书。这个域名对应于谷歌云平台提供的外部 IP 地址。
spec: tls: - secretName: kong.gamov.dev hosts: - kong.gamov.dev
这是对特定路径的相同配置规则。默认情况下,这将对应于我的Dune Quote服务。
- path:/ pathType:ImplementationSpecific backend: service: name: dune-quote-service port: number: 9001
入站流量将监听gRPC或gRPCS协议。我的Kong Gateway和Dune Quote服务也将使用gRPCS协议,因为我使用gRPCS部署我的服务。
konghq.com/protocols: grpc,grpcs kubernetes.io/ingress.class: kong kubernetes.io/tls-acme:"true" cert-manager.io/cluster-issuer: letsencrypt-prod
下一件事是配置我的ingress。我需要指定我的入口使用TLS,并为这个域名签发一个证书。这个域名对应于谷歌云平台提供的外部 IP 地址。
spec: tls: - secretName: kong.gamov.dev hosts: - kong.gamov.dev
这是对特定路径的相同配置规则。默认情况下,这将对应于我的Dune Quote服务。
- path:/ pathType:ImplementationSpecific backend: service: name: dune-quote-service port: number: 9001
入站流量将监听gRPC或gRPCS协议。我的Kong Gateway和Dune Quote服务也将使用gRPCS协议,因为我使用gRPCS部署我的服务。
konghq.com/protocols: grpc,grpcs kubernetes.io/ingress.class: kong kubernetes.io/tls-acme:"true" cert-manager.io/cluster-issuer: letsencrypt-prod
部署Kubernetes服务
在我们部署之前,我们需要提供两个秘密。

我们可以用下面的脚本来提供这些秘密。它生成了一个自签名的证书,之后,应用这个证书和密钥作为我的秘密。
#! /usr/bin/env bash openssl req -x509 -nodes -subj "/CN=gamov.dev" -newkey rsa:4096 -sha256 -keyout server.key -out server.crt -days 3650 kubectl create secret generic grpc-cert-chain --from-file=server.crt=server.crt kubectl create secret generic grpc-pk --from-file=server.key=server.key
接下来,让我们重新启动部署并启动我们的服务。
测试服务
一旦我们的服务启动了,我们就可以使用Insomnia来测试服务。
在Insomnia中,让我们上传我们的proto文件。一旦上传,我们将看到两个方法:GetQuote和GetQuoteStream。

当我们点击GetQuote时,我们从Dune获得一些报价。它起作用了!

接下来,让我们通过切换到GetQuoteStream看看流媒体是否工作。当我点击开始时,我的响应包含了来自gRPCS服务器的10个响应。很好!

而我的实现有一个拦截器,它将记录所有对我的服务的调用。

这就是一个Wrap!
在这篇文章中,我向你展示了如何将gRPC服务部署到Kubernetes,并使用Kong Ingress Controller将其暴露在集群之外。
一旦你完成了这个Kubernetes Ingress gRPC的例子,你可能会发现这些其他的Kubernetes教程很有帮助。
- 在Kong Konnect上配置一个Kubernetes应用程序
- 用Kubernetes Ingress Controller管理Docker应用程序
- 在Kubernetes中实施流量策略
这篇关于【翻译】Kubernetes Ingress gRPC实例与Dune报价服务的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!