Ingress企業實戰:實現GRPC與WebSocket服務訪問
什么是gRPC?
gRPC(gRPC Remote Procedure Call)是一種開源的遠程過程調用(RPC)框架,由Google開發并于2015年發布。它使用HTTP/2協議進行通信,旨在簡化跨網絡的服務通信和跨語言的服務調用。以下是 gRPC 的一些關鍵特點和概念:
- IDL(Interface Definition Language): gRPC 使用IDL來定義服務接口和消息格式。它使用Protocol Buffers(通常簡稱為ProtoBuf)作為默認的IDL工具。通過IDL,您可以明確定義服務的方法和參數,然后使用gRPC工具生成相應的客戶端和服務器代碼。
- 多語言支持: gRPC支持多種編程語言,包括但不限于C++, Java, Python, Go, Node.js, Ruby, C#,等。這意味著您可以使用不同的編程語言開發服務端和客戶端,它們仍然可以相互通信。
- HTTP/2: gRPC使用HTTP/2作為底層傳輸協議,這帶來了性能上的一些好處,如多路復用、頭部壓縮、流控制等。這有助于提高通信效率,特別是在高延遲或低帶寬網絡上。
- 雙向流: gRPC允許客戶端和服務器之間建立雙向流,這意味著它支持雙向通信。這對于流式數據傳輸和實時應用程序非常有用。
- 中間件支持: gRPC提供了一種插件式的中間件機制,使您可以在請求和響應處理過程中添加攔截器和處理器,以實現諸如身份驗證、授權、日志記錄等功能。
- 支持多種序列化格式: 盡管gRPC默認使用Protocol Buffers作為序列化格式,但它也支持其他序列化格式,如JSON。
- 服務發現: gRPC還提供了服務發現功能,使服務能夠注冊和發現其他服務的位置和狀態。這對于微服務架構非常有用。
申請SSL證書
生成CA證書:
# 生成CA根證書私鑰:為保證安全,生成一個4096位的私鑰,并使用aes方式加密
$ openssl genrsa -aes256 -out kubesre-ca.key 4096
Enter PEM pass phrase: # 密碼:12345678
Verifying - Enter PEM pass phrase:
# 通過CA根私鑰簽發CA根證書
$ openssl req -new -x509 -days 3650 -sha256 -extensions v3_ca -key kubesre-ca.key -out kubesre-ca.cer -subj "/C=CN/ST=shanghai/L=shanghai/O=kubesre/OU=kubesre/CN=*.kubesre.com"
Enter pass phrase for kubesre-ca.key: # 密碼:12345678
生成服務端證書:
# 生成服務端證書私鑰
$ openssl genrsa -out kubesre-server.key 2048
# 生成簽發請求csr
$openssl req -new -key kubesre-server.key -out kubesre-server.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=kubesre/OU=kubesre/CN=demo.kubesre.com"
# 用CA證書簽發服務端證書
$ openssl x509 -req -days 3650 -sha256 -CA kubesre-ca.cer -CAkey kubesre-ca.key -in kubesre-server.csr -out kubesre-server.cer
Certificate request self-signature ok
subject=C = CN, ST = shanghai, L = shanghai, O = kubesre, OU = kubesre, CN = demo.kubesre.com
Enter pass phrase for kubesre-ca.key: # 密碼:12345678
$ ll
total 40
-rw-r--r--@ 1 chuanzhang staff 2.0K 8 13 15:24 kubesre-ca.cer
-rw-------@ 1 chuanzhang staff 3.4K 8 13 15:22 kubesre-ca.key
-rw-r--r--@ 1 chuanzhang staff 1.6K 8 13 15:31 kubesre-server.cer
-rw-r--r--@ 1 chuanzhang staff 1.0K 8 13 15:28 kubesre-server.csr
-rw-------@ 1 chuanzhang staff 1.7K 8 13 15:27 kubesre-server.key
創建證書Secret(證書基于Kubernetes Secret進行存儲):
$ kubectl create secret tls kubesre-tls --key kubesre-server.key --cert kubesre-server.cer
secret/kubesre-tls created
$ kubectl get secret
NAME TYPE DATA AGE
kubesre-tls kubernetes.io/tls 2 18s
gRPC示例應用部署
部署示例版本:
$ cat demo.yml
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-shanghai.aliyuncs.com/kubesre01/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
# 執行創建操作
$ kubectl apply -f demo.yml
deployment.apps/grpc-service unchanged
service/grpc-service created
# 查看創建狀態
kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/grpc-service-56f784fcb5-n72hd 1/1 Running 0 81s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/grpc-service ClusterIP 10.96.239.197 <none> 50051/TCP 73s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
# 出現以上情況說明一切就緒
創建Ingress gRPC路由規則
$ cat demo-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grpc-ingress
annotations:
# 通過注解指定GRPC協議
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
spec:
ingressClassName: nginx
# 指定證書
tls:
- hosts:
- demo.kubesre.com
secretName: kubesre-tls
rules:
# 制定域名
- host: demo.kubesre.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grpc-service
port:
number: 50051
kubectl apply -f demo-ingress.yml
ingress.networking.k8s.io/grpc-ingress created
驗證:
$ grpcurl -insecure -authority demo.kubesre.com 127.0.0.1:443 list
grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter
# 出現如下情況,說明驗證成功了,流量成功路由到了后端服務了!
什么是WebSocket
WebSocket是一種計算機通信協議,它提供了一種在客戶端和服務器之間建立持久性連接的方式,允許雙向實時數據傳輸。WebSocket的主要目的是解決HTTP協議的一些限制,如請求-響應模式和高延遲。以下是WebSocket的一些關鍵特點和用途:
- 雙向通信:WebSocket允許服務器和客戶端之間進行雙向通信,而不像HTTP那樣需要每次都發起新的請求。
- 持久連接:WebSocket連接是持久性的,一旦建立連接,它可以保持打開狀態,以便隨時發送或接收數據,而不必重新建立連接。
- 實時性:由于WebSocket提供了低延遲的通信方式,它特別適合實時應用程序,如在線聊天、在線游戲和實時數據更新。
- 輕量級:WebSocket協議相對較輕量,因此減少了通信開銷和延遲。
- 跨域通信:WebSocket支持跨域通信,這意味著可以在不同域名下的客戶端和服務器之間建立連接。
- 安全性:WebSocket可以通過加密來確保通信的安全性,類似于HTTPS協議
WebSocket通常用于實現各種實時Web應用程序,例如在線聊天、協作工具、在線游戲、股票市場報價、實時監控和通知系統等。它在那些需要實時數據傳輸和即時響應的場景中非常有用,因為它可以降低通信延遲,提供更好的用戶體驗。WebSocket通信建立在TCP協議之上,通常使用端口80(HTTP)或443(HTTPS)來傳輸數據。
WebSocket示例應用部署
部署示例版本:
# 執行創建操作
$ kubectl apply -f ws.yml
deployment.apps/demo-ws created
service/demo-ws-svc created
# 查看創建狀態
kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/demo-ws-79bd8fbdc7-hml6q 1/1 Running 0 2m2s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/demo-ws-svc ClusterIP 10.96.255.28 <none> 8080/TCP 2m2s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 82m
# 出現以上情況說明一切就緒
創建Ingress WebSocket
Kubernetes Ingress Controller默認已支持WebSocket無需額外配置,并可以通過如下注解做些額外優化配置:
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
$ demo-ws-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ws-ingress
spec:
ingressClassName: nginx
rules:
- host: demo.kubesre.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-ws-svc
port:
number: 8090
# 創建WebSocket Ingress資源對象
$ kubectl apply -f demo-ws-ingress.yml
ingress.networking.k8s.io/demo-ws-ingress created
# 查看狀態
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
demo-ws-ingress nginx demo.kubesre.com 80 2m6s
Kubernetes Ingress Controller若默認不支持WebSocket可能是Ingress老版本,則可以通過如下方式進行配置(作為補充知識):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ws-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
spec:
rules:
- host: demo.kubesre.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-ws-svc
port:
number: 8090
NGINX Ingress Controller (Nginx官方),可以通過如下方式進行配置(作為補充知識):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ws-ingress
annotations:
nginx.org/websocket-services: "demo-ws-svc" # 具體的服務名
spec:
ingressClassName: nginx
rules:
- host: demo.kubesre.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-ws-svc
port:
number: 8090
驗證:通過ApiPost工具進行測試驗證成功,Ws可以連接成功并可以成功收發消息!
圖片
總結
本文介紹了gPRC與WebSocket后端協議Ingress配置方法,并通過實際案例的方式講解,下一章將講解Ingress更多企業級實戰,請敬請期待!