標籤:

使用阿里雲容器服務Kubernetes實現藍綠髮布功能

背景

在發布應用時,經常需要先上線一個新版本,用較小的流量去測試一下該新版本的可用性。但是Kubernetes的ingress resource 並沒有實現流量控制與切分的功能,導致針對同一個域名下的路徑,只能有一個service來進行服務。這樣對於灰度發布十分不利,下面我們就來介紹一下阿里雲容器服務的藍綠髮布功能,輕鬆實現流量切分。

前置條件

既然需要進行藍綠髮布,那麼應該已經有一個老服務在正常的對外提供服務中。我們這裡以nginx 為例,假定已經有一個nginx deployment 通過NodePort對外暴露埠,並且有一個ingress正在對外提供服務。我們使用的模板如下:

apiVersion: extensions/v1beta1kind: Deploymentmetadata: labels: run: old-nginx name: old-nginxspec: replicas: 1 selector: matchLabels: run: old-nginx template: metadata: labels: run: old-nginx spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/xianlu/old-nginx imagePullPolicy: Always name: old-nginx ports: - containerPort: 80 protocol: TCP restartPolicy: Always---apiVersion: v1kind: Servicemetadata: labels: run: old-nginx name: old-nginxspec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: old-nginx sessionAffinity: None type: NodePort---apiVersion: extensions/v1beta1kind: Ingressmetadata: name: echospec: backend: serviceName: default-http-backend servicePort: 80 rules: - host: mini-echo.io http: paths: - path: / backend: serviceName: old-nginx servicePort: 80

可以看到已經創建好的ingrsss地址

[root@iZwz91e2au5xvyw5jdpqp7Z manifests]# kubectl get ingNAME HOSTS ADDRESS PORTS AGEecho mini-echo.io 47.106.45.47 80 3m

我們在本機通過curl訪問可以看到如下效果

~ curl -H "Host: mini-echo.io" http://47.106.45.47old

進行藍綠髮布

  • 創建新的deployment與service

apiVersion: extensions/v1beta1kind: Deploymentmetadata: labels: run: new-nginx name: new-nginxspec: replicas: 1 selector: matchLabels: run: new-nginx template: metadata: labels: run: new-nginx spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/xianlu/new-nginx imagePullPolicy: Always name: new-nginx ports: - containerPort: 80 protocol: TCP restartPolicy: Always---apiVersion: v1kind: Servicemetadata: labels: run: new-nginx name: new-nginxspec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: new-nginx sessionAffinity: None type: NodePort

可以看到,唯一的變化就是,所有的old-nginx 都變成了new-nginx。

  • 修改ingress

主要增加兩個地方:

  1. 增加annotations ,標籤ingress.aliyun.weight/new-nginx: "50"代表,/後面為新服務的服務名,也就是新的service name。後面的50代表百分比,以%為單位,50代表新服務佔領百分之50的流量。此標籤的完整含義為,將流量的百分之50打到新的服務的pod裡面。
  2. 第二處為指定對應的新的serviceName。這裡是和上面老服務並列,即在相同的Path 下,掛兩個不同的service ,分別對應於兩個新老應用。
  • 效果

~ curl -H "Host: mini-echo.io" http://47.106.45.47old ~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47old ~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47old ~ curl -H "Host: mini-echo.io" http://47.106.45.47new

可以看到,執行六次請求,分別得到三次新服務,三次老服務的返回,這表明權重設置生效了。

流量完全切換到新服務

只需要將新服務的百分比寫到100就可以,再看一下效果。

~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47new

可以看到,流量都打到了新服務。

完成藍綠髮布

只需要將設置權重的annotation 刪除即可,然後將下面對應的serviceName也刪除,這樣就恢復了原本ingress的原貌,同時將原來的老服務改成了新的服務。下面再來看一下效果:

~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47new ~ curl -H "Host: mini-echo.io" http://47.106.45.47new

可以看到,新的服務已經上線,這就完成了整個藍綠髮布的完整生命周期。

原文鏈接

更多技術乾貨敬請關注云棲社區知乎機構號:阿里云云棲社區 - 知乎

推薦閱讀:

用 php 抓取 https 加密的鏈接

TAG:容器 | cURL |