在升級集群時,由于集群API版本的棄用,可能需要同步對Nginx Ingress Controller進行版本升級。此外,考慮到舊版本的組件可能存在穩定性風險以及功能缺失,推薦您及時將Nginx Ingress Controller升級到最新版本。Nginx Ingress Controller使用了分階段升級的方式,需要您在升級過程中及時關注組件狀態以及業務情況,保證業務流量不會受損。
升級流程
Nginx Ingress Controller作為數據面的關鍵組件,對穩定性有較高的要求。
由于新版本對Nginx Ingress Controller所做的自定義修改較多以及升級版本跨度較大,可能會導致部分配置不兼容。而且版本跨度大引起的配置不兼容,可能不會在升級后立即暴露出來,因此,一次性將組件升級到最新版本的風險較高。
為了確保升級Nginx Ingress Controller后組件以及業務的正常運行,升級將采用分階段的形式進行。升級期間,可以對業務狀況進行檢查,有問題也能夠及時回滾。
第一部分:前置檢查
前置檢查將會在組件升級開始之前自動進行,以檢查組件當前狀態是否滿足升級條件。如果組件存在不滿足升級條件的設置,或者處于不健康狀態時,將無法通過健康檢查,在完成問題的手動修復之前,無法繼續進行升級。
第二部分:驗證階段
驗證階段會擴容出1個新版本組件的Pod,驗證新版本組件的運行狀態以及Ingress規則是否符合預期。擴容成功后,一部分流量將會進入該Pod,此時可以通過容器日志、SLS日志服務或阿里云Prometheus監控服務來查看流量是否有異常。
驗證Pod擴容成功后,升級流程會被暫停。在確認組件和業務無異常后,即可手動確認繼續進行下一階段。若此時出現問題,也可以選擇回滾,刪除新版本Pod,終止升級流程。
該步是通過修改Deployment中的spec.minReadySeconds
和spec.strategy
字段實現的。
第三部分:發布階段
發布階段將會進行完整的滾動升級流程,將舊版本組件完全替換為新版本。在所有Pod更新完成后,升級流程會暫停,此時可以對組件和業務做最終的確認。當確認無誤后,升級結束。若此時出現問題,也可以選擇回滾,將所有Pod重置回舊版本,并結束升級流程。
第四部分:回滾(可選)
在驗證階段或者發布階段后的暫停過程中,如果發現組件或業務出現異常,可以通過回滾來將組件恢復到升級前的初始狀態。
升級前須知
在組件升級前,請確保擁有對業務流量的監控手段,以便及時發現問題。您可以通過SLS日志服務或阿里云Prometheus服務來查看業務流量狀況。以上兩種觀測手段的配置,請參見Nginx Ingress訪問日志分析與監控和使用阿里云Prometheus監控。
請確認目前組件健康狀態正常,Pod均為Ready狀態,沒有錯誤日志。
請確認沒有使用HPA等自動擴縮容規則。如存在,請提前刪除,在升級完成后將其恢復。
請確認LoadBalancer Service狀態正常,沒有異常事件透出。
在組件升級過程中,請勿對組件以及Ingress規則進行任何修改。
如果您的Nginx Ingress低于v0.44版本,在升級到高版本時,需要注意前綴匹配的差異,詳細信息請參見升級注意事項。
組件升級將采用灰度升級的方式,首先會創建一個升級目標版本的Nginx Ingress Pod實例。在經過流量驗證確認無誤后,單擊確認將觸發滾動更新。請確保集群中有足夠的可調度節點,以便Nginx Ingress Pod能夠正常創建和調度。
操作步驟
登錄容器服務管理控制臺,在左側導航欄選擇集群。
在集群列表頁面,單擊目標集群名稱,然后在左側導航欄,選擇 。
在組件管理頁面,找到Nginx Ingress Controller組件,單擊組件右下方的升級。
在彈出的升級界面中,單擊開始并確認,開始升級流程。
說明您可以在升級過程中的任何時間點退出該頁面,然后通過單擊組件管理頁面中的升級進度重新回到流程中。
流程的第一階段需要進行前置檢查。在完成前置檢查后,流程會自動進入下一階段。
若前置檢查不通過,可以通過前置檢查下的查看詳情跳轉到檢查報告頁面。然后根據未通過的檢查點排查問題,詳細信息,請參見前置檢查說明。問題解決后,可以單擊重試以重新開始升級流程。
驗證階段完成后,升級流程進入暫停狀態。此時,需要對組件運行狀態和業務狀態進行驗證。關于驗證方法,請參見驗證階段說明。
若出現擴容不成功的情況,請參見驗證和發布階段Pod擴容失敗怎么辦?。也可以在集群中查看Pod啟動失敗的具體原因,并在解決之后單擊重試,重試該階段。
若驗證業務出現問題,可以通過單擊回滾進行回滾操作。回滾完成后,該升級流程將會結束,可以從組件管理中單擊升級重新開始。
驗證階段確認一切正常后,單擊繼續進入發布階段。發布階段滾動更新完成后,升級流程進入暫停狀態。此時,需要對組件和業務狀態進行最后一次確認。若業務驗證出現問題,可以通過單擊回滾進行回滾操作。回滾完成后,升級流程將會結束,可以從組件管理中單擊升級重新開始。
確認組件運行狀態和業務狀態均沒有異常后,單擊繼續結束升級流程。
說明請控制整個升級流程的總時間不要超過一周。
前置檢查說明
前置檢查表
檢查項 | 檢查內容 | 異常處理 |
Deployment存在 | 組件的Deployment(kube-system/nginx-ingress-controller)存在。 | - |
Deployment健康 | 組件的Deployment所控制的Pod全部處于Ready狀態,且不處于滾動更新中等不穩定狀態。 | - |
Pod錯誤日志 | 檢查Pod中最近200條日志,其中不存在Error或者Fatal級別的錯誤日志。 | 如果有日志存在,說明組件近期可能因為配置錯誤等原因出現異常報錯,需要在問題解決后重新進行升級流程。根據日志解決問題,請參見Nginx Ingress異常問題排查。 |
LoadBalancer Service健康 | 首先檢查Nginx Ingress Controller所對應的LoadBalancer Service(kube-system/nginx-ingress-lb)是否存在。如果存在,會進一步檢查該Service是否存在任何錯誤事件。 請注意,Service不存在也會被認為該Service存在Warning事件。 | 當Service不存在時,請參考使用須知及高危風險操作說明文檔中 “在安裝Nginx Ingress Controller組件的情況下手動刪除 kube-system命名空間下的 Service存在但被檢查出異常事件時,可以根據事件內容尋找解決方案,詳細信息,請參見Service異常事件及處理方式。當Service不為LoadBalancer時,該項檢查會被跳過。 |
HPA | 組件Deployment沒有使用HPA。使用HPA時,在組件升級過程中,可能會因為HPA的自動擴縮容策略導致升級狀態被打亂。 | 在升級過程中,需要將HPA資源從集群中刪除,升級完成后,再重新啟用。 |
Deployment模板 | 組件的Deployment模板只能存在兼容的修改。 | 您之前對Nginx Ingress Controller Deployment所做的某些自定義配置或修改,在升級過程中可能無法自動保留。
上述模板更改不會導致檢查不通過。除此之外,無論是私自修改模板還是版本過舊、不符合升級條件,都會造成升級過程中的檢查環節無法通過,進而影響升級的成功率。常見的檢查不通過的原因如下:
如果Deployment模板檢查失敗,您可以通過手動還原模板的方法解決該問題。具體操作,請參見Deployment模板檢查不通過。 |
Ingress配置 | 集群內的Ingress只存在兼容的特性。 | 如果集群內的Ingress中使用了不兼容的特性,升級后可能會導致業務無法正常轉發流量,從而導致不可用的問題。確認及修改問題,請參見下方升級兼容性說明。 |
組件配置 | 組件ConfigMap(kube-system/nginx-configuration)中存在不兼容的配置 | 如果集群內ConfigMap中使用了不兼容的特性,升級后可能會導致業務無法正常轉發流量,從而導致不可用的問題。確認及修改問題,請參見下方升級兼容性說明。 |
升級兼容性說明
在組件的開發和維護過程中,Nginx Ingress Controller組件的新版本可能會引入新的功能、改進現有功能或者修復安全問題,但同時也可能因為內部架構的調整、依賴庫的變化等原因,導致與之前版本存在兼容性差異。關于Nginx Ingress Controller的變更記錄,請參見Nginx Ingress Controller。
snippet注解默認禁用
影響版本:v1.9.3-aliyun.1以下(不包括v1.9.3-aliyun.1)。
由于安全原因,自v1.9.3-aliyun.1版本起,Nginx Ingress Controller將默認禁用所有snippet注解,可能包括:
nginx.ingress.kubernetes.io/configuration-snippet
nginx.ingress.kubernetes.io/server-snippet
nginx.ingress.kubernetes.io/stream-snippet
nginx.ingress.kubernetes.io/auth-snippet
nginx.ingress.kubernetes.io/modsecurity-snippet
出于安全和穩定性風險的考慮,建議您優先使用相關注解或者設置項來實現所需功能。
如您仍需要使用snippet注解能力,請在充分評估風險后,通過在ConfigMapkube-system/nginx-configuration
中添加allow-snippet-annotations: "true"
手動開啟注解功能。
不支持較低版本的TLS
影響版本:v1.7.0-aliyun.1以下(不包括v1.7.0-aliyun.1)。
由于TLS1.1及以下版本存在安全問題,Nginx Ingress Controller新版本不再默認支持TLS v1.1和TLS v1.0的加密方式。因此,在升級前,請確保您的業務不依賴v1.1及以下版本的TLS,并且在配置中將其移除。修改ConfigMap后會立即生效。
例如,若Nginx Ingress Controller組件的ConfigMap(kube-system/nginx-configuration)配置如下所示:
ssl-protocols: SSLv3 SSLv2 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3
您需要在確認業務不受影響后,可直接將該行設置移除,使用默認選項;或者選擇移除SSLv3、SSLv2、TLSv1、TLSv1.1四項,改為:
ssl-protocols: TLSv1.2 TLSv1.3
若您需要強制使用舊版本的TLS加密方式,請參見Ingress支持哪些SSL/TLS版本?進行配置。
nginx.ingress.kubernetes.io/rewrite-target用法不兼容
影響版本:0.22.0以下(不包括0.22.0)。
0.22.0版本對
nginx.ingress.kubernetes.io/rewrite-target
注解的用法做了修改。在0.22.0及以上版本,使用rewrite-target
時,需要顯式指定捕獲組的使用。0.22.0版本以下的rewrite-target特性和最新版本的rewrite-target特性不兼容,在組件升級前,可以使用
configuration-snippet
代替rewrite-target
注解。
例如,在0.22.0以下版本,規則為:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- path: /something/
pathType: Prefix
backend:
service:
name: http-svc
port:
number: 80
- path: /something123/
pathType: Prefix
backend:
service:
name: http-svc-1
port:
number: 80
需修改為:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# 使用rewrite指令,/something為path中路徑(不包含尾部的斜杠)。
# Ingress中包含多個路徑,需要添加多條rewrite指令。
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite "(?i)/something(/|$)(.*)" /$2 break;
rewrite "(?i)/something123(/|$)(.*)" /$2 break;
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- path: /something/ # 和舊版本Ingress資源的路徑保持一致。
pathType: Prefix
backend:
service:
name: http-svc
port:
number: 80
- path: /something123/ # 和舊版本Ingress資源的路徑保持一致。
pathType: Prefix
backend:
service:
name: http-svc-1
port:
number: 80
修改為上述格式后,即可正常進行升級流程。升級完成后,將Ingress修改為新版的用法即可。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# 引用匹配的內容。
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
# 使用捕獲組。
- path: /something(/|$)(.*)
pathType: Prefix
backend:
service:
name: http-svc
port:
number: 80
# 使用捕獲組。
- path: /something123(/|$)(.*)
pathType: Prefix
backend:
service:
name: http-svc-1
port:
number: 80
驗證階段說明
驗證組件及業務狀態
除自身所擁有的業務監控能力外,ACK也提供了SLS日志、阿里云Prometheus大盤和容器自身的日志來觀測Nginx Ingress Controller的運行狀態。開啟上述服務,請參見Nginx Ingress訪問日志分析與監控和使用阿里云Prometheus監控。
SLS日志服務
您可以在容器服務控制臺查看通過SLS收集的日志。
登錄容器服務管理控制臺,在左側導航欄單擊集群。
在集群列表頁面,單擊目標集群名稱,然后在左側導航欄,選擇
。選擇應用日志頁簽,在日志庫下拉框中選擇nginx-ingress,單擊選擇日志庫。
說明若您的日志庫中沒有nginx-ingress條目,請確認是否配置了組件的日志收集功能。詳細信息,請參見Nginx Ingress訪問日志分析與監控。
在展示的日志中,可以看到應用的訪問日志,也可以在查詢語句中指定對應的Pod(如新版本組件的Pod)來只查看該Pod的訪問日志。需要注意新Pod的請求成功率是否異常,以及請求數對比舊Pod是否一致。若數據差距較大,可選擇回滾操作。
當請求沒有命中任何Ingress規則,返回404時,默認將不會記錄訪問日志。
阿里云Prometheus大盤
您可以通過阿里云Prometheus服務提供的大盤,來觀測組件整體的請求情況。
登錄容器服務管理控制臺,在左側導航欄單擊集群。
在集群列表頁面,單擊目標集群名稱,然后在左側導航欄,選擇
。單擊網絡監控頁簽,然后單擊集群ingress流量監控。
說明若監控中沒有集群ingress流量監控,請確認是否配置了組件的Prometheus Metrics搜集功能。詳細信息,請參見使用阿里云Prometheus監控。
在大盤中可以看到Ingress的各項運行指標,也可以通過選擇對應的Pod來查看該Pod的指標。同樣,需要注意的是新的Pod請求成功率是否有異常,以及請求數與舊Pod是否一致。若數據差距較大,可選擇回滾操作。
Ingress規則中沒有指定Host(默認為通配符“*”)的規則默認不會記錄Metrics。
Pod日志
您可以通過kubectl,以命令行的形式訪問Pod日志,來查看是否存在錯誤。
執行以下命令,查看Pod中Nginx的錯誤日志,包括warn、error和crit三個級別。
kubectl logs -n kube-system <Pod名稱> | grep -e warn -e error -e crit
執行以下命令,查看Pod中Controller的錯誤日志。
kubectl logs -n kube-system <Pod名稱> | grep "^[EF]"
升級注意事項
在低版本的Nginx Ingress Controller升級到高版本時,由于高版本在前綴匹配邏輯上有所變化,需要關注路徑path
配置與實際請求URL的是否一致,否則可能會導致原本正常的請求出現404錯誤。
已知問題
在Nginx Ingress Controller的不同版本中,前綴匹配邏輯可能存在差異,這可能導致服務訪問問題。
在低版本(v0.44之前)的Nginx Ingress Controller中,前綴匹配的規則較為寬松,允許如
/aaa/bbb
的配置,可以匹配請求的URL/aaa/bbbbb
。升級到高版本后,前綴匹配的邏輯可能會變得更加嚴格,只匹配精確的請求路徑,這可能導致原本應匹配的路徑
/aaa/bbbbb
不再匹配,從而引發404錯誤。
影響范圍
受影響的版本為Nginx Ingress版本低于v0.44。關于Nginx Ingress Controller版本記錄,請參見Nginx Ingress Controller。相關PR信息請參見kubernetes/ingress-nginx #6443。
示例配置
您可以根據以下的YAML配置比較低版本(如v0.22.0.5-552e0db-aliyun)和高版本(如v1.2.1-aliyun.1+)渲染出Nginx配置之間的差異。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
labels:
ingress-controller: nginx
name: test
namespace: default
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- backend:
service:
name: api-resources-svc
port:
number: 8080
path: /api/resource
低版本行為
在低版本Nginx Ingress(如v0.22.0.5-552e0db-aliyun)中,對應的Nginx配置:
Location /api/resource ## 沒有結尾的 "/"
在上面的配置中,使用的路徑
/api/resource
在低版本Nginx中允許通過http://www.example.com/api/resources
進行訪問。說明實際訪問路徑是resources而不是resource。
高版本行為
若將Nginx Ingress Controller升級到高版本(如v1.2.1-aliyun.1+),對應的Nginx配置:
Location /api/resource/ # 增加了結尾的 "/" { } ... Location = /api/resource # 增加了一個 Location 進行精確匹配 { }
訪問
http://www.example.com/api/resources
將返回404錯誤。
常見問題
Nginx Ingress Controller是否支持升級至指定的版本?升級成功后,還能回退到之前的某個版本嗎?
Nginx Ingress Controller組件不支持升級到指定版本,采用分階段的形式進行升級,直至將組件升級到最新的版本。升級成功后無法回退。
驗證和發布階段Pod擴容失敗怎么辦?
問題原因 | 解決方案 |
新版本Pod啟動時出現錯誤(如配置加載失敗等),導致一直處于crash狀態。 | 根據上方Pod日志部分提供的方法,查看對應Pod錯誤日志。定位及解決問題,請參見Nginx Ingress異常問題排查。 |
常見于使用專屬節點部署Nginx Ingress Controller的情況。當新的Pod擴容時,會因為所配置的資源限制和節點選擇器,導致無可用節點能夠調度新的Pod。 | 臨時擴容節點,或在業務低峰期縮容Nginx Ingress Controller再進行升級,使得在升級時Pod能夠正常調度。 |
Deployment模板檢查不通過怎么辦?
如果在前置檢查過程中,您的Deployment模板檢查不通過,請單擊異常原因右側的鏈接,進入組件差異展示頁面,查看檢查不通過的字段。
在Nginx Ingress Controller 組件升級頁面的前置檢查下方,單擊查看詳情。
在檢查報告頁面的集群組件檢查結果區域,單擊①處的紅色方框查看檢查結果,然后在檢查結果頁面單擊Deployment 模板,最后單擊②處異常原因右側的鏈接。
進入組件差異展示頁面,查看檢查不通過的字段。
在組件差異頁面,會展示出該版本組件的標準模板(左側)和當前集群中的組件模板(右側)的對比展示。組件差異頁面會標出兩者之間的全部差異,包括兼容和不兼容的字段,并在差異展示的下方標出集群中組件是否通過差異檢查,以及不兼容的差異字段的具體路徑。
如下圖所示,下方提示存在一處差異,差異字段為.spec.template.spec.containers.(nginx-ingress-controller).args(括號中的內容為數組中元素的name字段)。通過組件差異對比,發現args中
--v=2
被修改為了--v=3
,需要在升級前進行修正。修改差異字段。
選擇工作負載>無狀態,找到Nginx Ingress Controller組件,單擊更多>查看YAML,在編輯YAML頁面中將args字段中的
--v=3
修改為--v=2
。將差異字段修改后,您也可以重新進入或刷新組件差異展示頁面,查看最新的對比結果。當頁面底部提示組件可通過差異檢測時,即可通過Deployment模板檢查點。
說明修改集群內Deployment過程中,Nginx Ingress Controller Pod會重啟,建議您在業務低峰期進行相關操作。
相關文檔
如需了解Nginx Ingress Controller組件的變更記錄,請參見Nginx Ingress Controller。
如果在使用Nginx Ingress Controller組件過程中出現網絡不通等問題,請優先查閱文檔解決。詳細信息,請參見配置集群安全組、Nginx Ingress FAQ。