Openshift上使用Nginx Pod作灰度發(fā)布

參考文章:使用 Nginx 實(shí)現(xiàn)灰度發(fā)布

什么是灰度發(fā)布

  • 【百度百科】灰度發(fā)布(又名金絲雀發(fā)布)是指在黑與白之間,能夠平滑過(guò)渡的一種發(fā)布方式。 在其上可以進(jìn)行A/B testing,即讓一部分用戶繼續(xù)用產(chǎn)品特性A,一部分用戶開(kāi)始用產(chǎn)品特性B,如果用戶對(duì)B沒(méi)有什么反對(duì)意見(jiàn),那么逐步擴(kuò)大范圍,把所有用戶都遷移到B上面來(lái)。
  • 除了AB test灰度發(fā)布另一種思想是,只發(fā)布給一小部分用戶,如:App在發(fā)布之前,針對(duì)性的給一小批用戶測(cè)試下新版本,用小流量發(fā)布的方式來(lái)檢驗(yàn)新版會(huì)不會(huì)有問(wèn)題。
  • 灰度發(fā)布可以保證整體系統(tǒng)的穩(wěn)定,在初始灰度的時(shí)候就可以發(fā)現(xiàn)、調(diào)整問(wèn)題,以保證其影響度。

Openshift上實(shí)現(xiàn)藍(lán)綠部署

image.png

在openshift上的部署兩個(gè)版本的Service:service01, service02。在創(chuàng)建Route的時(shí)候,可以非常簡(jiǎn)單地指定同一個(gè)Route流量訪問(wèn)兩個(gè)service的百分比service01(25%流量), service02(75%流量)。所有請(qǐng)求該Route的流量會(huì)被按指定的比例訪問(wèn)后service。


配置發(fā)布75%-25%.png

Route詳情展示.png

對(duì)應(yīng)的Route yaml配置文件如下:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  labels:
    app: grey-test
  name: grey-test
  namespace: grey
spec:
  alternateBackends:
    - kind: Service
      name: service_v2
      weight: 75
  host: grey-test.sample.com
  port:
    targetPort: web
  to:
    kind: Service
    name: service_v1
    weight: 25
  wildcardPolicy: None

金絲雀發(fā)布的不足

  • openshift中Route自帶的金絲雀發(fā)布配置非常簡(jiǎn)單,也很實(shí)用。但是它沒(méi)辦法對(duì)請(qǐng)求的流量進(jìn)行定義控制。
  • 例如根據(jù)IP,指定IP為'202.38.12.10'的用戶訪問(wèn)service_v2,那么Openshift中Route自帶的分流就無(wú)法實(shí)現(xiàn)。
  • 所以必須對(duì)特定用戶訪問(wèn)特定版本的問(wèn)題,我們需要尋求其它辦法。使用傳統(tǒng)的方法,Nginx是一個(gè)比較常見(jiàn)的選擇。在openshift的灰度方案中,我們也嘗試使用Nginx來(lái)實(shí)現(xiàn)對(duì)特定用戶的灰度發(fā)布。

Nginx配置實(shí)現(xiàn)灰度發(fā)布

  1. 創(chuàng)建兩個(gè)upstream
  2. 針對(duì)remote_addr進(jìn)行分流,默認(rèn)訪問(wèn)default的upstream,如果ip為'202.38.12.10',則訪問(wèn)api_v2的upstream。

無(wú)需多解釋,直接上配置。

upstream default{
    server 172.30.198.194:8080 max_fails=1 fail_timeout=60;
}

upstream api_v2{
    server 172.30.198.194:8080 max_fails=1 fail_timeout=60;
}

server {
  listen 80;
  server_name  _;

  set $group default;
  if ($remote_addr ~ "202.38.12.10") {
      set $group api_v2;
  }

location / {                       
    proxy_pass http://$group;
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    index  index.html index.htm;
  }
}

對(duì)配置作進(jìn)一步優(yōu)化

怎么獲取客戶端IP?

  • 如果直接訪問(wèn)Nginx服務(wù)的話,在Nginx上通過(guò) $remote_addr 能夠獲得客戶端IP,但是我們知道在Openshift高可用部署中,我們使用了負(fù)載均衡器。通過(guò)負(fù)載均衡器轉(zhuǎn)發(fā)后,Nginx webserver獲得的$remote_addr其實(shí)是負(fù)載均衡器的IP,而不是客戶端真實(shí)IP。
  • 為了能在Nginx webserver中獲得客戶端IP,需要在附加HTTP頭字段開(kāi)啟客戶端真實(shí)IP。同時(shí)在Nginx的配置中使用$http_x_forwarded_for來(lái)檢查客戶端IP.


    IaaS上創(chuàng)建負(fù)載均衡器.png
  • 新的配置如下
upstream default{
    server 172.30.198.194:8080 max_fails=1 fail_timeout=60;
}

upstream api_v2{
    server 172.30.198.194:8080 max_fails=1 fail_timeout=60;
}

server {
  listen 80;
  server_name  _;

  set $group default;
  if ($http_x_forwarded_for ~ "202.38.12.10") {
      set $group api_v2;
  }

location / {                       
    proxy_pass http://$group;
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    index  index.html index.htm;
  }
}

如何實(shí)現(xiàn)高可用?

這個(gè)非常簡(jiǎn)單,只需要在Openshift上將為Nginx的DeploymentConfig增加Pod數(shù)增就可以了。

我要有多個(gè)IP加入白名單,有沒(méi)有更方便的配置方法?

Nginx有map函數(shù),能將IP與訪問(wèn)的后臺(tái)服務(wù)。

map $http_x_forwarded_for $group {
        default 172.30.198.194:8080;
        ~202.38.12.10 172.30.198.194:8080;
    }
server{
    listen  8080;
    server_name _; 
    location /{
        proxy_pass http://$group;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
        index index.html index.htm;
    }
} 

明明有域名為啥只能是IP?

  • Openshift對(duì)于Service除了有固定的IP外,還有固定的域名,一般域名形式為:servername-projectname.svc。我們能否用域名代替IP,讓這個(gè)配置的可讀性更高,什么IP訪問(wèn)什么服務(wù)一目了然。
  • 但是直接將IP更改為對(duì)應(yīng)Service的域名,在啟動(dòng)Nginx時(shí)會(huì)報(bào)無(wú)法解析域名的錯(cuò)誤。
  • Nginx需要在map配置中解析域名需要指定dns。
  • 最終配置如下(172.30.0.1為Openshif集群默認(rèn)的內(nèi)部DNS,可在master的配置文件中查看):
resolver 172.30.0.1;
map $http_x_forwarded_for $group {
        default api_v1.server.svc:8080;
        ~202.38.12.10 api_v2.server.svc:8080;
    }
server{
    listen  8080;
    server_name _; 
    location /{
        proxy_pass http://$group;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
        index index.html index.htm;
    }
} 

Openshift中對(duì)于443端口的負(fù)載均衡器使用的是TCP協(xié)議,無(wú)法轉(zhuǎn)發(fā)X_forward_for,那https服務(wù)要怎么弄?

如何應(yīng)用請(qǐng)求為Https,無(wú)法直接使用TCP負(fù)載均衡器,而Openshift部署時(shí)是通過(guò)TCP負(fù)載均衡器來(lái)作443端口的負(fù)載的。

  • 這就需要?jiǎng)?chuàng)建一個(gè)Https負(fù)載均衡器, 后臺(tái)Openshift Nginx的Route設(shè)置為正常的Http。其它配置一樣。既能將clientIP傳給后臺(tái)webserver,同時(shí)又滿足了該業(yè)務(wù)請(qǐng)求為Http協(xié)議。
  • 最終的流程圖如下:


    Nginx作負(fù)載均衡器圖.png

拓展思考

  • 是否一定要在Openshift上部署呢?【必然不需要】
  • Nginx實(shí)現(xiàn)灰度發(fā)布除了支持ip還支持啥?【對(duì)Header頭信息等】
  • 除了對(duì)頁(yè)面HTTP請(qǐng)求實(shí)現(xiàn)這種灰度,那么對(duì)于TCP服務(wù)呢,比如說(shuō)數(shù)據(jù)庫(kù)?【也是OK的】
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容