ambassador網關實現灰度部署

開發者能夠經過kuberneters annotation,很容易控制服務的流量,實現灰度發佈api

應用場景

  1. 微服務各組件獨立更新,而後驗證又必須在實際環境中進行
  2. 部署新功能有風險,而後能夠經過導流一小部分用戶實際使用,來減少風險
  3. 依賴的第三方組件,沒法很好地進行測試,只能依靠實際的使用,來驗證是否能成功的對接。

過程

  1. 部署v2版本,定義導量1%
  2. 測試(請求多少次,有木有失敗之類的,由業務方決定),觀測和監控
  3. 沒有問題則v2 100%(沒有迭代的過程,區別滾動部署),下線v1版本

架構圖

架構圖

工做流程

  • service annotation中定義配置,Kubernetes API 異步通知 Ambassador 的更改。
  • Ambassador 將配置轉換爲抽象的中間代碼 (IR)。
  • 從 IR 中生成一個 Envoy 配置文件。
  • 使用 Ambassador 驗證 Envoy 配置文件。
  • 若是配置文件有效,Ambassador 將使用 Envoy 的熱從新啓動機制來部署新的配置,並保持鏈接。
  • 流量將會在新啓動的 Envoy 進程中傳輸。

功能描述

Self-Service via Kubernetes Annotations

developer能夠經過kubernetes service 的annotations來定義ambassadorf服務,很容易集成到你的現有項目中。架構

Flexible Canary Deployments

developer能夠經過kuberneters annotation很容易控制到服務的流量,實現金絲雀發佈。app

Kubernetes-Native Architecture

利用k8s原生能力實現可靠性、可用性和可伸縮性。使用envoy實現路由和代理curl

gRPC and HTTP/2 Support

由envoy提供的能力異步

Istio Integration

和istio配合實現服務網格。ambassador做爲邊緣代理,實現外部流量到內部istio的橋樑。ide

Authentication

ambassador支持請求認證。若是配置了,ambassador在路由以前會事先請求第三方認證服務微服務

Rate Limiting

ambassador支持限流。ambassador在路由以前會事先請求第三方速度限流服務測試

Integrated Diagnostics

ambassador包含一個診斷服務,能夠快速定位問題ui

部署

install deploythis

測試

提早部署兩個後臺服務 sv1 和 sv2

sv1 請求返回"Hello World, this is test service num 1!"
sv2 請求返回"Hello World, this is test service num 2!"

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: svc1
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: svc1
    spec:
      containers:
      - name: svc1
        image: ambassador-sv1:1.0
        ports:
        - name: http-api
          containerPort: 5000
        resources:
          limits:
            cpu: "0.1"
            memory: 100Mi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: svc2
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: svc2
    spec:
      containers:
      - name: svc2
        image: ambassador-sv2:1.0
        ports:
        - name: http-api
          containerPort: 5000
        resources:
          limits:
            cpu: "0.1"
            memory: 100Mi

根據weight進行灰度

以80%的機率路由到svc1, 20%的機率路由到svc2

svc1 (不配置權重,默認100%)

---
apiVersion: v1
kind: Service
metadata:
  name: svc1
  namespace: 295-a222222
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind:  Mapping
      name:  svc1_mapping
      prefix: /svc/
      service: svc1.295-a222222:8080
spec:
  selector:
    app: svc1
  ports:
  - port: 8080
    name: http-svc
    targetPort: http-api

svc2

---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  namespace: 295-a222222
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind:  Mapping
      name:  svc2_mapping
      prefix: /svc/
      service: svc2.295-a222222:8080
      weight: 20
spec:
  selector:
    app: svc2
  ports:
  - port: 8080
    name: http-svc
    targetPort: http-api

結果:

[root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 2![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 2![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 2![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl 10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl

根據請求頭 header 進行灰度 (regex_headers 正則匹配)

請求頭中包含Cookie: UM_distinctid=12345的請求所有路由到svc2中

---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind:  Mapping
      name:  svc2_mapping
      prefix: /svc/
      service: svc2
      headers:
        Cookie: UM_distinctid=12345
spec:
  selector:
    app: svc2
  ports:
  - port: 80
    name: http-svc2
    targetPort: http-api
regex_headers
apiVersion: v1
kind: Service
metadata:
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind:  Mapping
      name:  create
      prefix: /svc/create/
      service: create:8080
      regex_headers:
        Cookie: "ddddd.*"

結果:

[root@master01 ambassador]# curl  10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl  10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl  10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl  10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# curl  10.104.75.142:80/svc/
Hello World, this is test service num 1![root@master01 ambassador]# 
[root@master01 ambassador]# 
[root@master01 ambassador]# curl -H "Cookie: UM_distinctid=12345" 10.104.75.142:80/svc/
Hello World, this is test service num 2![root@master01 ambassador]# curl -H "Cookie: UM_distinctid=12345" 10.104.75.142:80/svc/
Hello World, this is test service num 2![root@master01 ambassador]# curl -H "Cookie: UM_distinctid=12345" 10.104.75.142:80/svc/
Hello World, this is test service num 2![root@master01 ambassador]# curl -H "Cookie: UM_distinctid=12345" 10.104.75.142:80/svc/
Hello World, this is test service num 2![root@master01 ambassador]# curl -H "Cookie: UM_distinctid=12345" 10.104.75.142:80/svc/
Hello World, this is test service num 2![root@master01 ambassador]# curl -H "Cookie: UM_distinctid=12345" 10.104.75.142:80/svc/
Hello World, this is test service num 2![root@master01 ambassador]#

業務灰度流程

當前業務

即須要更新的業務,此時業務流向全走向svc1

kubectl apply -f svc1.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc1
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind:  Mapping
      name:  svc1_mapping
      prefix: /svc/
      service: svc1
spec:
  ····

查看ambassador的流量代理

url service weight
http://172.31.133.26:31327/svc/ svc1 100.0%

灰度版本

部署svc2.yaml,此時帶header: Cookie: UM_distinctid=12345 流量走向svc2,不帶header流量依舊走svc1。

kubectl apply -f svc2.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind:  Mapping
      name:  svc2_mapping
      prefix: /svc/
      service: svc2
      headers:
        Cookie: UM_distinctid=12345
spec:
  ···

查看ambassador的流量代理

url service weight
http://172.31.133.26:31327/svc/ svc1 100.0%
http://172.31.133.26:31327/svc/
Cookie: UM_distinctid=12345
svc2 100.0%

流量切換

第一步

更新header(去掉header),此時一半流量到svc1,一半到svc2

kubectl apply -f svc2.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind:  Mapping
      name:  svc2_mapping
      prefix: /svc/
      service: svc2
#      headers:
#        Cookie: UM_distinctid=12345
spec:
  ···

查看ambassador的流量代理

url service weight
http://172.31.133.26:31327/svc/ svc1
svc2
50.0%
100.0%

第二步

下線老的服務svc1,流量所有走到svc2

kubectl delete -f svc1.yaml

查看ambassador的流量代理

url service weight
http://172.31.133.26:31327/svc/ svc2 100.0%
相關文章
相關標籤/搜索