如果您的服務采用分布式架構,您可以使用gRPC協議提升客戶端與服務器端的通訊效率。將使用gRPC協議的服務部署在Nginx Ingress Controller的后端時,您需要對Ingress資源進行特殊的配置。
背景信息
gRPC(Google Remote Procedure Call)是一個基于HTTP/2協議標準和ProtoBuf(Protocol Buffers)序列化協議設計的遠程過程調用(RPC)框架。它由Google開源,支持在多語言開發的平臺上使用。其因其高效、靈活和跨語言的特性,gRPC適用于分布式系統和微服務架構場景,例如微服務間調用、物聯網設備間通訊、使用復雜數據結構的遠程API服務等。
定義如下gRPC服務,客戶端可調用helloworld.Greeter服務的SayHello接口。
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
更多gRPC服務示例,請參見grpc-go。
前提條件
已安裝Nginx Ingress Controller組件,且組件版本為0.22.0及以上。具體操作,請參見管理Nginx Ingress Controller組件。
已通過kubectl工具連接集群。具體操作,請參見獲取集群KubeConfig并通過kubectl工具連接集群。
已安裝gRPCurl工具。具體操作,請參見gRPCurl。
已獲取到可信的數字證書。您可以從以下幾個途徑獲取數字證書:
從阿里云數字證書中心購買證書。具體操作,請參見購買SSL證書。
從其他CA購買的證書。
(可選)參照本文中的(可選)生成自簽名證書生成自簽名證書。
步驟一:將SSL證書保存到集群Secret資源中
使用Nginx Ingress Controller時,gRPC服務只運行在HTTPS端口(默認443)上,因此需要使用SSL證書。證書需要以Secret資源的方式保存在集群中。
如果您暫未擁有證書,您可參照下方的步驟生成自簽名證書,示例中使用grpc.example.com
作為證書的域名。
由于缺乏可靠的CA認證,自簽名證書在瀏覽器和客戶端中默認不受信任,通常會導致客戶訪問時收到安全警告。本文中生成的自簽名證書僅作為示例,請勿在生產環境中使用。
創建并拷貝以下內容至/tmp/openssl.cnf文件中。
[ req ] #default_bits = 2048 #default_md = sha256 #default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes req_extensions = v3_req [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (eg, fully qualified host name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 [v3_req] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = grpc.example.com
執行以下命令簽署證書請求。
openssl req -new -nodes -keyout grpc.key -out grpc.csr -config /tmp/openssl.cnf -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=AlibabaCloud/OU=ContainerService/CN=grpc.example.com"
執行以下命令簽署證書。
openssl x509 -req -days 3650 -in grpc.csr -signkey grpc.key -out grpc.crt -extensions v3_req -extfile /tmp/openssl.cnf
命令執行成功后,可得到證書grpc.crt與私鑰文件grpc.key。
執行以下命令,將證書通過grpc-secret
添加到集群中。
kubectl create secret tls grpc-secret --key grpc.key --cert grpc.crt # grpc.key替換為您的證書文件,grpc.crt替換為您的私鑰文件
步驟二:創建gRPC服務
創建并將以下內容拷貝到grpc.yaml文件中。
apiVersion: apps/v1 kind: Deployment metadata: name: grpc-service spec: replicas: 1 selector: matchLabels: run: grpc-service template: metadata: labels: run: grpc-service spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/grpc-server:latest imagePullPolicy: Always name: grpc-service ports: - containerPort: 50051 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: grpc-service spec: ports: - port: 50051 protocol: TCP targetPort: 50051 selector: run: grpc-service sessionAffinity: None type: NodePort
執行以下命令創建gRPC服務。
kubectl apply -f grpc.yaml
預期輸出:
deployment.apps/grpc-service created service/grpc-service created
步驟三:創建Ingress
創建并拷貝以下內容到grpc-ingress.yaml文件中。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grpc-ingress annotations: # 必須指明后端服務為gRPC服務 nginx.ingress.kubernetes.io/backend-protocol: "GRPC" spec: # 指定通過Secret保存的SSL證書 tls: - hosts: - grpc.example.com secretName: grpc-secret rules: - host: grpc.example.com # gRPC服務域名,替換為您的域名 http: paths: - path: / pathType: Prefix backend: service: # gRPC服務 name: grpc-service port: number: 50051
重要由于Nginx grpc_pass的限制,目前對于gRPC服務,暫不支持service-weight的配置。
執行以下命令創建Ingress。
kubectl apply -f grpc-ingress.yaml
預期輸出:
ingress.networking.k8s.io/grpc-ingress created
步驟四:效果驗證
執行以下命令,查看Ingress信息。
kubectl get ingress
預期輸出:
NAME CLASS HOSTS ADDRESS PORTS AGE grpc-ingress nginx grpc.example.com 139.196.***** 80, 443 3m51s
記錄
ADDRESS
對應的IP地址。使用grpcurl連接服務。
grpcurl -insecure -authority grpc.example.com <IP_ADDRESS>:443 list # <IP_ADDRESS>替換為上一步中記錄的IP地址
輸出如下,表明流量被Ingress成功轉發到后端gRPC服務:
grpc.reflection.v1alpha.ServerReflection helloworld.Greeter
相關文檔
關于如何通過Nginx Ingress Controller實現gRPC服務的灰度發布,請參見通過Nginx Ingress實現灰度發布和藍綠發布。
Nginx Ingress Controller支持鏈路追蹤。具體操作,請參見實現Nginx Ingress Controller組件的鏈路追蹤。