對於部署在ACK叢集中的gRPC應用,為實現外部客戶端的訪問,可配置Nginx Ingress並添加 nginx.ingress.kubernetes.io/backend-protocol: "GRPC" 註解來路由gRPC流量。
核心樣本
以下為Nginx Ingress安全暴露gRPC服務的核心配置。
gRPC 協議代理:通過
backend-protocol: "GRPC"註解,明確指示 Ingress 將流量作為 gRPC(基於HTTP/2)進行代理,而不是預設的HTTP。TLS 加密:為樣本網域名稱
grpc.example.com啟用了 TLS,並使用Secret中儲存的認證進行加密。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grpc-ingress
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "GRPC" # 關鍵:指明後端服務為gRPC協議
spec:
tls:
- hosts:
- grpc.example.com # 替換為gRPC服務網域名稱
secretName: nginx-ingress-tls # 配置儲存認證的Secret
rules:
- host: grpc.example.com # 替換為gRPC服務網域名稱
#...部署gRPC樣本應用
控制台
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在無狀態頁面,單擊使用YAML建立資源,然後將以下內容複寫到模板地區,單擊建立。
在彈窗中找到目標無狀態應用,單擊查看,確認Pod狀態為
Running。
kubectl
將以下YAML內容儲存為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應用並建立服務(Service)。
kubectl apply -f grpc.yaml確認目標應用Pod狀態為
Running。kubectl get pod | grep grpc-service
該服務基於以下 .proto 檔案定義。服務名為 Greeter,提供了一個 SayHello 方法。
將SSL憑證存放區為Secret
要在 Nginx Ingress 中啟用 gRPC 所依賴的 HTTP/2 協議,必須先開啟 TLS 加密。可以將 SSL認證與私密金鑰存入Secret中進行安全管理,並通過引用該Secret來完成TLS加密配置。
購買或產生SSL認證。
(可選)若已從阿里雲購買認證,需下載SSL認證檔案到本地。
建立Secret,儲存認證及私密金鑰。
控制台
登入Container Service管理主控台,在左側導覽列選擇叢集列表。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在保密字典頁面,選擇
default命名空間後,單擊左側建立,在彈出面板中配置新的保密字典。配置完成後,單擊確定。名稱:
nginx-ingress-tls類型:TLS認證
認證:認證檔案(
.crt或.pem)中的完整內容密鑰:私密金鑰檔案(
.key)中的完整內容
kubectl
將以下
<PUBLIC_CERT>、<PRIVATE_KEY>替換成實際的認證檔案(.crt或.pem)路徑和私密金鑰檔案(.key)路徑,然後執行命令將認證和私密金鑰儲存為Secret。# --key 參數指定私密金鑰檔案,--cert 參數指定認證檔案 kubectl create secret tls nginx-ingress-tls --cert <PUBLIC_CERT> --key <PRIVATE_KEY>
配置Ingress暴露服務
登入Container Service管理主控台,單擊目的地組群名稱,在叢集詳情頁左側導覽列選擇组件管理。
在搜尋方塊輸入Nginx Ingress Controller並定位組件,然後在目標組件卡片上單擊安裝。
v1.2之前版本的組件已不再維護,請升級Nginx Ingress Controller組件至最新版。
配置Ingress,通過註解(
annotations)指明後端協議為gRPC,並引用上一步建立的Secret。控制台
在左側導覽列,選擇。選擇
default命名空間,單擊建立 Ingress。添加以下Ingress配置,單擊確定。
網關類型:選擇
Nginx Ingress。名稱:
grpc-ingress。網域名稱:
grpc.example.com。路徑映射:路徑:
/,匹配規則:首碼匹配(Prefix),服務名稱:grpc-service,連接埠:50051。TLS配置:開啟。網域名稱:
grpc.example.com,保密字典:nginx-ingress-tls。註解:名稱:
nginx.ingress.kubernetes.io/backend-protocol,值GRPC。
在路由列表頁,查看建立的Ingress,擷取訪問端點地址。
Nginx Ingress生效過程耗時約10秒,可稍後單擊重新整理按鈕擷取端點資訊。若長時間未更新端點資訊,可單擊路由名稱,進入事件頁簽,進行異常問題排查。
kubectl
將以下YAML內容儲存為grpc-ingress.yaml檔案,然後執行
kubectl apply -f grpc-ingress.yaml命令。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grpc-ingress annotations: # 關鍵:指明後端服務為gRPC協議 nginx.ingress.kubernetes.io/backend-protocol: "GRPC" spec: ingressClassName: nginx # 配置TLS,引用儲存認證的Secret tls: - hosts: - grpc.example.com # 替換為gRPC服務網域名稱 secretName: nginx-ingress-tls # 上一步建立Secret指定的名稱 rules: - host: grpc.example.com # 替換為gRPC服務網域名稱 http: paths: - path: / pathType: Prefix backend: service: name: grpc-service port: number: 50051擷取訪問端點地址。Ingress IP分配會有延遲,若無輸出結果,可等待10秒後重試。
ADDRESS=$(kubectl get ingress grpc-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo $ADDRESS
訪問gRPC服務
為便於測試,以下提供本地區名映射方法。
macOS / Linux:
sudo vi /etc/hosts。Windows: 以管理員身份開啟記事本,然後開啟
C:\Windows\System32\drivers\etc\hosts。
將以下地址替換為實際訪問端點地址,在檔案末尾添加以下網域名稱映射記錄並儲存。
47.102.XX.XX grpc.example.com安裝grpcurl工具。調用gRPC服務介面。
grpcurl -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter/SayHello{ "message": "Hello gRPC" }
使用限制
由於gRPC基於長串連的特性,Nginx Ingress暫不支援為其佈建服務權重(service-weight)路由。
常見問題
如何產生自我簽署憑證?
執行以下命令可產生一個網域名稱為grpc.example.com、有效期間為365天的自我簽署憑證(grpc.crt)和私密金鑰(grpc.key)。
openssl req -x509 -newkey rsa:2048 -keyout grpc.key -out grpc.crt -days 365 -nodes \
-subj "/CN=grpc.example.com" \
-addext "subjectAltName=DNS:grpc.example.com"自我簽署憑證缺乏權威 CA 認證,瀏覽器及各類用戶端預設不予信任,使用者訪問時將觸發安全警告,請勿在生產環境中使用。
SSL認證和TLS認證的區別?
SSL (Secure Sockets Layer) 為早期的加密協議,現已被更安全的TLS (Transport Layer Security) 協議取代。
在行業術語中,“SSL認證”已成為一個習慣性描述,其更準確的名稱應為“TLS認證”。