标签 排错 下的文章

背景:
位于阿里云的kubernetes集群,通过ingress svc暴露,类型为ClusterIP。某天在对集群内大量缩容节点时,马上出现了大量的502、504报警
500告警.jpg

以为外部密集请求导致后端服务受影响,从监控观察并无异常,联想到最近的变更,怕不是缩容导致?正在排查的过程中,服务恢复。事后通过工单确认
ClusterIP类型的SLB后端的rs被移除时,SLB的操作就是静默丢包,也就是该SLB对任何发过来的tcp包都会默认丢弃,DROP并不会响应

  • 如果此时此链接是空闲链接,就会等待SLB设置的空闲链接超时时间,超过这个时间后,SLB断开链接
  • 如果此时此链接还有请求,由于SLB不会回ack包,客户端就会超时重传,重传的时间就取决于客户端或者内核的超时设置,比如内核ack默认会进行15次重传(net.ipv4.tcp_retries2=15),累加起来大概是924秒,JDBC URL支持设置SocketTimeout、ConnectTimeout,会在这个超时时间后断开重连

文档描述
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/add-annotations-to-the-yaml-file-of-a-service-to-configure-clb-instances
注解.jpg

最终解法

  • 代码中判断,失败重新建立连接
  • 在ingress中开启上述注解,缩短时间。并在谷值时缩容

上次的数据库故障余波未平。老服务整改周期内仍有可能增高,有没什么方法限制单个pod只能建立一定数量的数据库连接,把事故控制在一定范围内

  • 首先是数据库层面,可以在配置文件中限制连接数,但基于容器的环境IP会有变化 pass
  • 其次想到的是服务网格,因为是业务标配+出色的流量控制,应该可以从这里入手。看了圈文档,Istio更多关注的是进方向
  • 再次想到kubernetes本身的网络插件也有限流的功能,calico具备对进出方向端口的限制,但没找到连接数的

陷入僵局,最笨用iptables限制,但还能实时发现pod的重启更换IP,难道要复杂化,监控结合脚本的方式吗?忽然灵光一闪,initContainers阶段不是可以做很多事情嘛

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  initContainers:
  - name: init-iptables
    image: my-iptables-image
    command: ['sh', '-c', 'iptables -A OUTPUT -p tcp --dport 3306 -m connlimit --connlimit-above 20 -j REJECT']
  containers:
  - name: my-container
    image: my-image

😅未验证,原理可行- -