调试 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- NGINX 的 ALB,请参阅 Ingress 资源配置文档注解文档。 对于基于 Traefik 的 ALB,请参阅 Ingress 资源配置文档Ingress Controller 配置文档

    NAME:             myingress
    Namespace:        default
    Address:          169.xx.xxx.xxx,169.xx.xxx.xxx
    Default backend:  <default>
    Rules:
        Host                                             Path  Backends
        ----                                             ----  --------
        mycluster-<hash>-0000.us-south.containers.appdomain.cloud
        /tea      myservice1:80 (<none>)
        /coffee   myservice2:80 (<none>)
    Annotations:                                         <none>
    Events:
      Type    Reason  Age                From                      Message
      ----    ------  ----               ----                      -------
      Normal  Sync    26s (x8 over 19m)  nginx-ingress-controller  Scheduled for sync
      Normal  Sync    26s (x8 over 19m)  nginx-ingress-controller  Scheduled for sync
    
  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`。
        * 经典集群:
            ```sh {: pre}
            ibmcloud ks ingress alb disable --alb <ALB_ID> -c <cluster_name_or_ID>
            ```
            ```sh {: pre}
            ibmcloud ks ingress alb enable classic --alb <ALB_ID> -c <cluster_name_or_ID>
            ```
        * VPC 集群:
            ```sh {: pre}
            ibmcloud ks ingress alb disable --alb <ALB_ID> -c <cluster_name_or_ID>
            ```
            ```sh {: pre}
            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
        ```
    1. 对于基于 Ingress- NGINX 的 ALB,请获取每个 ALB Pod 中 `nginx-ingress` 容器的日志。 对于基于 Traefik 的 ALB,请获取每个 ALB Pod 中 `traefik` 容器的日志。
    ```sh {: pre}
        kubectl logs <ingress_pod_ID> <nginx-ingress/traefik> -n kube-system
        ```
    1. 在 ALB 日志中查找错误消息。
    
    

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

检查 Ingress 子域和 ALB 的公共 IP 地址的可用性。 此外,请确保 IBM NS1 能够访问您的 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 pre-DNAT 网络策略或其他自定义防火墙来阻止群集的入站流量,则必须允许从 Kubernetes 控制平面和 IBM NS1 的 IPv4 IP 地址到 ALB 的 IP 地址的 80 或 443 端口入站访问,以便 Kubernetes 控制平面可以检查 ALB 的健康状况。 例如,如果使用 Calico 策略,可 创建 Calico pre-DNAT 策略,允许从 IBM NS1 的源 IP 地址通过 80 端口和 群集所在区域的控制平面子网对 ALB IP 地址进行入站访问。

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

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

    • Ping 每个公共 ALB 的 IP 地址(经典)或主机名(VPC),以确保每个 ALB 都能成功接收数据包。 如果您使用的是私有 ALB,则只能从私有网络对它们的 IP 地址(经典型)或主机名(VPC 型)进行 ping 操作。
        ping <ALB_IP>
        ```
        * 如果 CLI 返回超时错误,且您有自定义防火墙在保护工作节点,请确保在防火墙中允许 ICMP 流量。
        * 如果您没有防火墙,或者防火墙未阻止 ping,并且 ping 仍然超时,请 [检查 ALB pod 的状态](#check_pods)。
    
    * 仅限多区域集群:您可以使用 MZLB 健康检查来确定 ALB IP 地址(经典)或主机名(VPC)的状态。 以下 HTTP cURL 命令使用 `albhealth` 主机,该主机由 IBM Cloud Kubernetes Service 配置为返回 ALB IP 的 `healthy` 或 `unhealthy` 阶段状态。
    ```sh {: pre}
        curl -X GET http://<ALB_IP>/ -H "Host: albhealth.<ingress_subdomain>"
        ```
        示例命令:
        ```sh {: pre}
        curl -X GET http://169.62.196.238/ -H "Host: albhealth.mycluster-<hash>-0000.us-south.containers.appdomain.cloud"
        ```
        示例输出
        ```sh {: screen}
        healthy
        ```
         如果一个或多个 IP 返回 `unhealthy`,请[检查 ALB pod 的状态](#check_pods)。
    
    
  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:请确认您的自定义域名已在规范名称(CNAME)记录中映射到集群提供的 IBM 子域名。
        host www.my-domain.com
        ```
        示例输出
        ```sh {: screen}
        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 应该与在[上一部分](#ping)的步骤 1 中获取的公共 ALB IP 相匹配。
    ```sh {: pre}
        host www.my-domain.com
        ```
        示例输出
        ```sh {: screen}
        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 部分中配置的路径。 如果应用程序设置为侦听根路径,请使用 / 作为路径。 如果发往此路径的传入流量必须被路由到您的应用监听的另一个路径,请在 **Ingress-NGINX** 上使用 [重写路径](/docs/containers?topic=containers-comm-ingress-annotations#alb-rewrite-paths) 注解。 对于 Traefik,请使用 ReplacePath 中间件

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

        kubectl edit ingress <myingressresource>
        ```
    
    

在 Classic 环境中为调试目的从 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 地址从域名中移除。 “update”命令会完全替换已注册的IP地址,因此您只需在命令中指定正常的IP地址即可:

    ibmcloud ks ingress domain update --cluster <cluster_name> --domain <cluster domain> --ip 169.46.52.222
    
  2. 通过检查 IBM NS1 服务器,确认 ALB IP 地址已从您域名的 DNS 记录中移除。 请注意,DNS 注册可能需要几分钟时间来更新。

    host mycluster-<hash>-0000.us-south.containers.appdomain.cloud dns1.p02.nsone.net
    

    以下输出示例确认仅运行正常的 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
    
  3. 既然已从生产环境中除去该 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 资源配置文件Ingress- NGINX ),或查阅 TraefikIngress Controller 配置文档,以及您仅针对此 ALB 应用的任何其他配置。
  4. 调试完成后,请使用以下命令恢复 ALB 的 DNS 注册:

    ibmcloud ks ingress domain update --cluster <cluster_name> --domain <cluster domain> --ip 169.46.52.222 --ip 169.62.196.238
    
  5. 请通过检查 IBM NS1 服务器,确认ALB IP地址已在您域名的DNS记录中恢复。 请注意,DNS 注册可能需要几分钟时间来更新。

    host mycluster-<hash>-0000.us-south.containers.appdomain.cloud dns1.p02.nsone.net
    

    示例输出

    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