通过阿里云K8S Ingress Controller实现路由配置的动态更新
簡(jiǎn)介
在Kubernetes集群中,Ingress作為集群內(nèi)服務(wù)對(duì)外暴露的訪問(wèn)接入點(diǎn),其幾乎承載著集群內(nèi)服務(wù)訪問(wèn)的所有流量。我們知道,Nginx Ingress Controller是Kubernetes社區(qū)很重要的一個(gè)子項(xiàng)目,其內(nèi)部主要依托于高性能的負(fù)載均衡軟件Nginx,將Kubernetes Ingress資源對(duì)象實(shí)時(shí)地自動(dòng)化轉(zhuǎn)換為Nginx配置規(guī)則來(lái)對(duì)外提供期望的授權(quán)訪問(wèn)入口。
現(xiàn)實(shí)問(wèn)題
當(dāng)隨著Kubernetes集群中部署的微服務(wù)越來(lái)越多,對(duì)外暴露的路由規(guī)則越來(lái)越復(fù)雜,服務(wù)后端Endpoint變化的越來(lái)越頻繁,那么對(duì)應(yīng)地都會(huì)引起Nginx Ingress Controller組件內(nèi)Nginx配置文件的變化越來(lái)越頻繁;而我們知道,任何一行Nginx配置的變化,都需要Reload Nginx才能生效,這在變化頻率較低的場(chǎng)景下索性還能接受,但在高頻率變化的場(chǎng)景下就會(huì)引起Nginx的頻繁Reload。
而Nginx頻繁Reload帶來(lái)的問(wèn)題,這已是一個(gè)老生常談的話題了,其問(wèn)題本質(zhì)主要還是源于Nginx本身最初的架構(gòu)設(shè)計(jì)模型:
一般在Linux服務(wù)器中,我們會(huì)配置使用Nginx的EPOLL多進(jìn)程模式;當(dāng)我們修改了Nginx配置文件后,需要通過(guò)
nginx -s reload命令來(lái)重新熱加載新的Nginx配置規(guī)則;
當(dāng)Nginx Master進(jìn)程接收到reload signal后,其會(huì)從指定路徑重新加載新的Nginx配置文件內(nèi)容,并校驗(yàn)配置規(guī)則的有效性,若檢驗(yàn)為有效的配置文件,則會(huì)依據(jù)新的配置文件中的worker_processes值fork出指定數(shù)量的新的Nginx Worker進(jìn)程,此時(shí)新fork出來(lái)的子進(jìn)程完全繼承了父進(jìn)程的內(nèi)存數(shù)據(jù)ngx_cycle(其包含了新的解析后的Nginx配置規(guī)則),同時(shí)將配置中的每一個(gè)Listen Socket FD注冊(cè)到內(nèi)核的EPOLL事件監(jiān)聽(tīng)中,此時(shí)這些新的Nginx Worker進(jìn)程可以接收處理來(lái)自客戶端的請(qǐng)求;
同時(shí)Nginx Master進(jìn)程會(huì)發(fā)送QUIT signal通知老的Nginx Worker進(jìn)程平滑退出,當(dāng)老的Nginx Worker進(jìn)程接收到QTUI信號(hào)后,將其之前注冊(cè)到EPOLL中的監(jiān)聽(tīng)Event移除,至此不再接收處理新的客戶端請(qǐng)求,并依據(jù)老配置文件中設(shè)置的worker_shutdown_timeout值來(lái)設(shè)置定時(shí)器,然后繼續(xù)處理完已接收的客戶端請(qǐng)求;若在worker_shutdown_timeout之前處理完已有的客戶端請(qǐng)求,則自動(dòng)退出,若未處理完,則被強(qiáng)制Kill退出,此時(shí)就會(huì)導(dǎo)致該客戶端請(qǐng)求響應(yīng)異常。
因此,對(duì)于在高頻率變化的場(chǎng)景下,Nginx頻繁Reload會(huì)帶來(lái)較明顯的請(qǐng)求訪問(wèn)問(wèn)題:
動(dòng)態(tài)更新
為緩解Nginx頻繁Reload帶來(lái)的影響,我們需要通過(guò)動(dòng)態(tài)更新的方式來(lái)加載Nginx配置規(guī)則,即在不Fork新Nginx Worker進(jìn)程的情況下來(lái)實(shí)時(shí)更新已加載到內(nèi)存中的Nginx配置規(guī)則。
首先我們看下Nginx的配置文件樣式,主要包含下面幾部分配置章節(jié):
# 1. main configuration daemon off; worker_processes 4;events {# 2. event configurationmulti_accept on;worker_connections 1024;use epoll; }http {# 3. http main configurationaccess_log /var/log/nginx/access.log;error_log /var/log/nginx/error.log;upstream {# 4. upstream configurationserver 0.0.0.1;}server {# 5. server configurationserver_name _ ;listen 80 default_server;location / {# 6. location configurationproxy_pass http://upstream_balancer;} }而在Kubernetes集群中,一個(gè)Ingress資源對(duì)象主要被解析映射到Nginx的HTTP Main Block、Server Block、Upstream Block和Location Block等章節(jié)的配置規(guī)則上,因此我們可以將這幾部分頻繁變化的配置內(nèi)容以Shared Memory的方式統(tǒng)一維持在內(nèi)存中,同時(shí)在Ingress Controller內(nèi)部暴露出管控端口,通過(guò)API的方式來(lái)實(shí)時(shí)管理Nginx路由規(guī)則配置:
當(dāng)K8S Ingress Controller監(jiān)控到集群內(nèi)Ingress及相關(guān)聯(lián)的資源發(fā)生變化時(shí),均可通過(guò)Internal API將最新的Nginx配置規(guī)則推送到統(tǒng)一的共享內(nèi)存配置中,而不用再通過(guò)Reload Nginx的方式來(lái)使新配置生效,至此當(dāng)Nginx處理任何新接收的客戶端請(qǐng)求時(shí),都可以基于最新的共享內(nèi)存中的配置進(jìn)行規(guī)則匹配和路由轉(zhuǎn)發(fā);
配置說(shuō)明
1、目前阿里云容器服務(wù)Kubernetes集群中最新版本的Nginx Ingress Controller組件默認(rèn)已開(kāi)啟Upstream的動(dòng)態(tài)更新,同時(shí)支持應(yīng)用服務(wù)的灰度發(fā)布和藍(lán)綠發(fā)布功能,具體配置說(shuō)明可參考這里;
我們可以通過(guò)如下命令來(lái)查看當(dāng)前共享內(nèi)存中的Nginx Upstream的配置列表:
kubectl -n kube-system exec -it <NGINX-INGRESS-CONOTROLLER-POD-NAME> -- curl http://127.0.0.1:18080/configuration/backends2、同時(shí)也支持HTTPS證書(shū)的動(dòng)態(tài)更新,可通過(guò)修改nginx-ingress-controller deployment的如下參數(shù)配置來(lái)開(kāi)啟Nginx Ingress Controller的證書(shū)動(dòng)態(tài)更新:
- args:- /nginx-ingress-controller- --configmap=$(POD_NAMESPACE)/nginx-configuration- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services- --udp-services-configmap=$(POD_NAMESPACE)/udp-services- --annotations-prefix=nginx.ingress.kubernetes.io- --publish-service=$(POD_NAMESPACE)/nginx-ingress-lb- --enable-dynamic-certificates=true ### 添加該配置- --v=2當(dāng)開(kāi)啟HTTPS證書(shū)的動(dòng)態(tài)更新后,Ingress的TLS證書(shū)都統(tǒng)一維護(hù)在Nginx的共享內(nèi)存中,我們可通過(guò)如下命令來(lái)查看當(dāng)前共享內(nèi)存中配置的證書(shū)列表:
kubectl -n kube-system exec -it <NGINX-INGRESS-CONOTROLLER-POD-NAME> -- curl http://127.0.0.1:18080/configuration/certs3、進(jìn)一步地我們也支持Nginx Server和Location配置的動(dòng)態(tài)更新,可通過(guò)修改nginx-ingress-controller deployment的如下參數(shù)配置來(lái)開(kāi)啟Nginx Ingress Controller的Server和Location的動(dòng)態(tài)更新:
- args:- /nginx-ingress-controller- --configmap=$(POD_NAMESPACE)/nginx-configuration- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services- --udp-services-configmap=$(POD_NAMESPACE)/udp-services- --annotations-prefix=nginx.ingress.kubernetes.io- --publish-service=$(POD_NAMESPACE)/nginx-ingress-lb- --enable-dynamic-certificates=true ### 添加該配置- --enable-dynamic-servers=true ### 添加該配置,同時(shí)也要enable-dynamic-certificates- --v=2同樣地,當(dāng)我們開(kāi)啟了Nginx Ingress Controller的Server動(dòng)態(tài)更新后,所有Nginx Server和Location的配置都統(tǒng)一維護(hù)在共享內(nèi)存中,我們同樣可以通過(guò)如下命令來(lái)查看當(dāng)前共享內(nèi)存中的Server配置列表:
kubectl -n kube-system exec -it <NGINX-INGRESS-CONOTROLLER-POD-NAME> -- curl http://127.0.0.1:18080/configuration/servers注意說(shuō)明:當(dāng)開(kāi)啟Server的動(dòng)態(tài)更新特性后,部分Ingress Annotation配置暫不支持,正在逐步優(yōu)化支持中,相應(yīng)地您可直接通過(guò)ConfigMap方式來(lái)進(jìn)行配置;
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的通过阿里云K8S Ingress Controller实现路由配置的动态更新的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【机器学习PAI实战】—— 玩转人工智能
- 下一篇: 阿里云 MaxCompute 2018-