金絲雀發布/灰度發布
金絲雀發布的重點在于:試錯。金絲雀發布的來歷本身就是自然界的美麗生物在人類工業發展過程中的一個悲慘的故事。金絲雀就是用它的生命來為礦工的安全來試錯的。用很小的成本來換取整體的安全,在持續部署的實踐中,金絲雀就是流量控制,用很少的流量比如百分之一或者十分之一用于檢證某個版本是否正常,如果不正常則就用最低的成本實現了其作用,降低了風險。如果正常,則可以逐漸加大權重直至百分之百,將所有的流量都平穩地切換至新的版本?;叶劝l布,一般來說也是類似的概念。灰色是介于黑和白之前的一個過渡,區別于藍綠部署的非藍即綠,灰度發布/金絲雀發布會有一個兩者同時存在的時間段,只是兩者對應的流量不同,金絲雀發布如果說和灰度發布有所不同的話,其不同點應該是目的性的不同,金絲雀發布目的在于試錯,而灰度發布在于平穩發布,而在金絲雀發布沒有問題的狀況下進行的平穩過渡則正是灰度發布。
模擬金絲雀發布
接下來我們使用nginx的upstream來簡單模擬一下金絲雀發布的場景。具體場景如下, 當前活躍的是主版本,通過調整nginx設定,通過不斷的調節金絲雀版本的權重,最終實現平穩地發布。
事前準備
事前在7001/7002兩個端口分別啟動兩個服務,用于顯示不同信息,為了演示方便,使用tornado做了一個鏡像,通過docker容器啟動時傳遞的參數不同用于顯示服務的不同。
docker?run?-d?-p?7001:8080?liumiaocn/tornado:latest?python?/usr/local/bin/daemon.py?"hello?main?service:?v1?in?7001" docker?run?-d?-p?7002:8080?liumiaocn/tornado:latest?python?/usr/local/bin/daemon.py?"hello?canary?deploy?service:?v2?in?7002"
執行日志
[root@kong?~]#?docker?run?-d?-p?7001:8080?liumiaocn/tornado:latest?python?/usr/local/bin/daemon.py?"hello?main?service:?v1?in?7001" 28f42bbd21146c520b05ff2226514e62445b4cdd5d82f372b3791fdd47cd602a [root@kong?~]#?docker?run?-d?-p?7002:8080?liumiaocn/tornado:latest?python?/usr/local/bin/daemon.py?"hello?canary?deploy?service:?v2?in?7002" b86c4b83048d782fadc3edbacc19b73af20dc87f5f4cf37cf348d17c45f0215d [root@kong?~]#?curl?http://192.168.163.117:7001 hello,?service?:hello?main?service:?v1?in?7001 [root@kong?~]#?curl?http://192.168.163.117:7002 hello,?service?:hello?canary?deploy?service:?v2?in?7002 [root@kong?~]#
啟動nginx
[root@kong?~]#?docker?run?-p?9080:80?--name?nginx-canary?-d?nginx 659f15c4d006df6fcd1fab1efe39e25a85c31f3cab1cda67838ddd282669195c [root@kong?~]#?docker?ps?|grep?nginx-canary 659f15c4d006????nginx???????????"nginx?-g?'daemon?..."??7?seconds?ago????up?7?seconds????0.0.0.0:9080->80/tcp???nginx-canary [root@kong?~]#
nginx代碼段
準備如下nginx代碼段將其添加到nginx的/etc/nginx/conf.d/default.conf中, 模擬方式很簡單,通過down來表示流量為零(nginx中無法將weight設置為零),開始的時候100%的流量都發到主版本。
http?{ upstream?nginx_canary?{ ??server?192.168.163.117:7001?weight=100; ??server?192.168.163.117:7002?down; } server?{ ??listen????80; ??server_name?www.liumiao.cn?192.168.163.117; ??location?/?{ ????proxy_pass?http://nginx_canary; ??} }
修改default.conf的方法
可以通過在容器中安裝vim達到效果,也可以在本地修改然后通過docker cp傳入,或者直接sed修改都可。如果在容器中安裝vim,使用如下方式即可
[root@kong?~]#?docker?exec?-it?nginx-lb?sh #?apt-get?update ...省略 #?apt-get?install?vim ...省略
修改前
#?cat?default.conf server?{ ??listen????80; ??server_name?localhost; ??#charset?koi8-r; ??#access_log?/var/log/nginx/host.access.log?main; ??location?/?{ ????root??/usr/share/nginx/html; ????index?index.html?index.htm; ??} ??#error_page?404???????/404.html; ??#?redirect?server?error?pages?to?the?static?page?/50x.html ??# ??error_page??500?502?503?504?/50x.html; ??location?=?/50x.html?{ ????root??/usr/share/nginx/html; ??} ??#?proxy?the?php?scripts?to?apache?listening?on?127.0.0.1:80 ??# ??#location?~?.php$?{ ??#??proxy_pass??http://127.0.0.1; ??#} ??#?pass?the?php?scripts?to?fastcgi?server?listening?on?127.0.0.1:9000 ??# ??#location?~?.php$?{ ??#??root??????html; ??#??fastcgi_pass??127.0.0.1:9000; ??#??fastcgi_index?index.php; ??#??fastcgi_param?script_filename?/scripts$fastcgi_script_name; ??#??include????fastcgi_params; ??#} ??#?deny?access?to?.htaccess?files,?if?apache's?document?root ??#?concurs?with?nginx's?one ??# ??#location?~?/.ht?{ ??#??deny?all; ??#} } #
修改后
#?cat?default.conf upstream?nginx_canary?{ ??server?192.168.163.117:7001?weight=100; ??server?192.168.163.117:7002?down; } server?{ ??listen????80; ??server_name?www.liumiao.cn?192.168.163.117; ??#charset?koi8-r; ??#access_log?/var/log/nginx/host.access.log?main; ??location?/?{ ????#root??/usr/share/nginx/html; ????#index?index.html?index.htm; ????proxy_pass?http://nginx_canary; ??} ??#error_page?404???????/404.html; ??#?redirect?server?error?pages?to?the?static?page?/50x.html ??# ??error_page??500?502?503?504?/50x.html; ??location?=?/50x.html?{ ????root??/usr/share/nginx/html; ??} ??#?proxy?the?php?scripts?to?apache?listening?on?127.0.0.1:80 ??# ??#location?~?.php$?{ ??#??proxy_pass??http://127.0.0.1; ??#} ??#?pass?the?php?scripts?to?fastcgi?server?listening?on?127.0.0.1:9000 ??# ??#location?~?.php$?{ ??#??root??????html; ??#??fastcgi_pass??127.0.0.1:9000; ??#??fastcgi_index?index.php; ??#??fastcgi_param?script_filename?/scripts$fastcgi_script_name; ??#??include????fastcgi_params; ??#} ??#?deny?access?to?.htaccess?files,?if?apache's?document?root ??#?concurs?with?nginx's?one ??# ??#location?~?/.ht?{ ??#??deny?all; ??#} } #
重新加載nginx設定
#?nginx?-s?reload 2018/05/28?05:16:20?[notice]?319#319:?signal?process?started #
確認結果
10次調用全部輸出的都是v1 in 7001
[root@kong ~]# cnt=0; while [ $cnt -lt 10 ]; do curl ; let cnt++; done
hello, service :hello main service: v1 in 7001
hello, service :hello main service: v1 in 7001
hello, service :hello main service: v1 in 7001
hello, service :hello main service: v1 in 7001
hello, service :hello main service: v1 in 7001
hello, service :hello main service: v1 in 7001
hello, service :hello main service: v1 in 7001
hello, service :hello main service: v1 in 7001
hello, service :hello main service: v1 in 7001
hello, service :hello main service: v1 in 7001
[root@kong ~]#
金絲雀發布: 金絲雀版本流量權重10%
通過調整default.conf的weight,然后執行nginx -s reload的方式,調節金絲雀版本的權重為10%,流量的10%會執行新的服務
修改default.conf的方法
只需要將upstream中的server的權重做如下調整:
upstream?nginx_canary?{ ??server?192.168.163.117:7001?weight=10; ??server?192.168.163.117:7002?weight=90; }
重新加載nginx設定
#?nginx?-s?reload 2018/05/28?05:20:14?[notice]?330#330:?signal?process?started #
確認結果
[root@kong ~]# cnt=0; while [ $cnt -lt 10 ]; do curl ; let cnt++; done
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello main service: v1 in 7001
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
[root@kong ~]#
金絲雀發布: 金絲雀版本流量權重50%
通過調整default.conf的weight,然后執行nginx -s reload的方式,調節金絲雀版本的權重為50%,流量的50%會執行新的服務
修改default.conf的方法
只需要將upstream中的server的權重做如下調整:
upstream?nginx_canary?{ ??server?192.168.163.117:7001?weight=50; ??server?192.168.163.117:7002?weight=50; }
重新加載nginx設定
#?nginx?-s?reload 2018/05/28?05:22:26?[notice]?339#339:?signal?process?started #
確認結果
[root@kong ~]# cnt=0; while [ $cnt -lt 10 ]; do curl ; let cnt++; done
hello, service :hello main service: v1 in 7001
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello main service: v1 in 7001
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello main service: v1 in 7001
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello main service: v1 in 7001
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello main service: v1 in 7001
hello, service :hello canary deploy service: v2 in 7002
[root@kong ~]#
金絲雀發布: 金絲雀版本流量權重90%
通過調整default.conf的weight,然后執行nginx -s reload的方式,調節金絲雀版本的權重為90%,流量的90%會執行新的服務
修改default.conf的方法
只需要將upstream中的server的權重做如下調整:
upstream?nginx_canary?{ ??server?192.168.163.117:7001?weight=10; ??server?192.168.163.117:7002?weight=90; }
重新加載nginx設定
#?nginx?-s?reload 2018/05/28?05:24:29?[notice]?346#346:?signal?process?started #
確認結果
[root@kong ~]# cnt=0; while [ $cnt -lt 10 ]; do curl ; let cnt++; done
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello main service: v1 in 7001
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
[root@kong ~]#
金絲雀發布: 金絲雀版本流量權重100%
通過調整default.conf的weight,然后執行nginx -s reload的方式,調節金絲雀版本的權重為100%,流量的100%會執行新的服務
修改default.conf的方法
只需要將upstream中的server的權重做如下調整:
upstream?nginx_canary?{ ??server?192.168.163.117:7001?down; ??server?192.168.163.117:7002?weight=100; }
重新加載nginx設定
#?nginx?-s?reload 2018/05/28?05:26:37?[notice]?353#353:?signal?process?started
確認結果
[root@kong ~]# cnt=0; while [ $cnt -lt 10 ]; do curl ; let cnt++; done
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
hello, service :hello canary deploy service: v2 in 7002
[root@kong ~]#