在升级集群时,由于集群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以下版本,规则为:
需修改为:
修改为上述格式后,即可正常进行升级流程。升级完成后,将Ingress修改为新版的用法即可。
验证阶段说明
验证组件及业务状态
除自身所拥有的业务监控能力外,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。