跨叢集流量複製是通過將生產環境的流量鏡像到另一個測試環境中,協助進行系統模擬測試和問題定位。這種方式可以在不影響生產環境的情況下,對應用服務進行全面的測試和故障排查。本文將介紹如何通過Nginx Ingress Controller實現在不同ACK叢集間的流量複製。
前提條件
已建立兩個ACK叢集。具體操作,請參見建立Kubernetes託管版叢集。
已安裝Nginx Ingress Controller組件,版本不低於v1.2.1。具體操作,請參見管理Nginx Ingress Controller組件。
應用情境
流量複製(Traffic Mirror)功能應用於以下兩個情境:
真實流量類比測試:
在系統進行重大重構或者發布新功能時,往往需要對系統進行壓測以事先評估新系統的承載能力。傳統情況下,線上下環境類比線上各種測試資料來對新系統進行測試,但是這種方式往往並不能有效地類比出線上真實的訪問量,尤其是類比正常流量中混雜著各色的異常流量。針對這種情況,可以通過將線上的應用流量複製到指定的線下環境來對新系統進行模擬測試。
問題排查:
線上系統遇到效能瓶頸,但是又不能快速地定位出問題時,這時可以採用流量複製的方式來將應用的真實流量引導到線下環境來進行問題定位。
本樣本情境中ACK叢集一個名為K8s Product Cluster(生產環境),另一個名為K8s Stage Cluster(測試環境)。
前置說明
將K8s Product Cluster(生產環境)中的應用100%的訪問流量鏡像,到K8s Stage Cluster(測試環境)中對應的應用服務,即將所有訪問網域名稱example.com
的提取複寫並轉寄到example1.com
。
步驟一:測試環境中部署基礎應用
在K8s Stage Cluster(測試環境)中使用以下樣本應用的YAML內容,建立名為my-nginx.yaml檔案。
說明K8s Stage Cluster(測試環境)作為複製流量的接收方,只部署接收流量的應用服務,不用做任何配置修改。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 imagePullPolicy: Always name: nginx ports: - containerPort: 80 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: NodePort --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress spec: rules: - host: example1.com http: paths: - path: / backend: service: name: nginx-service port: number: 80 pathType: ImplementationSpecific
執行以下命令,部署樣本應用my-nginx。
kubectl apply -f my-nginx.yaml
執行以下命令,查看該應用的Ingress配置。
kubectl get ing nginx-ingress
預期輸出:
NAME HOSTS ADDRESS PORTS AGE nginx-ingress example1.com 47.**.**.53 80 8m
網域名稱解析後,執行以下命令,測試訪問應用網域名稱。
curl http://example1.com
步驟二:生產環境中配置流量複製
在K8s Product Cluster(生產環境)部署應用服務後,需要在Ingress中添加流量鏡像的注釋。
在K8s Product Cluster(生產環境)中使用以下樣本應用的YAML內容,建立名為my-nginx.yaml檔案。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 imagePullPolicy: Always name: nginx ports: - containerPort: 80 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: NodePort
執行以下命令,部署樣本應用my-nginx。
kubectl apply -f my-nginx.yaml
使用以下樣本Ingress的YAML內容,建立名為my-ingress.yaml檔案。
配置
nginx.ingress.kubernetes.io/mirror-target
,指向在K8s Stage Cluster(測試環境叢集)步驟3中擷取的ADDRESS
。僅適用於HTTP或HTTPS協議,更多詳情請參見ingress-nginx_mirror。配置
nginx.ingress.kubernetes.io/mirror-host
指向在K8s Stage Cluster(測試環境叢集)步驟3中擷取的HOSTS
。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress annotations: nginx.ingress.kubernetes.io/mirror-target: "http://47.**.**.53$request_uri" #指定鏡像請求的目標後端地址。 nginx.ingress.kubernetes.io/mirror-request-body: "off" # 關閉將請求體(request body)發送到鏡像目標後端,如果需要請求體去掉此注釋即可。 nginx.ingress.kubernetes.io/mirror-host: "example1.com" # 設定流量鏡像請求的Host頭。 spec: rules: - host: example.com http: paths: - path: / backend: service: name: nginx-service port: number: 80 pathType: ImplementationSpecific
執行以下命令,部署樣本鏡像Ingress。
kubectl apply -f my-ingress.yaml
執行以下命令,查看該應用的Ingress配置。
kubectl get ing nginx-ingress
預期輸出:
NAME HOSTS ADDRESS PORTS AGE nginx-ingress example.com 39.**.**.54 80 1m
執行以下命令,測試訪問應用網域名稱。
curl http://example.com
結果驗證
訪問K8s Product Cluster(生產環境)中的應用網域名稱example.com
。通過執行以下命令,可以看到每次請求該網域名稱時,都會產生一個相同的請求並轉寄到K8s Stage Cluster(測試環境)中對應的服務。
kubectl -n kube-system logs --tail=0 -f nginx-ingress-controller-674c96ffbc-9mc8n