调试 Ingress
虚拟私有云 经典基础架构
您可以在集群中为应用程序创建一个 Ingress 资源,从而公开应用程序。 但是,当您尝试通过 Ingress 子域或 ALB 的 IP 地址连接到应用程序时,连接将失败或超时。
以下各部分中的步骤可帮助您调试 Ingress 设置。
开始之前,请确保您具有 IBM Cloud Kubernetes Service的以下 IBM Cloud IAM 访问策略:
- 群集的编辑器或管理员平台访问角色
- 撰稿人或管理员服务访问角色
步骤 1: 检查应用程序部署
在调试 Ingress 之前,请先检出 调试应用程序部署。
入口问题通常由应用程序部署或公开应用程序的 ClusterIP
服务中的底层问题导致。 例如,应用程序标签和服务选择器可能不匹配,或者应用程序和服务目标端口可能不匹配。
步骤 2:检查 Ingress 部署和 ALB pod 日志中的错误消息
首先检查 Ingress 资源部署事件和 ALB pod 日志中的错误消息。 这些错误消息可帮助您找到故障的根本原因,并在后续各部分中进一步调试 Ingress 设置。
-
检查您的 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.
-
检查 ALB pod 的状态。
-
获取正在集群中运行的 ALB pod。
kubectl get pods -n kube-system | grep alb
-
通过检查 STATUS 列来确保所有 pod 都在运行。
-
如果 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>
- 经典集群:
-
-
检查 ALB 的日志。
- 获取正在集群中运行的 ALB pod 的标识。
kubectl get pods -n kube-system | grep alb
- 获取每个 ALB pod 上
nginx-ingress
容器的日志。kubectl logs <ingress_pod_ID> nginx-ingress -n kube-system
- 在 ALB 日志中查找错误消息。
- 获取正在集群中运行的 ALB pod 的标识。
步骤 3:对 ALB 子域和公共 IP 地址执行 ping 操作
检查 Ingress 子域和 ALB 的公共 IP 地址的可用性。 此外,请确保 Akamai 多专区负载均衡器可以访问 ALB 以进行运行状况检查。
-
获取公共 ALB 正在侦听的 IP 地址 (经典) 或主机名 (VPC)。
ibmcloud ks ingress alb ls --cluster <cluster_name_or_ID>
工作节点位于
dal10
和dal13
的经典多区集群的输出示例: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 -
- 如果公共 ALB 没有 IP 地址 (经典) 或主机名 (VPC),请参阅 Ingress ALB 未部署在区域中。
-
验证 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 的必要健康检查流量。
-
-
检查 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 的healthy
或unhealthy
阶段状态。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 的状态。
-
-
获取 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
-
确保在本节第 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 资源配置
- 如果使用定制域,请验证是否使用了 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
- IBM-提供的子域 CNAME:检查您的自定义域是否已映射到集群 IBM 提供的 Canonical Name 记录 (CNAME) 中的子域。
- 检查集群的 Ingress 资源配置文件。
kubectl get ingress -o yaml
-
确保一个主机仅在一个 Ingress 资源中进行定义。 如果一个主机在多个 Ingress 资源中进行定义,那么 ALB 可能无法正确转发流量,并且您可能会遇到错误。
-
检查子域和 TLS 证书是否正确。 要查找 IBM 提供的 Ingress 子域和 TLS 证书,请运行
ibmcloud ks cluster get --cluster <cluster_name_or_ID>
。 -
确保应用程序侦听的是在 Ingress 的 path 部分中配置的路径。 如果应用程序设置为侦听根路径,请使用
/
作为路径。 如果流至此路径的入局流量必须路由到应用程序侦听的其他路径,请使用重写路径注释。 -
根据需要编辑资源配置 YAML。 关闭编辑器时,会保存并自动应用更改。
kubectl edit ingress <myingressresource>
-
从 DNS 除去 ALB 以进行调试
如果无法通过特定 ALB IP 访问应用程序,那么可以通过禁用 ALB 的 DNS 注册来临时从生产环境除去 ALB。 然后,可以使用该 ALB 的 IP 地址对该 ALB 运行调试测试。
例如,假设在 2 个专区中有一个多专区集群,并且 2 个公共 ALB 具有 IP 地址 169.46.52.222
和 169.62.196.238
。 尽管运行状况检查对于第二个专区的 ALB 返回 healthy,但仍然无法直接通过它访问应用程序。 为此,您决定从生产环境中除去 ALB 的 IP 地址 169.62.196.238
,以进行调试。 第一个专区的 ALB IP 169.46.52.222
已向域注册,并且在您调试第二个专区的 ALB 时,会继续路由流量。
-
获取具有不可访问 IP 地址的 ALB 的名称。
ibmcloud ks ingress alb ls --cluster <cluster_name> | grep <ALB_IP>
例如,不可访问的 IP
169.62.196.238
属于 ALBpublic-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 -
-
使用上一步中的 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
-
禁用对所有 ALB pod 运行的运行状况检查。 对上一步中获得的每个 ALB pod 重复这些步骤。 这些步骤中的命令和输出示例使用的是第一个 pod
public-cr24a9f2caf6554648836337d240064935-alb1-7f78686c9d-8rvtq
。- 登录到 ALB pod,并检查 NGINX 配置文件中的
server_name
行。
确认 ALB pod 配置了正确的健康检查子域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
albhealth.<domain>
的输出示例:server_name albhealth.mycluster-<hash>-0000.us-south.containers.appdomain.cloud;
- 要通过禁用运行状况检查来除去此 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
- 验证是否已应用更改。
示例输出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
- 要从 DNS 注册中除去 IP,请重新装入 NGINX 配置。
kubectl exec -ti public-cr24a9f2caf6554648836337d240064935-alb1-7f78686c9d-8rvtq -n kube-system -c nginx-ingress -- nginx -s reload
- 对每个 ALB pod 重复这些步骤。
- 登录到 ALB pod,并检查 NGINX 配置文件中的
-
现在,尝试通过 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>
-
通过检查 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 IP169.62.196.238
已除去:mycluster-<hash>-0000.us-south.containers.appdomain.cloud has address 169.46.52.222
-
既然已从生产环境中除去该 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 的其他任何配置。
-
完成调试后,请对 ALB pod 复原运行状况检查。 对每个 ALB pod 重复这些步骤。
- 登录到 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
- 重新装入 NGINX 配置,以便应用运行状况检查复原。
kubectl exec -ti <pod_name> -n kube-system -c nginx-ingress -- nginx -s reload
- 登录到 ALB pod,并从
-
现在,通过 cURL 使
albhealth
主机对 ALB IP 进行运行状况检查时,检查会返回healthy
。curl -X GET http://169.62.196.238/ -H "Host: albhealth.mycluster-<hash>-0000.us-south.containers.appdomain.cloud"
-
通过检查 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