k8s集群中App无法访问网络问题排查

k8s集群中App无法访问网络问题排查

在工作中使用Fireboom构建镜像后,使用k8s运行容器,发现应用无法访问网络,错误内容是:dial tcp 10.14.228.89:9825: connect: connection refused,导致Fireboom应用无法正常使用。多天排查后发现竟然是Istio的问题。

我们使用Kubesphere来搭建k8s集群,它提供了很方便的k8s管理功能,包括对于应用部署非常重要的服务网格、蓝绿部署、金丝雀部署等。

最近正在逐步将我们的Fireboom相关应用重构为使用k8s来管理,为此我们构建了一个Fireboom二进制基础镜像,该镜像只有一个任务,就是fireboom start。我们的镜像在本地运行非常正常,于是我们推送到Kubesphere集群中部署:新建自制应用,开启应用治理,添加容器,添加 Volume 共享,启动。但是在fireboom容器中查看日志发现应用无法访问oidcs3服务。

排查过程

  1. 通过查看代码,发现这2个服务都是通过golangclient.Do方法来访问某个 URL,于是在Kubesphere中使用Terminal测试这些链接,结果都是可以连同的,排除网络问题
  2. Kubesphere的其它命名空间中创建同样的应用,结果Fireboom启动日志是正确的,排除Kubesphere网络问题
  3. 在原应用的同namespace中创建同样的应用,仍无法访问,猜测是不是namespace有什么不一样的设置,只是后来多次对比测试后没找到问题
  4. 尝试在原应用中添加wait-for-it.sh来测试容器启动阶段是否网络是通的,结果发现是可访问的,这就很懵了
  5. 同事提醒我可以不要在应用下创建,于是我就在Kubesphere中单独开了一个工作负载,同样的容器和 Volume 配置,发现启动日志正常。于是对比了下和应用里的 Pod 的区别,那只剩下多出的istio-initistio-proxy两个容器了
  6. 根据查找出的现象,开始搜索,找到一篇文章提到要修改istioConfigMap中的holdApplicationUntilProxyStarts配置,但是文章中的配置方法较老,于是找到官网的介绍,根据官网描述在全局ConfigMap中找到istio-system命名空间下的istio-sidecar-injector-1-14-6配置,将其中的holdApplicationUntilProxyStarts修改为true,然后重启应用,结果从日志中发现应用可以正常访问网络了。激动!困扰了几天的问题终于解决了。

总结

Istio为我们提供了非常强大的应用治理能力,它通过在init containers注入一个istio-proxy sidecar 容器,来为整个 Pod 添加 iptabls规则并将流量重定向到istio-proxy也就是Envoy。但是由于istio-proxy的启动时间较长,因此在应用启动阶段,istio-proxy还未启动,导致应用流量转发失败而无法访问网络。

针对这个这个问题的解决方法就是holdApplicationUntilProxyStarts配置为true,可以是k8s全局的,也可以针对某个 Pod,上述的官网中这2种情况都有配置介绍。其实现原理是将istio-proxy注入为第一个 container,并添加postStart钩子pilot-agent wait,其目的就是等待istio-proxy流量转发完成并阻塞后续容器启动。这样当istio-proxy流量转发就绪的时候,应用就可以正常访问网络了。

istio-proxy-injection.png

这是我刚接触k8s实战的过程中遇到的一个问题,记录下来,希望对大家有所帮助。

k8s集群中App无法访问网络问题排查

https://blog.erguotou.me/k8s-network-refused.html

作者

二锅头

发布于

2024-02-26

许可协议

CC BY-NC-SA 4.0

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×