# 集群外部访问Ingress不通
Ingress基于七层的HTTP和HTTPS协议进行转发，是集群流量的入口，可以通过域名和路径对访问做到更细粒度的划分。集群在添加Ingress后，可能会出现无法正常访问的情况，本文提供添加Ingress失败或无法正常访问的通用排查思路，帮助您找到问题所在。在进行Ingress问题排查前，请您阅读以下几点须知，并进行自检。
![](https://support.huaweicloud.com/cce_faq/public_sys-resources/notice_3.0-zh-cn.png)
- 如创建Ingress过程中指定了host地址，将无法通过IP访问。
- 请检查集群的节点安全组，确认30000-32767范围内的业务端口在入方向对所有网段放开。
 
#### 排查思路
本文提供了Ingress外部访问异常排查全景图，如[图1]所示，帮助您由浅入深地排查Ingress访问异常问题。
图1Ingress访问异常排查全景图   
![](https://support.huaweicloud.com/cce_faq/zh-cn_image_0000001394212509.png "点击放大")
1. **[检查异常是否由Ingress引起]** 。
   首先需要确认问题是否由Ingress导致的，因此需要确保外部域名解析正常、安全组规则正确，且Ingress对应的Service和工作负载工作正常。
   
2. **[检查Ingress状态是否正常]** 。
   在Service和工作负载都正常的情况下，需要保证Ingress依赖的ELB状态正常。如果是Nginx型的Ingress，还需要保证nginx-ingress插件的状态是正常的。
   
3. **[检查Ingress配置是否正确]** 。
   如果以上排查结果都正常，说明可能是Ingress的配置出现问题。
   - 检查对接ELB参数是否填写正确。
   
   - 检查Service参数是否填写正确。
   
   - 检查转发配置的参数是否填写正确。
     
4. **[检查证书问题]** 。
   如果Ingress开启了HTTPS访问，还需要排除证书配置错误的问题。您可使用相同ELB创建一个HTTP协议的Ingress访问，如HTTP协议下访问正常，则说明HTTPS协议证书可能存在问题。
   
5. 如果以上排查均无效果，请进行抓包分析，或提交工单寻求帮助。
 
 #### 检查异常是否由Ingress引起
您需要确认访问异常是否由Ingress引起，当存在域名解析异常、安全组规则错误、Service异常或工作负载本身异常时，都可能会引起Ingress访问不通。
以下排查顺序遵从由外到内的规则：
1. 检查域名解析或安全组规则是否正常，排除集群外部可能存在的问题。 
   1. 执行以下命令检查域名在权威DNS的解析是否生效。
      ```
      nslookup -qt=类型 域名 权威DNS地址
      ```
      
   
   2. 检查集群节点安全组规则，确认30000-32767范围内的业务端口在入方向对所有网段放开。如需对安全组进行加固，详情请参见[如何修改集群安全组规则配置](https://support.huaweicloud.com/cce_faq/cce_faq_00265.html)。
      ![](https://support.huaweicloud.com/cce_faq/zh-cn_image_0000001393933001.png "点击放大")
      
   
   
   
   
2. 检查Service是否可以正常访问容器内业务，检查集群内部可能存在的问题。 
   您可通过在集群中新建Pod并通过ClusterIP访问Service的方式进行检查，如您的服务为NodePort类型，也可通过EIP:Port使用互联网访问服务来验证。
   1. 通过kubectl连接集群，查询集群内服务。
      ```
      # kubectl get svc
      NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
      kubernetes   ClusterIP   10.247.0.1       <none>        443/TCP        34m
      nginx        ClusterIP   10.247.138.227   <none>        80/TCP         30m
      ```
      
   
   2. 创建一个Pod并登录到容器内。
      ```
      kubectl run -i --tty --image nginx:alpine test --rm /bin/sh
      ```
      
   
   3. 使用curl命令访问Service的ClusterIP:Port，检验集群内服务是否可访问。
      ```
      curl 10.247.138.227:80
      ```
      如Service可正常访问，则说明后端工作负载状态正常，初步可认定异常由Ingress引起，请参照[检查Ingress状态是否正常]继续排查。
      如Service访问异常，则需继续排查工作负载状态，确定异常原因。
      
    
   
   
3. 检查工作负载状态是否正常。 
   如工作负载正常，但Service无法正常访问，则说明异常可能是由于Service引起。请检查Service的配置，例如容器端口是否正确填写为容器内业务开放端口。
   如工作负载正常，但访问结果不符合预期，请排查容器内运行的业务代码。
   
   
 
 #### 检查Ingress状态是否正常
CCE支持两种类型的Ingress，其中Nginx类型的Ingress Controller由社区开源的插件提供，需要在集群中安装插件自行运维；而ELB型的Ingress Controller运行在master节点上，由专门的华为云团队负责运维，无需用户保证。
1. 如果您使用Nginx类型的Ingress，需要在集群中安装nginx-ingress插件。如果您使用ELB型的Ingress，则无需检查此步骤。 
   前往"插件中心"查看nginx-ingress插件的状态为"运行中"。请保证集群下节点资源充足，若资源不足，插件实例将无法调度。
   
   
2. 前往ELB控制台检查ELB的状态。 
   - ELB型Ingress 访问端口可自定义，请检查ELB侧创建的监听器和后端服务器组未被删除或修改。
     建议您在创建ELB型Ingress时通过控制台选择自动创建ELB，并且不要对自动创建的ELB进行修改，能够有效避免ELB侧导致的Ingress异常。
     
   
   - Nginx型Ingress 访问端口固定为80和443，不支持自定义端口。安装nginx-ingress插件将同时占用80和443端口，切勿删除，否则只能通过重装插件解决。
     
   
   
   您也可以通过错误码来简单判断故障是否由于ELB引起，如下图页面所示，说明该异常大概率由ELB侧故障引起，需要重点排查。
   ![](https://support.huaweicloud.com/cce_faq/zh-cn_image_0000001393972657.png "点击放大")
   
   
 
 #### 检查Ingress配置是否正确
如果以上排查项都正常，需要考虑是否由于参数设置引起异常。由于使用kubectl创建时需要填写的参数较多易出错，建议您使用控制台创建，根据可视界面按需设置参数，自动过滤不符合要求的负载均衡及Service，能够有效避免出现关键参数格式错误或缺失的问题。
请您根据以下思路进行逐一排查Ingress配置：
- **检查对接ELB参数是否正确**
  由于ELB通过annotations字段下的参数进行定义，但是K8s在创建资源时并不会对annotations字段参数进行校验，如果出现关键参数错误或缺失，Ingress资源也可被创建，但无法正常访问。
  以下是出现频率较高的问题，供您参考：
  - 对接的目标ELB未与集群处于**同一VPC**下。
  
  - 添加ELB型Ingress时对接已有ELB，annotations中关键字段**kubernetes.io/elb.id** 、**kubernetes.io/elb.ip** 、**kubernetes.io/ingress.class** 、**kubernetes.io/elb.port**缺失。
  
  - 添加Nginx型Ingress时，**未安装nginx-ingress插件**导致无ELB连接。
  
  - 添加Nginx型Ingress时，**kubernetes.io/elb.port**参数不支持自定义端口，使用HTTP协议固定为80，HTTPS协议固定为443。
   
- **检查Service配置是否正确**
  - 检查Ingress对接的Service类型是否正确，Ingress支持的Service如下。
    表1ELB Ingress支持的Service类型 
    | 集群类型            | ELB类型    | 集群内访问（ClusterIP） | 节点访问（NodePort） |
    |:---|:---|:---|:---|
    | CCE Standard集群 | 共享型负载均衡  | 不支持               | 支持             |
    | CCE Standard集群 | 独享型负载均衡 | 不支持                  | 支持              |
    | CCE Turbo集群    | 共享型负载均衡     | 不支持               | 支持              |
    | CCE Turbo集群    | 独享型负载均衡    | 支持               | 支持              |
       
    表2Nginx Ingress支持的Service类型 
    | 集群类型            | ELB类型       | 集群内访问（ClusterIP） | 节点访问（NodePort） |
    |:---|:---|:---|:---|
    | CCE Standard集群 | 共享型负载均衡   | 支持               | 支持              |
    | CCE Standard集群 | 独享型负载均衡 | 支持              | 支持            |
    | CCE Turbo集群     | 共享型负载均衡    | 支持               | 支持             |
    | CCE Turbo集群     | 独享型负载均衡  | 支持               | 支持              |
       
    
  
  - 检查Service的访问端口号是否正确，此处Service的访问端口号（port字段）需区别于容器端口号（targetPort字段）。
   
- **检查转发配置的参数是否填写正确**
  - 添加的URL转发路径要求后端应用内存在相同的路径，否则转发无法生效。 例如，Nginx应用默认的Web访问路径为"/usr/share/nginx/html"，在为Ingress转发策略添加"/test"路径时，需要应用的Web访问路径下也包含相同路径，即"/usr/share/nginx/html/test"，否则将返回404。
    ![](https://support.huaweicloud.com/cce_faq/public_sys-resources/note_3.0-zh-cn.png)
    使用Nginx型的Ingress Controller时，您可通过在annotations字段添加rewrite注释进行重定向，将业务内不存在的path路径进行重写，避免访问路径不存在的错误，详情请参见[Rewrite](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rewrite)。
    
  
  - 创建Ingress时指定了域名（host），将无法通过IP访问。
   
 
 #### 检查证书问题
CCE的Ingress密钥证书类型为IngressTLS或kubernetes.io/tls，若证书类型不正确，创建的Ingress将无法在ELB侧建立监听器，导致Ingress访问异常。
1. 首先去除YAML中关于HTTPS的参数，尝试创建HTTP类型的Ingress是否可正常访问。 
   如HTTP访问正常，则考虑HTTPS密钥证书是否存在问题。
   
   
2. 排除密钥类型错误。检查密钥类型是否为**IngressTLS或kubernetes.io/tls类型** 。
   
   ```
   kubectl get secret
   ```
   回显如下：
   ```
   NAME                  TYPE                                  DATA   AGE
   ingress               IngressTLS                            2      36m
   ```
   
   
3. 创建测试证书，排除证书问题。 
   ```
   openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN={YOUR_HOST}/O={YOUR_HOST}"
   ```
   
   
4. 使用测试的私钥证书tls.key和tls.crt创建正确类型的密钥，并重新创建HTTPS类型的Ingress测试是否可以正常访问。本文以创建IngressTLS类型密钥为例。 
   通过kubectl方式创建时，创建IngressTLS类型密钥的示例如下：
   ```
   kind: Secret
   apiVersion: v1
   type: IngressTLS
   metadata:
     name: ingress
     namespace: default
   data:
     tls.crt: LS0tLS1CRU*****FURS0tLS0t
     tls.key: LS0tLS1CRU*****VZLS0tLS0=
   ```
   ![](https://support.huaweicloud.com/cce_faq/public_sys-resources/note_3.0-zh-cn.png)
   此处tls.crt和tls.key为示例，请获取真实密钥进行替换。tls.crt和tls.key的值为Base64加密后的内容。
   
   
 
