天天看點

通過K8S Ingress Controller來實作應用的流量複制

仿真測試

通常在系統進行重大重構或者釋出新功能時,我們都需要進行壓測以事先評估新系統的承載能力,傳統情況下我們一般會線上下環境來模拟線上各種測試資料來對新系統進行測試,但是這種方式往往并不能有效地模拟出線上真實的通路量,尤其是模拟出正常流量中混雜着各色的異常流量,針對這種情況我們可以通過将線上的應用流量複制到指定的線下環境來對新系統進行仿真測試;另外一種情況假若我們線上系統遇到了性能瓶頸,但是又不能快速地定位出問題點,我們同樣可以采用流量複制的方式來将應用的真實流量引導到線下環境來進行定位。下面主要跟大家分享下如何在

阿裡雲容器服務

不同K8S叢集内進行應用的流量複制:

通過K8S Ingress Controller來實作應用的流量複制

部署基礎應用

這裡假設您已經在

阿裡雲容器服務控制台

申請了兩個不同的K8S叢集(暫定一個為K8S Product Cluster,一個為K8S Stage Cluster)。

一、在K8S Product Cluster中部署一個應用,并通過Ingress來對外暴露服務通路:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      # 目前配置為老版本鏡像
      - image: registry.cn-hangzhou.aliyuncs.com/xianlu/old-nginx
        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: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  # 這裡配置使用了叢集預設域名(您也可以使用自定義域名并作DNS解析)
  - host: nginx.c37bf6b77bded43669ba2fb67448b4146.cn-hangzhou.alicontainer.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service
          servicePort: 80           

二、部署完成後可通過如下指令測試通路:

# 檢視該應用的ingress配置
  kubectl get ing nginx-ingress
NAME            HOSTS                                                                  ADDRESS         PORTS     AGE
nginx-ingress   nginx.c37bf6b77bded43669ba2fb67448b4146.cn-hangzhou.alicontainer.com   47.110.199.44   80        8m
 
  # 測試通路應用域名
  curl http://nginx.c37bf6b77bded43669ba2fb67448b4146.cn-hangzhou.alicontainer.com
old
            

三、在K8S Stage Cluster中部署一個相同應用,同樣通過Ingress來對外暴露服務通路:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      # 目前配置為新版本鏡像
      - image: registry.cn-hangzhou.aliyuncs.com/xianlu/new-nginx
        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: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  # 這裡配置使用了叢集預設域名(您也可以使用自定義域名并作DNS解析)
  - host: nginx.c41eb6ca34a3e49f7aea63b8bc9e8ad98.cn-beijing.alicontainer.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service
          servicePort: 80           

四、部署完成後可通過如下指令測試通路:

# 檢視該應用的ingress配置
 kubectl get ing nginx-ingress
NAME            HOSTS                                                                 ADDRESS        PORTS     AGE
nginx-ingress   nginx.c41eb6ca34a3e49f7aea63b8bc9e8ad98.cn-beijing.alicontainer.com   39.106.233.1   80        1m

 # 測試通路應用域名
 curl http://nginx.c41eb6ca34a3e49f7aea63b8bc9e8ad98.cn-beijing.alicontainer.com
new
           

配置流量複制

這裡假設我們希望将K8S Product Cluster中該應用 100% 的通路流量複制到K8S Stage Cluster中對應的應用服務上,即将所有通路域名

nginx.c37bf6b77bded43669ba2fb67448b4146.cn-hangzhou.alicontainer.com

的請求複制轉發一份到

nginx.c41eb6ca34a3e49f7aea63b8bc9e8ad98.cn-beijing.alicontainer.com

上:

通過K8S Ingress Controller來實作應用的流量複制

說明:由于K8S Stage Cluster Ingress僅僅隻作為複制流量的接收方,是以它不需要做任何配置修改,這裡我們隻需要在K8S Product Cluster Ingress上進行配置即可。

一、配置複制流量百分比和接收複制流量的應用域名

通過如下指令來修改K8S Ingress Controller的ConfigMap配置增加

http-snippet

配置片段,配置期望的複制流量百分比和接收複制流量的目标應用域名:

~ kubectl -n kube-system edit cm nginx-configuration           

配置如下KV對:

http-snippet: |
   split_clients "$date_gmt" $mirror_servers {
      100%    nginx.c41eb6ca34a3e49f7aea63b8bc9e8ad98.cn-beijing.alicontainer.com;
   }

# 配置說明:
# 1. 流量百分比取值範圍:(0, 100],百分比總和必須不大于100%
# 2. 支援同時配置多個不同的複制流量接收目标應用           

二、配置流量複制

這裡我們通過

configuration-snippet

server-snippet

來修改源Ingress增加應用的流量複制配置(YAML參考如下):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
        mirror /mirror; # 配置N次該項則可放大N倍流量
    nginx.ingress.kubernetes.io/server-snippet: |
        location = /mirror {
            internal;
            # 不列印mirror請求日志
            #access_log off; 
            # 設定proxy_upstream_name,格式必須為[Namespace]-[BackendServiceName]-[BackendServicePort]
            set $proxy_upstream_name    "default-nginx-service-80";
            # 自定義字元串,會作為請求頭X-Shadow-Service值傳給mirror server
            set $shadow_service_name    "nginx-product-service"; 
            proxy_set_header X-Shadow-Service  $shadow_service_name;
            proxy_set_header Host $mirror_servers;
            proxy_pass http://$mirror_servers$request_uri;
        }
spec:
  rules:
  - host: nginx.c37bf6b77bded43669ba2fb67448b4146.cn-hangzhou.alicontainer.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service
          servicePort: 80           

至此,基于K8S Ingress Controller的應用流量複制配置已經完成。

測試流量複制

這裡我們嘗試通路K8S Product Cluster中的應用域名

nginx.c37bf6b77bded43669ba2fb67448b4146.cn-hangzhou.alicontainer.com

,可以看到每次請求K8S Product Cluster中的Ingress應用域名時,其都将複制一份同樣的請求轉發到K8S Stage Cluster中對應的應用服務中:

通過K8S Ingress Controller來實作應用的流量複制

同時,由于前面我們在流量複制配置中配置了

proxy_set_header X-Shadow-Service $shadow_service_name

,是以在K8S Stage Cluster目标應用接收的請求中,都會攜帶一個

X-Shadow-Service

頭來指明該鏡像流量來源于哪個線上應用。

繼續閱讀