zoukankan      html  css  js  c++  java
  • DCOS 场景 访问 l4lb vip 偶现超时

    环境信息

    centos7,linux 3.10,lvs 使用 nat 模式。client 容器化部署,使用veth连接到linux网桥

    业务背景

    redisclient 使用长连接访问 vip,由lvs转发到后端redis,偶现出现redisclient请求报文报文超时,连接断开

    分析进展:

    • 问题出现时,veth,bridge上抓包有报文,lvs转发后接口没抓到,filter表input链里添加规则,也能匹配到包。
    • 出现问题时,客户端因为没收到回复重传了多次都没转发出去,最后因为服务器没收到报文发送tcp keepalive,客户端能收到,但是keepalive 回复报文也没转出去。
    • 跟同事交流说可能是gro的问题,我们设备开启了gro,但是抓到的报文都是不超过200的小包(奇怪为啥gro没生效),所以gro导致报文过大影响lvs转发也说不过去。

    环境信息

    centos7,linux 3.10,lvs 使用 nat 模式。client 容器化部署,使用veth连接到linux网桥

    业务背景

    redisclient 使用长连接访问 vip,由lvs转发到后端redis,偶现出现redisclient请求报文报文超时,连接断开

    分析进展:

    • 问题出现时,veth,bridge上抓包有报文,lvs转发后接口没抓到,filter表input链里添加规则,也能匹配到包。
    • 出现问题时,客户端因为没收到回复重传了多次都没转发出去,最后因为服务器没收到报文发送tcp keepalive,客户端能收到,但是keepalive 回复报文也没转出去。
    • 跟同事交流说可能是gro的问题,我们设备开启了gro,但是抓到的报文都是不超过200的小包(奇怪为啥gro没生效),所以gro导致报文过大影响lvs转发也说不过去。

    原因是由于删除和创建service的判断逻辑有问题。

    分析如下:

    之前分析过lvs和overlay的配置没有发现问题。后面发现系统日志中频繁出现如下日志,即lvs删除service,而且是指删除。

    Jul 12 21:14:57 test-agent-3 kernel: IPVS: __ip_vs_del_service: enter
    Jul 12 21:14:57 test-agent-3 kernel: IPVS: __ip_vs_del_service: enter
    Jul 12 21:14:57 test-agent-3 kernel: IPVS: __ip_vs_del_service: enter
    Jul 12 21:14:57 test-agent-3 kernel: IPVS: __ip_vs_del_service: enter
    

    这些删除lvs service是由dcos-navstar发起的,调高日志级别发现,navstar删除service后,又重新批量添加回来services,如下代码所示,非常奇怪。

    apply_diff({ServicesToAdd, ServicesToRemove, ServicesToModify}, Namespace, State) ->
    lists:foreach(fun({VIP, _BEs}) -> remove_service(VIP, Namespace, State) end, ServicesToRemove),
    lists:foreach(fun({VIP, BEs}) -> add_service(VIP, BEs, Namespace, State) end, ServicesToAdd),
    

    再往前追溯修改的原因,发现是由于 vip 变动导致的,即有使用内部负载均衡的服务被删除或者创建,或者配额有改变。

    push_vips(VIPs0) ->
    VIPs1 = ordsets:from_list(VIPs0),
    gen_statem:cast(?SERVER, {vips, VIPs1}).
    

    之后引发状态机的变化,apply_diff 根据下面Diff变量得到删除或者添加service,Diff 根据最新获取的service列表及之前的缓存做对比得到的。
    LastConfigured 是之前的 service 缓存, VIPs1是最新得到 service 列表,两个列表都做过排序。

    maintain(VIPs0, State = #state{ns = Namespaces, routes = Routes, last_configured_vips = LastConfigured}) ->
    VIPs1 = process_reachability(VIPs0, State),
    Diff = generate_diff(LastConfigured, VIPs1),
    NewRoutes = ordsets:from_list([VIP || {{_Proto, VIP, _Port}, _Backends} <- VIPs1]), 
    lager:debug("Last Configured: ~p, VIPs: ~p, NewRoutes ~p, Diff ~p", [LastConfigured, VIPs1, NewRoutes, Diff]),
    lists:foreach(fun(Namespace) -> 
    do_update_routes(NewRoutes, Routes, Namespace, State),
    apply_diff(Diff, Namespace, State) 
    end, Namespaces),
    State#state{last_configured_vips = VIPs1, last_received_vips = VIPs0, routes = NewRoutes}.
    

    假设有这样的service列表,原有的service为[1,2,4,5], 最新的service列表为[1,2,3,4,5],有如下执行的结果

    修复方案: 修改上面两个函数判断条件如下,即可。

    generate_diff(Lhs = [VIPLhs|_RestLhs], [VIPRhs|RestRhs], VIPsToAdd0, VIPsToRemove, Mutations) when VIPLhs > VIPRhs ->
    generate_diff(Lhs, RestRhs, [VIPRhs|VIPsToAdd0], VIPsToRemove, Mutations);
    %% To delete VIP
    generate_diff([VIPLhs|RestLhs], Rhs = [VIPRhs|_RestRhs], VIPsToAdd, VIPsToRemove0, Mutations) when VIPLhs < VIPRhs ->
    generate_diff(RestLhs, Rhs, VIPsToAdd, [VIPLhs|VIPsToRemove0], Mutations);

    修改 PR 链接 :

    https://github.com/dcos/navstar/pull/100
    https://github.com/dcos/dcos-net/pull/59
    jira问题跟踪链接 :
    https://jira.mesosphere.com/browse/DCOS_OSS-3602

  • 相关阅读:
    致 CODING 用户的元宵问候
    持续集成之理论篇
    基于 CODING 的 Spring Boot 持续集成项目
    使用 CODING 进行 Hexo 项目的持续集成
    使用 CODING 进行 Spring Boot 项目的集成
    三种前端模块化规范
    XSS和CSRF
    小问题填坑,关于obj.x和obj["x"]
    说一个闭包在实际开发中的应用
    关于return的分号自动插入问题
  • 原文地址:https://www.cnblogs.com/haoqingchuan/p/9370468.html
Copyright © 2011-2022 走看看