
# NGINX Ingress控制器插件升级导致集群内Nginx类型的Ingress路由访问异常
#### 问题现象
集群中存在未指定Ingress类型（annotations中未添加kubernetes.io/ingress.class: nginx）的Nginx Ingress路由，NGINX Ingress控制器插件从1.x版本升级至2.x版本后，服务中断。
#### 问题自检
针对Nginx类型的Ingress资源，查看对应Ingress的YAML，如Ingress的YAML中未指定Ingress类型，并确认该Ingress由Nginx Ingress Controller管理，则说明该Ingress资源存在风险。
1. 获取Ingress类别。 
   您可以通过如下命令获取Ingress类别：
   ```
   kubectl get ingress <ingress-name> -oyaml | grep -E ' kubernetes.io/ingress.class: | ingressClassName:' -B 1
   ```
   - 故障场景：如果上述命令输出为空，说明Ingress资源未指定类别。
   
   - 正常场景：Ingress已通过annotations或ingressClassName指定其类别，即存在输出。 ![](https://support.huaweicloud.com/cce_faq/zh-cn_image_0000001659509288.png "点击放大")
     
    
   
   
2. 确认该Ingress被Nginx Ingress Controller纳管。如果使用ELB类型的Ingress则无此问题。
   
   - 1.19集群可通过managedFields机制确认。
     ```
     kubectl get ingress <ingress-name> -oyaml | grep 'manager: nginx-ingress-controller'
     ```
     如果回显信息中包含"manager: nginx-ingress-controller"，表示已被纳管。
     ![](https://support.huaweicloud.com/cce_faq/zh-cn_image_0000001707906733.png "点击放大")
     
   
   - 其他版本集群可通过Nginx Ingress Controller Pod的日志确认。
     ```
     kubectl logs -nkube-system cceaddon-nginx-ingress-controller-545db6b4f7-bv74t | grep 'updating Ingress status'
     ```
     其中，*cceaddon-nginx-ingress-controller-545db6b4f7-bv74t*为Nginx控制器Pod名称。如果回显中看到类似 "updating Ingress status" namespace="default" ingress="your-ingress-name"的信息，表示已被纳管。
     ![](https://support.huaweicloud.com/cce_faq/zh-cn_image_0000001659507340.png "点击放大")
     
   
   
   若通过上述两种方式仍然无法确认，请联系技术支持人员。
   
   
 
#### 解决方案
为Nginx类型的Ingress添加注解，方式如下：
```
kubectl annotate ingress <ingress-name> kubernetes.io/ingress.class=nginx
```
![](https://support.huaweicloud.com/cce_faq/public_sys-resources/notice_3.0-zh-cn.png)
ELB类型的Ingress无需添加该注解，请[确认]该Ingress被Nginx Ingress Controller纳管。
#### 问题根因
NGINX Ingress控制器插件基于开源社区Nginx Ingress Controller的模板与镜像。
对于社区较老版本的Nginx Ingress Controller来说（社区版本v0.49及以下，对应CCE插件版本v1.x.x），在创建Ingress时没有指定Ingress类别为nginx，即annotations中未添加kubernetes.io/ingress.class: nginx的情况，也可以被Nginx Ingress Controller纳管。详情请参见[社区代码](https://github.com/kubernetes/ingress-nginx/blob/0a2ec01eb4ec0e1b29c4b96eb838a2e7bfe0e9f6/internal/ingress/annotations/class/main.go#L50)。
但对于较新版本的Nginx Ingress Controller来说（社区版本v1.0.0及以上，对应CCE插件版本2.x.x），如果在创建Ingress时没有显示指定Ingress类别为nginx，该资源将被Nginx Ingress Controller忽略，Ingress规则失效，导致服务中断。详情请参见[社区代码](https://github.com/kubernetes/ingress-nginx/blob/f207702c3080d679ae86307eafbc16b0d3098e6c/internal/ingress/controller/store/store.go#L830)。
社区相关PR链接为：<https://github.com/kubernetes/ingress-nginx/pull/7341>
目前有两种方式指定Ingress类别：
- 通过annotations指定，为Ingress资源添加annotations（kubernetes.io/ingress.class: nginx）。
- 通过spec指定，.spec.ingressClassName字段配置为nginx。但需要配套具有IngressClass资源。
示例如下：
```
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  ingressClassName: nginx
  rules:
    …
status:
  loadBalancer: {}
```
