IBM Cloud Docs
调试 Ingress

调试 Ingress

虚拟私有云 经典基础架构

您可以在集群中为应用程序创建一个 Ingress 资源,从而公开应用程序。 但是,当您尝试通过 Ingress 子域或 ALB 的 IP 地址连接到应用程序时,连接将失败或超时。

以下各部分中的步骤可帮助您调试 Ingress 设置。

开始之前,请确保您具有 IBM Cloud Kubernetes Service的以下 IBM Cloud IAM 访问策略:

  • 群集的编辑器管理员平台访问角色
  • 撰稿人管理员服务访问角色

步骤 1: 检查应用程序部署

在调试 Ingress 之前,请先检出 调试应用程序部署

入口问题通常由应用程序部署或公开应用程序的 ClusterIP 服务中的底层问题导致。 例如,应用程序标签和服务选择器可能不匹配,或者应用程序和服务目标端口可能不匹配。

步骤 2:检查 Ingress 部署和 ALB pod 日志中的错误消息

首先检查 Ingress 资源部署事件和 ALB pod 日志中的错误消息。 这些错误消息可帮助您找到故障的根本原因,并在后续各部分中进一步调试 Ingress 设置。

  1. 检查您的 Ingress 资源部署,查找警告或错误信息。

    kubectl describe ingress <myingress>
    

    在输出的 Events 部分中,您可能会看到警告消息,提醒您所使用的 Ingress 资源或某些注释中有无效的值。 请检查 Ingress 资源配置文档注释文档

    NAME:             myingress
    Namespace:        default
    Address:          169.xx.xxx.xxx,169.xx.xxx.xxx
    Default backend:  default-http-backend:80 (<none>)
    Rules:
        Host                                             Path  Backends
        ----                                             ----  --------
        mycluster-<hash>-0000.us-south.containers.appdomain.cloud
        /tea      myservice1:80 (<none>)
        /coffee   myservice2:80 (<none>)
    Annotations:
        custom-port:        protocol=http port=7490; protocol=https port=4431
        location-modifier:  modifier='~' serviceName=myservice1;modifier='^~' serviceName=myservice2
    Events:
        Type     Reason             Age   From                                                            Message
        ----     ------             ----  ----                                                            -------
        Normal   Success            1m    public-cr87c198fcf4bd458ca61402bb4c7e945a-alb1-258623678-gvf9n  Successfully applied ingress resource.
        Warning  TLSSecretNotFound  1m    public-cr87c198fcf4bd458ca61402bb4c7e945a-alb1-258623678-gvf9n  Failed to apply ingress resource.
        Normal   Success            59s   public-cr87c198fcf4bd458ca61402bb4c7e945a-alb1-258623678-gvf9n  Successfully applied ingress resource.
        Warning  AnnotationError    40s   public-cr87c198fcf4bd458ca61402bb4c7e945a-alb1-258623678-gvf9n  Failed to apply ingress.bluemix.net/custom-port annotation. Error annotation format error : One of the mandatory fields not valid/missing for annotation ingress.bluemix.net/custom-port
        Normal   Success            40s   public-cr87c198fcf4bd458ca61402bb4c7e945a-alb1-258623678-gvf9n  Successfully applied ingress resource.
        Warning  AnnotationError    2s    public-cr87c198fcf4bd458ca61402bb4c7e945a-alb1-258623678-gvf9n  Failed to apply ingress.bluemix.net/custom-port annotation. Invalid port 7490. Annotation can't use ports 7481 - 7490
        Normal   Success            2s    public-cr87c198fcf4bd458ca61402bb4c7e945a-alb1-258623678-gvf9n  Successfully applied ingress resource.
    
  2. 检查 ALB pod 的状态。

    1. 获取正在集群中运行的 ALB pod。

      kubectl get pods -n kube-system | grep alb
      
    2. 通过检查 STATUS 列来确保所有 pod 都在运行。

    3. 如果 pod 没有 Running 状态,则可以禁用和重新启用 ALB。 在以下命令中,请将 <ALB_ID> 替换为 pod 的 ALB ID。 例如,如果未运行的 pod 名称为 public-crb2f60e9735254ac8b20b9c1e38b649a5-alb1-5d6d86fbbc-kxj6z,那么 ALB 标识为 public-crb2f60e9735254ac8b20b9c1e38b649a5-alb1

      • 经典集群:
        ibmcloud ks ingress alb disable --alb <ALB_ID> -c <cluster_name_or_ID>
        
        ibmcloud ks ingress alb enable classic --alb <ALB_ID> -c <cluster_name_or_ID>
        
      • VPC 集群:
        ibmcloud ks ingress alb disable --alb <ALB_ID> -c <cluster_name_or_ID>
        
        ibmcloud ks ingress alb enable vpc-gen2 --alb <ALB_ID> -c <cluster_name_or_ID>
        
  3. 检查 ALB 的日志。

    1. 获取正在集群中运行的 ALB pod 的标识。
      kubectl get pods -n kube-system | grep alb
      
    2. 获取每个 ALB pod 上 nginx-ingress 容器的日志。
      kubectl logs <ingress_pod_ID> nginx-ingress -n kube-system
      
    3. 在 ALB 日志中查找错误消息。

步骤 3:对 ALB 子域和公共 IP 地址执行 ping 操作

检查 Ingress 子域和 ALB 的公共 IP 地址的可用性。 此外,请确保 Akamai 多专区负载均衡器可以访问 ALB 以进行运行状况检查。

  1. 获取公共 ALB 正在侦听的 IP 地址 (经典) 或主机名 (VPC)。

    ibmcloud ks ingress alb ls --cluster <cluster_name_or_ID>
    

    工作节点位于 dal10dal13 的经典多区集群的输出示例:

    ALB ID                                            Enabled   Status     Type      ALB IP          Zone    Build                          ALB VLAN ID   NLB Version
    private-cr24a9f2caf6554648836337d240064935-alb1   false     disabled   private   -               dal13   ingress:1.1.2_2507_iks   2294021       -
    private-cr24a9f2caf6554648836337d240064935-alb2   false     disabled   private   -               dal10   ingress:1.1.2_2507_iks   2234947       -
    public-cr24a9f2caf6554648836337d240064935-alb1    true      enabled    public    169.62.196.238  dal13   ingress:1.1.2_2507_iks   2294019       -
    public-cr24a9f2caf6554648836337d240064935-alb2    true      enabled    public    169.46.52.222   dal10   ingress:1.1.2_2507_iks   2234945       -
    
  2. 验证 ALB 运行状况检查是否可访问您的 ALB IP 地址。

    • 经典: 如果使用 Calico DNAT 前网络策略或其他定制防火墙来阻止到集群的入局流量,那么必须允许从 Kubernetes 控制平面和 Akamai 的 IPv4 IP 地址到 ALB 的 IP 地址的端口 80 或 443 上的入站访问,以便 Kubernetes 控制平面可以检查 ALB 的运行状况。 例如,如果使用 Calico 策略,请 创建 Calico DNAT 前策略,以允许从端口 80 上的 Akamai 的源 IP 地址 和集群所在区域的 控制平面子网对 ALB IP 地址进行入站访问。

    • VPC:如果您在 VPC LBaaS (LoadBalancer-as-a-Service) 实例上为群集入口设置了自定义安全组,请确保安全组规则允许从 Kubernetes 控制平面 IP 地址到端口 443 的必要健康检查流量。

  3. 检查 ALB IP (经典) 或主机名 (VPC) 的运行状况。

    • Ping 每个公共 ALB 的 IP 地址(经典)或主机名(VPC),以确保每个 ALB 都能成功接收数据包。 如果使用专用 ALB,则只能从专用网络 ping 它们的 IP 地址(经典)或主机名(VPC)。

      ping <ALB_IP>
      
      • 如果 CLI 返回超时,而您有保护工作节点的自定义防火墙,请确保防火墙允许 ICMP。
      • 如果您没有防火墙,或者防火墙未阻止 ping,并且 ping 仍然超时,请 检查 ALB pod 的状态
    • 仅限多区群集:可以使用 MZLB 健康检查来确定 ALB IP(传统)或主机名(VPC)的状态。 以下 HTTP cURL 命令使用 albhealth 主机,该主机由 IBM Cloud Kubernetes Service 配置为返回 ALB IP 的 healthyunhealthy 阶段状态。

      curl -X GET http://<ALB_IP>/ -H "Host: albhealth.<ingress_subdomain>"
      

      示例命令:

      curl -X GET http://169.62.196.238/ -H "Host: albhealth.mycluster-<hash>-0000.us-south.containers.appdomain.cloud"
      

      示例输出

      healthy
      

      如果一个或多个 IP 返回 unhealthy,请检查 ALB pod 的状态

  4. 获取 IBM 提供的 Ingress 子域。

    ibmcloud ks cluster get --cluster <cluster_name_or_ID> | grep Ingress
    

    示例输出

    Ingress Subdomain:      mycluster-<hash>-0000.us-south.containers.appdomain.cloud
    Ingress Secret:         mycluster-<hash>-0000
    
  5. 确保在本节第 1 步中获得的每个公共 ALB 的 IP(经典)或主机名(VPC)已在群集 IBM 提供的 Ingress 子域中注册。 例如,在经典的多区群集中,每个有工作节点的区的公共 ALB IP 必须在相同的子域下注册。

    kubectl get ingress -o wide
    

    示例输出

    NAME                HOSTS                                                    ADDRESS                        PORTS     AGE
    myingressresource   mycluster-<hash>-0000.us-south.containers.appdomain.cloud      169.46.52.222,169.62.196.238   80        1h
    

步骤 4:检查域映射和 Ingress 资源配置

  1. 如果使用定制域,请验证是否使用了 DNS 提供程序将该定制域映射到 IBM 提供的子域或 ALB 的公共 IP 地址。 请注意,使用 CNAME 是首选项,因为 IBM 会在 IBM 子域上提供自动运行状况检查,并从 DNS 响应中除去任何失败的 IP。
    • IBM-提供的子域 CNAME:检查您的自定义域是否已映射到集群 IBM 提供的 Canonical Name 记录 (CNAME) 中的子域。
      host www.my-domain.com
      
      示例输出
      www.my-domain.com is an alias for mycluster-<hash>-0000.us-south.containers.appdomain.cloud
      mycluster-<hash>-0000.us-south.containers.appdomain.cloud has address 169.46.52.222
      mycluster-<hash>-0000.us-south.containers.appdomain.cloud has address 169.62.196.238
      
    • 公共 IP 地址 A 记录:检查 A 记录中的自定义域名是否已映射到 ALB 的可移植公共 IP 地址。 这些 IP 应该与在上一部分的步骤 1 中获取的公共 ALB IP 相匹配。
      host www.my-domain.com
      
      示例输出
      www.my-domain.com has address 169.46.52.222
      www.my-domain.com has address 169.62.196.238
      
  2. 检查集群的 Ingress 资源配置文件。
    kubectl get ingress -o yaml
    
    1. 确保一个主机仅在一个 Ingress 资源中进行定义。 如果一个主机在多个 Ingress 资源中进行定义,那么 ALB 可能无法正确转发流量,并且您可能会遇到错误。

    2. 检查子域和 TLS 证书是否正确。 要查找 IBM 提供的 Ingress 子域和 TLS 证书,请运行 ibmcloud ks cluster get --cluster <cluster_name_or_ID>

    3. 确保应用程序侦听的是在 Ingress 的 path 部分中配置的路径。 如果应用程序设置为侦听根路径,请使用 / 作为路径。 如果流至此路径的入局流量必须路由到应用程序侦听的其他路径,请使用重写路径注释。

    4. 根据需要编辑资源配置 YAML。 关闭编辑器时,会保存并自动应用更改。

      kubectl edit ingress <myingressresource>
      

从 DNS 除去 ALB 以进行调试

如果无法通过特定 ALB IP 访问应用程序,那么可以通过禁用 ALB 的 DNS 注册来临时从生产环境除去 ALB。 然后,可以使用该 ALB 的 IP 地址对该 ALB 运行调试测试。

例如,假设在 2 个专区中有一个多专区集群,并且 2 个公共 ALB 具有 IP 地址 169.46.52.222169.62.196.238。 尽管运行状况检查对于第二个专区的 ALB 返回 healthy,但仍然无法直接通过它访问应用程序。 为此,您决定从生产环境中除去 ALB 的 IP 地址 169.62.196.238,以进行调试。 第一个专区的 ALB IP 169.46.52.222 已向域注册,并且在您调试第二个专区的 ALB 时,会继续路由流量。

  1. 获取具有不可访问 IP 地址的 ALB 的名称。

    ibmcloud ks ingress alb ls --cluster <cluster_name> | grep <ALB_IP>
    

    例如,不可访问的 IP 169.62.196.238 属于 ALB public-cr24a9f2caf6554648836337d240064935-alb1

    ALB ID                                            Enabled   Status     Type      ALB IP           Zone    Build                          ALB VLAN ID   NLB Version
    public-cr24a9f2caf6554648836337d240064935-alb1    false     disabled   private   169.62.196.238   dal13   ingress:1.1.2_2507_iks   2294021       -
    
  2. 使用上一步中的 ALB 名称来获取 ALB pod 的名称。 以下命令使用上一步中的示例 ALB 名称:

    kubectl get pods -n kube-system | grep public-cr24a9f2caf6554648836337d240064935-alb1
    

    示例输出

    public-cr24a9f2caf6554648836337d240064935-alb1-7f78686c9d-8rvtq   2/2       Running   0          24m
    public-cr24a9f2caf6554648836337d240064935-alb1-7f78686c9d-trqxc   2/2       Running   0          24m
    
  3. 禁用对所有 ALB pod 运行的运行状况检查。 对上一步中获得的每个 ALB pod 重复这些步骤。 这些步骤中的命令和输出示例使用的是第一个 pod public-cr24a9f2caf6554648836337d240064935-alb1-7f78686c9d-8rvtq

    1. 登录到 ALB pod,并检查 NGINX 配置文件中的 server_name 行。
      kubectl exec -ti public-cr24a9f2caf6554648836337d240064935-alb1-7f78686c9d-8rvtq -n kube-system -c nginx-ingress -- grep server_name /etc/nginx/conf.d/kube-system-alb-health.conf
      
      确认 ALB pod 配置了正确的健康检查子域 albhealth.<domain> 的输出示例:
      server_name albhealth.mycluster-<hash>-0000.us-south.containers.appdomain.cloud;
      
    2. 要通过禁用运行状况检查来除去此 IP,请在 # 前面插入 server_name。 当 ALB 禁用 albhealth.mycluster-<hash>-0000.us-south.containers.appdomain.cloud 虚拟主机时,自动健康检查会自动从 DNS 响应中删除 IP。
      kubectl exec -ti public-cr24a9f2caf6554648836337d240064935-alb1-7f78686c9d-8rvtq -n kube-system -c nginx-ingress -- sed -i -e 's*server_name*#server_name*g' /etc/nginx/conf.d/kube-system-alb-health.conf
      
    3. 验证是否已应用更改。
      kubectl exec -ti public-cr24a9f2caf6554648836337d240064935-alb1-7f78686c9d-8rvtq -n kube-system -c nginx-ingress -- grep server_name /etc/nginx/conf.d/kube-system-alb-health.conf
      
      示例输出
      #server_name albhealth.mycluster-<hash>-0000.us-south.containers.appdomain.cloud
      
    4. 要从 DNS 注册中除去 IP,请重新装入 NGINX 配置。
      kubectl exec -ti public-cr24a9f2caf6554648836337d240064935-alb1-7f78686c9d-8rvtq -n kube-system -c nginx-ingress -- nginx -s reload
      
    5. 对每个 ALB pod 重复这些步骤。
  4. 现在,尝试通过 cURL 使 albhealth 主机对 ALB IP 进行运行状况检查时,检查会失败。

    curl -X GET http://169.62.196.238/ -H "Host: albhealth.mycluster-<hash>-0000.us-south.containers.appdomain.cloud"
    

    输出:

    <html>
        <head>
            <title>404 Not Found</title>
        </head>
        <body bgcolor="white"><center>
            <h1>404 Not Found</h1>
        </body>
    </html>
    
  5. 通过检查 Akamai 服务器,确认 ALB IP 地址已从您域名的 DNS 注册中删除。 请注意,DNS 注册可能需要几分钟时间来更新。

    host mycluster-<hash>-0000.us-south.containers.appdomain.cloud ada.ns.Akamai.com
    

    以下输出示例确认仅运行正常的 ALB IP 169.46.52.222 保留在 DNS 注册中,运行状况欠佳的 ALB IP 169.62.196.238 已除去:

    mycluster-<hash>-0000.us-south.containers.appdomain.cloud has address 169.46.52.222
    
  6. 既然已从生产环境中除去该 ALB IP,您就可以通过该 IP 对应用程序运行调试测试。 要通过此 IP 测试与应用程序的通信,可以运行以下 cURL 命令,并将示例值替换为您自己的值:

    curl -X GET --resolve mycluster-<hash>-0000.us-south.containers.appdomain.cloud:443:169.62.196.238 https://mycluster-<hash>-0000.us-south.containers.appdomain.cloud/
    
    • 如果已正确配置所有内容,那么您将获得从应用程序返回的预期响应。
    • 如果在响应中获得错误,说明应用程序中或仅适用于此特定 ALB 的配置中可能存在错误。 请检查应用程序代码、Ingress 资源配置文件或仅应用于此 ALB 的其他任何配置。
  7. 完成调试后,请对 ALB pod 复原运行状况检查。 对每个 ALB pod 重复这些步骤。

    1. 登录到 ALB pod,并从 # 中除去 server_name
      kubectl exec -ti <pod_name> -n kube-system -c nginx-ingress -- sed -i -e 's*#server_name*server_name*g' /etc/nginx/conf.d/kube-system-alb-health.conf
      
    2. 重新装入 NGINX 配置,以便应用运行状况检查复原。
      kubectl exec -ti <pod_name> -n kube-system -c nginx-ingress -- nginx -s reload
      
  8. 现在,通过 cURL 使 albhealth 主机对 ALB IP 进行运行状况检查时,检查会返回 healthy

    curl -X GET http://169.62.196.238/ -H "Host: albhealth.mycluster-<hash>-0000.us-south.containers.appdomain.cloud"
    
  9. 通过检查 Akamai 服务器,确认 ALB IP 地址已在您域名的 DNS 注册中恢复。 请注意,DNS 注册可能需要几分钟时间来更新。

    host mycluster-<hash>-0000.us-south.containers.appdomain.cloud ada.ns.Akamai.com
    

    示例输出

    mycluster-<hash>-0000.us-south.containers.appdomain.cloud has address 169.46.52.222
    mycluster-<hash>-0000.us-south.containers.appdomain.cloud has address 169.62.196.238