排查 AKS 群集上托管的应用的连接问题
与 Microsoft Azure Kubernetes 服务 (AKS) 群集的连接问题可能意味着不同的事情。 在某些情况下,这可能意味着与 API 服务器的连接 (受到影响,例如,使用 kubectl) 。 在其他情况下,这可能意味着常见的连接问题会影响 AKS 群集上托管的应用程序。 本文讨论如何排查 AKS 群集连接问题。
注意
若要排查尝试连接到 AKS API 服务器时的常见问题,请参阅 API 服务器群集连接问题的基本故障排除。
先决条件
客户端 URL (cURL) 工具或类似的命令行工具。
用于处理包的 apt-get 命令行工具。
Kubernetes kubectl 工具或用于连接到群集的类似工具。 若要使用 Azure CLI 安装 kubectl,请运行 az aks install-cli 命令。
要考虑的因素
本部分介绍在尝试连接到 AKS 群集上托管的应用程序时遇到问题时要采取的故障排除步骤。
在任何网络方案中,管理员在进行故障排除时应考虑以下重要因素:
请求的源和目标是什么?
源和目标之间的跃点是多少?
请求-响应流是什么?
哪些跃点顶部具有额外的安全层,例如以下项:
- 防火墙
- 网络安全组 (NSG)
- 网络策略
检查每个组件时,获取和分析 HTTP 响应代码。 这些代码可用于识别问题的性质,在应用程序响应 HTTP 请求的情况下尤其有用。
如果其他故障排除步骤未提供任何结论性结果,请从客户端和服务器获取数据包捕获。 当客户端和服务器之间涉及非 HTTP 流量时,数据包捕获也很有用。 有关如何为 AKS 环境收集数据包捕获的详细信息,请参阅数据收集指南中的以下文章:
了解如何获取 HTTP 响应代码并捕获数据包,可以更轻松地排查网络连接问题。
AKS 上应用程序的基本网络流
通常,用于访问 AKS 群集上托管的应用程序的请求流如下所示:
客户端 >> DNS 名称 >> AKS 负载均衡器 IP 地址 >> AKS 节点 >> Pod
还有其他可能涉及额外组件的情况。 例如:
- 应用程序网关通过应用程序网关入口控制器 (AGIC) 而不是Azure 负载均衡器使用。
- Azure Front Door 和 API 管理 可能在负载均衡器的顶部使用。
- 进程使用内部负载均衡器。
- 连接可能不会在 Pod 和请求的 URL 处结束。 这可能取决于 Pod 是否可以连接到另一个实体,例如数据库或同一群集中的其他任何服务。
了解应用程序的请求流非常重要。
到 AKS 群集上应用程序的基本请求流类似于下图所示的流。
从内到外故障排除
排查连接问题可能涉及许多检查,但 从内到外 的方法可以帮助查找问题的根源并确定瓶颈。 在此方法中,从 Pod 本身开始,检查应用程序是否在对 Pod 的 IP 地址做出响应。 然后,将每个组件检查到最终客户端。
步骤 1:检查 Pod 是否正在运行,以及 Pod 中的应用或容器是否正确响应
若要确定 Pod 是否正在运行,请运行以下 kubectl get 命令之一:
# List pods in the specified namespace.
kubectl get pods -n <namespace-name>
# List pods in all namespaces.
kubectl get pods -A
如果 Pod 未运行,该怎么办? 在这种情况下,使用 kubectl describe 命令检查 Pod 事件:
kubectl describe pod <pod-name> -n <namespace-name>
如果 Pod 不处于 Ready
或 Running
状态,或者它多次重启,检查kubectl describe
输出。 这些事件将显示阻止你启动 Pod 的任何问题。 或者,如果 Pod 已启动,则 Pod 中的应用程序可能已失败,从而导致 Pod 重启。
相应地对 Pod 进行故障排除 ,以确保它处于适当的状态。
如果 Pod 正在运行,则检查 Pod 的日志以及其中容器的日志也很有用。 运行以下 kubectl logs 命令系列:
kubectl logs <pod-name> -n <namespace-name>
# Check logs for an individual container in a multicontainer pod.
kubectl logs <pod-name> -n <namespace-name> -c <container-name>
# Dump pod logs (stdout) for a previous container instance.
kubectl logs <pod-name> --previous
# Dump pod container logs (stdout, multicontainer case) for a previous container instance.
kubectl logs <pod-name> -c <container-name> --previous
Pod 是否正在运行? 在这种情况下,通过在群集中启动测试 Pod 来测试连接性。 在测试 Pod 中,可以直接访问应用程序的 Pod IP 地址,并检查应用程序是否正确响应。 运行 kubectl run、 apt-get
和 cURL
命令,如下所示:
# Start a test pod in the cluster:
kubectl run -it --rm aks-ssh --image=debian:stable
# After the test pod is running, you will gain access to the pod.
# Then you can run the following commands:
apt-get update -y && apt-get install dnsutils -y && apt-get install curl -y
# After the packages are installed, test the connectivity to the application pod:
curl -Iv http://<pod-ip-address>:<port>
对于侦听其他协议的应用程序,可以在测试 Pod 中安装相关工具,然后检查与应用程序 Pod 的连接。
有关对 Pod 进行故障排除的更多命令,请参阅 调试正在运行的 Pod。
步骤 2:检查应用程序是否可以从服务访问
对于运行 Pod 中的应用程序的方案,可以主要关注对 Pod 的公开方式进行故障排除。
Pod 是否作为服务公开? 在这种情况下,检查服务事件。 此外,检查服务说明中的 Pod IP 地址和应用程序端口是否可用作终结点:
# Check the service details.
kubectl get svc -n <namespace-name>
# Describe the service.
kubectl describe svc <service-name> -n <namespace-name>
检查 Pod 的 IP 地址是否作为终结点存在于服务中,如以下示例所示:
$ kubectl get pods -o wide # Check the pod's IP address.
NAME READY STATUS RESTARTS AGE IP NODE
my-pod 1/1 Running 0 12m 10.244.0.15 aks-agentpool-000000-vmss000000
$ kubectl describe service my-cluster-ip-service # Check the endpoints in the service.
Name: my-cluster-ip-service
Namespace: default
Selector: app=my-pod
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.0.174.133
IPs: 10.0.174.133
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.0.15:80 # <--- Here
$ kubectl get endpoints # Check the endpoints directly for verification.
NAME ENDPOINTS AGE
my-cluster-ip-service 10.244.0.15:80 14m
如果终结点未指向正确的 Pod IP 地址,请验证 Labels
Pod 和服务的 和 Selectors
。
服务中的终结点是否正确? 如果是,请访问服务,并检查应用程序是否可访问。
访问 ClusterIP 服务
ClusterIP
对于服务,可以在群集中启动测试 Pod 并访问服务 IP 地址:
# Start a test pod in the cluster:
kubectl run -it --rm aks-ssh --image=debian:stable
# After the test pod is running, you will gain access to the pod.
# Then, you can run the following commands:
apt-get update -y && apt-get install dnsutils -y && apt-get install curl -y
# After the packages are installed, test the connectivity to the service:
curl -Iv http://<service-ip-address>:<port>
如果上一个命令未返回适当的响应,检查任何错误的服务事件。
访问 LoadBalancer 服务
LoadBalancer
对于服务,可以从群集外部访问负载均衡器 IP 地址。
curl -Iv http://<service-ip-address>:<port>
LoadBalancer
服务 IP 地址是否返回正确的响应? 否则,请按照以下步骤操作:
验证服务的事件。
验证与 AKS 节点和 AKS 子网关联的网络安全组 (NSG) 是否允许服务端口上的传入流量。
有关对服务进行故障排除的更多命令,请参阅 调试服务。
使用入口而不是服务的方案
对于使用 Ingress
资源公开应用程序的情况,流量流类似于以下进度:
客户端 >> DNS 名称 >> 负载均衡器或应用程序网关 IP 地址 >> 群集 >> 服务或 Pod 中的入口 Pod
也可以在此处应用从内到外进行故障排除的方法。 有关详细信息,还可以检查入口和入口控制器详细信息:
$ kubectl get ing -n <namespace-of-ingress> # Checking the ingress details and events.
NAME CLASS HOSTS ADDRESS PORTS AGE
hello-world-ingress <none> myapp.com 20.84.x.x 80, 443 7d22h
$ kubectl describe ing -n <namespace-of-ingress> hello-world-ingress
Name: hello-world-ingress
Namespace: <namespace-of-ingress>
Address: 20.84.x.x
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
tls-secret terminates myapp.com
Rules:
Host Path Backends
---- ---- --------
myapp.com
/blog blog-service:80 (10.244.0.35:80)
/store store-service:80 (10.244.0.33:80)
Annotations: cert-manager.io/cluster-issuer: letsencrypt
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/use-regex: true
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 5m41s nginx-ingress-controller Scheduled for sync
Normal Sync 5m41s nginx-ingress-controller Scheduled for sync
此示例包含一个 Ingress
资源,该资源:
- 侦
myapp.com
听主机。 - 配置了两
Path
个字符串。 - 路由到后端中的两个
Services
。
验证后端服务是否正在运行,并响应入口说明中提到的端口:
$ kubectl get svc -n <namespace-of-ingress>
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
ingress-basic blog-service ClusterIP 10.0.155.154 <none> 80/TCP
ingress-basic store-service ClusterIP 10.0.61.185 <none> 80/TCP
ingress-basic nginx-ingress-ingress-nginx-controller LoadBalancer 10.0.122.148 20.84.x.x 80:30217/TCP,443:32464/TCP
如果出现错误,请验证入口控制器 Pod 的日志:
$ kubectl get pods -n <namespace-of-ingress> # Get the ingress controller pods.
NAME READY STATUS RESTARTS AGE
aks-helloworld-one-56c7b8d79d-6zktl 1/1 Running 0 31h
aks-helloworld-two-58bbb47f58-rrcv7 1/1 Running 0 31h
nginx-ingress-ingress-nginx-controller-9d8d5c57d-9vn8q 1/1 Running 0 31h
nginx-ingress-ingress-nginx-controller-9d8d5c57d-grzdr 1/1 Running 0 31h
$ # Check logs from the pods.
$ kubectl logs -n ingress-basic nginx-ingress-ingress-nginx-controller-9d8d5c57d-9vn8q
如果客户端向入口主机名或 IP 地址发出请求,但在入口控制器 Pod 的日志中看不到任何条目,该怎么办? 在这种情况下,请求可能未到达群集,并且用户可能收到 Connection Timed Out
错误消息。
另一种可能性是入口 Pod 上的组件(如负载均衡器或应用程序网关)未将请求正确路由到群集。 如果属实,则可以检查这些资源的后端配置。
如果收到Connection Timed Out
错误消息,检查与 AKS 节点关联的网络安全组。 此外,检查 AKS 子网。 它可能会阻止从负载均衡器或应用程序网关流向 AKS 节点的流量。
有关如何排查入口 ((如 Nginx 入口) )的详细信息,请参阅 ingress-nginx 故障排除。
联系我们寻求帮助
如果你有任何疑问或需要帮助,请创建支持请求或联系 Azure 社区支持。 还可以向 Azure 反馈社区提交产品反馈。
第三方联系人免责声明
Microsoft 提供第三方联系信息,帮助你查找有关本主题的其他信息。 该联系信息如有更改,恕不另行通知。 Microsoft 不保证第三方联系信息的准确性。