文档首页> 云容器引擎 CCE> 常见问题> 网络管理> 网络异常> 添加Ingress失败或无法正常访问
更新时间:2022-05-06 GMT+08:00
分享

添加Ingress失败或无法正常访问

Ingress基于七层的HTTP和HTTPS协议进行转发,是集群流量的入口,可以通过域名和路径对访问做到更细粒度的划分。集群在添加Ingress后,可能会出现无法正常访问的情况,本文提供添加Ingress失败或无法正常访问的通用排查思路,帮助您找到问题所在。

排查思路

Ingress作为集群流量的分发器,是连接负载均衡器和容器内业务的桥梁。在进行Ingress问题排查前,请您阅读以下几点须知,并进行自检。
  • 如使用Nginx型Ingress,请确认已安装nginx-ingress插件。
  • 如Ingress中指定了host地址,将无法通过IP访问,非问题,请知悉。

通过Kubectl创建Ingress是问题出现最多的场景,这里提供了几个重点排查项供您参考,帮助您快速找到根因。

图1 Ingress异常排查思路

排查项一:Ingress资源必需参数是否正确

如您通过YAML文件添加Ingress,首先考虑是否由于参数设置引起异常。Ingress通过annotations字段下的参数进行定义,K8s在创建资源时并不会对annotations字段参数进行校验,如果出现关键参数错误或缺失,Ingress资源也可被创建,但无法正常访问。

主要的高频错误有如下几项供您参考:
  • 对接ELB失败
    • 对接的目标ELB未与集群处于同一VPC下。
    • 添加ELB型Ingress时对接已有ELB,annotations中关键字段kubernetes.io/elb.idkubernetes.io/elb.ipkubernetes.io/ingress.classkubernetes.io/elb.port缺失。
    • 添加Nginx型Ingress时,未安装nginx-ingress插件导致无ELB连接。
    • 添加Nginx型Ingress时,annotations中关键字段kubernetes.io/ingress.classkubernetes.io/elb.port缺失。
    • 添加Nginx型Ingress时,kubernetes.io/elb.port参数不支持自定义端口,使用HTTP协议固定为80,HTTPS协议固定为443。
  • 对接后端Service失败
    • Ingress对接的Service类型错误,Ingress支持的Service请参见表1
      表1 Ingress支持的Service类型

      Ingress类型

      访问类型

      集群内访问(ClusterIP)

      节点访问(NodePort)

      ELB型Ingress

      负载均衡路由

      不支持

      支持

      ENI负载均衡路由

      支持

      不支持

      Nginx型Ingress

      负载均衡路由

      支持

      支持

      ENI负载均衡路由

      支持

      不支持

解决措施:

如通过Kubectl添加Ingress,请根据常见错误项进行检查,并检查关键参数是否存在填写错误的情况。若异常依旧无法排除,建议重新创建Ingress,确认基础功能可用后再添加自定义的高级功能。

建议通过CCE控制台添加Ingress,根据可视界面按需设置参数,自动过滤不符合要求的负载均衡及Service,能够有效避免出现关键参数格式错误或缺失的问题。

排查项二:Service后端容器端口是否正确

通过YAML创建Ingress时,需要正确填写目标Service名称及访问端口,然后确认Service中的容器端口是正确配置的,即Service可正常访问容器内业务。

通过CCE控制台添加Ingress时,将筛选符合要求的目标Service并自动填充对应的Service访问端口,您只需确认Service可正常访问容器内业务。

解决措施:

您需要确认Service中正确填写了容器内应用的暴露端口,在集群内的容器或节点上能够正常访问。可通过以下步骤进行检验。

  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并登录到容器内,使用curl命令访问Service的IP:Port,检验集群内服务是否可访问。

    # kubectl run -i --tty --image nginx:alpine test --rm /bin/sh
    If you don't see a command prompt, try pressing enter.
    / # curl 10.247.138.227:80
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

  3. 如无法正常访问,则需进一步检查Service中的容器端口是否正确,或容器内业务是否正常运行。

排查项三:容器内业务是否存在相应路径

Ingress进行转发时支持设置不同的访问路径,需要注意的是该访问路径是目标容器内业务真实暴露的路径,如业务不存在对应路径,访问结果将返回404错误,无法找到对应的内容。

解决措施一:

确认容器内业务拥有相应的路径,将Ingress中的path修改为目标业务中真实存在的路径。

解决措施二(仅使用nginx-ingress插件支持):

Nginx型的Ingress Controller支持重定向,可通过在annotations字段添加rewrite注释,将业务内不存在的path路径进行重写,避免访问路径不存在的错误。

YAML示例如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-test
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: ''
      http:
        paths:
          - path: /.*
            backend:
              serviceName: <your_service_name>  #替换为您的目标服务名称
              servicePort: 80

示例中,path路径“/.*”为正则表达式,表示匹配任意值,可将任意路径重写为根路径“/”,例如用户访问“http://**.**.**/test”时,将被自动重定向至“http://**.**.**/”,即使业务内不存在“/test”路径也可以正常访问。

排查项四:使用HTTPS时密钥证书是否正确

CCE的Ingress密钥证书类型为IngressTLS,若证书类型不正确,创建的Ingress将无法在ELB侧建立监听器,导致Ingress访问异常。

解决措施:

  1. 首先去除YAML中关于HTTPS的参数,尝试创建HTTP类型的Ingress是否可正常访问,确认Ingress的annotations字段参数和Service没有问题。

    如HTTP访问正常,则考虑HTTPS密钥证书是否存在问题。

  2. 排除密钥类型错误。检查密钥类型是否为IngressTLS类型

    # 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创建IngressTLS类型的密钥,测试是否可以正常访问。

    通过kubectl方式创建时,YAML示例如下:

    kind: Secret
    apiVersion: v1
    type: IngressTLS
    metadata:
      name: ingress
      namespace: default
    data:
      tls.crt: LS0tLS1CRU*****FURS0tLS0t
      tls.key: LS0tLS1CRU*****VZLS0tLS0=

    此处tls.crt和tls.key为示例,请获取真实密钥进行替换。tls.crt和tls.key的值为Base64加密后的内容。

分享:

网络异常所有常见问题

more

close