全部產品
Search
文件中心

:在Nginx Ingress Controller後端部署gRPC服務

更新時間:Aug 10, 2024

如果您的服務採用分布式架構,您可以使用gRPC協議提升用戶端與伺服器端的通訊效率。將使用gRPC協議的服務部署在Nginx Ingress Controller的後端時,您需要對Ingress資源進行特殊的配置。

背景資訊

gRPC(Google Remote Procedure Call)是一個基於HTTP/2協議標準和ProtoBuf(Protocol Buffers)序列化協議設計的遠端程序呼叫(RPC)架構。它由Google開源,支援在多語言開發的平台上使用。其因其高效、靈活和跨語言的特性,gRPC適用於分布式系統和微服務架構情境,例如微服務間調用、物聯網裝置間通訊、使用複雜資料結構的遠程API服務等。

gRPC服務樣本

定義如下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

前提條件

步驟一:將SSL認證儲存到叢集Secret資源中

使用Nginx Ingress Controller時,gRPC服務只運行在HTTPS連接埠(預設443)上,因此需要使用SSL認證。認證需要以Secret資源的方式儲存在叢集中。

(可選)產生自我簽署憑證

如果您暫未擁有認證,您可參照下方的步驟產生自我簽署憑證,樣本中使用grpc.example.com作為認證的網域名稱。

重要

由於缺乏可靠的CA認證,自我簽署憑證在瀏覽器和用戶端中預設不受信任,通常會導致客戶訪問時收到安全警告。本文中產生的自我簽署憑證僅作為樣本,請勿在生產環境中使用。

  1. 建立並拷貝以下內容至/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
  2. 執行以下命令簽署認證請求。

    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"
  3. 執行以下命令簽署認證。

    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服務

  1. 建立並將以下內容拷貝到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
  2. 執行以下命令建立gRPC服務。

    kubectl apply -f grpc.yaml

    預期輸出:

    deployment.apps/grpc-service created
    service/grpc-service created

步驟三:建立Ingress

  1. 建立並拷貝以下內容到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的配置。

  2. 執行以下命令建立Ingress。

    kubectl apply -f grpc-ingress.yaml

    預期輸出:

    ingress.networking.k8s.io/grpc-ingress created

步驟四:效果驗證

  1. 執行以下命令,查看Ingress資訊。

    kubectl get ingress

    預期輸出:

    NAME           CLASS   HOSTS              ADDRESS         PORTS     AGE
    grpc-ingress   nginx   grpc.example.com   139.196.*****   80, 443   3m51s

    記錄ADDRESS對應的IP地址。

  2. 使用grpcurl串連服務。

    grpcurl -insecure -authority grpc.example.com <IP_ADDRESS>:443 list # <IP_ADDRESS>替換為上一步中記錄的IP地址

    輸出如下,表明流量被Ingress成功轉寄到後端gRPC服務:

    grpc.reflection.v1alpha.ServerReflection
    helloworld.Greeter

相關文檔