加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 移动互联 > 正文

容器云平台API Server卡顿问题排查

发布时间:2019-07-02 00:29:00 所属栏目:移动互联 来源:aoxiang
导读:58云计较平台是58团体架构线基于Kubernetes + Docker技能为团体内部处事开拓的一套营业实例打点平台,它具有简朴,轻量的特点及高效操作物理资源,更快的陈设和同一类型的尺度化运行情形,通过云平台,使得处事尺度化,上线流程类型化,资源操作公道化。然

经排查,TGW的监控检测模块按期向全部的RS发送心跳包,可是TGW监控检测模块只能收到A处事器的回包,因此TGW以为只有A节点是存活状态,全部的哀求数据包最终就由TGW转发到A处事器上了,这就是负载平衡计策失效的基础缘故起因。

这里尚有一个征象是为什么etcd集群中只有一个节点的负载很高呢?

五个节点的etcd集群中只有一个节点负载很高,其他正常,通过查察A处事器的API Server的log,可以看到的大量的读哀求都牢靠发送到了统一个etcd节点。

对付这个征象,可以看下API Server会见后端存储的源码,今朝线上Kubernetes基于v1.7.12的源码编译运行,API Server会见etcd是在内部初始化一个etcd client端,然后通过etcd client端发送哀求到etcd server端。etcd client端有v2和v3两个版本。线上API Server行使的是v2版本客户端。首要代码如下:

  1. //初始化etcd事变 
  2. func New(cfg Config) (Client, error) { 
  3. c := &httpClusterClient{//返回一个http范例的client 
  4. clientFactory: newHTTPClientFactory(cfg.transport(), cfg.checkRedirect(), cfg.HeaderTimeoutPerRequest), 
  5. rand:          rand.New(rand.NewSource(int64(time.Now().Nanosecond()))),//传入一个当前时刻的随机种子 
  6. selectionMode: cfg.SelectionMode, 
  7.  
  8. if err := c.SetEndpoints(cfg.Endpoints); err != nil { 
  9. return nil, err 
  10. return c, nil 
  11. //对etcd列表举办打乱 
  12. func (c *httpClusterClient) SetEndpoints(eps []string) error { 
  13. ... 
  14. neps, err := c.parseEndpoints(eps) 
  15. c.Lock() 
  16. defer c.Unlock() 
  17. c.endpoints = shuffleEndpoints(c.rand, neps)//打乱etcd列表 
  18. c.pinned = 0 
  19. ... 
  20. return nil 
  21.  
  22. func shuffleEndpoints(r *rand.Rand, eps []url.URL) []url.URL { 
  23. p := r.Perm(len(eps))//rank库的Perm要领可以返回[0,n)之间的随机乱序数组 
  24. neps := make([]url.URL, len(eps)) 
  25. for i, k := range p { 
  26. neps[i] = eps[k] 
  27. return neps 
  28. }  

可以看到在初始化etcd客户端时辰会传入一个当前时刻的随机种子去打乱全部Endpoints(etcd节点)的次序。

对付etcd的操纵都是通过API Server内部的etcd客户端发送http哀求到etcd Server端,最首要是挪用如下要领:

  1. func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) { 
  2. ... 
  3. for i := pinned; i < leps+pinned; i++ { 
  4. k := i % leps 
  5. hc := c.clientFactory(eps[k]) 
  6. resp, body, err = hc.Do(ctx, action) 
  7. ... 
  8. if resp.StatusCode/100 == 5 { 
  9.   switch resp.StatusCode { 
  10.   case http.StatusInternalServerError, http.StatusServiceUnavailable: 
  11.     cerr.Errors = ... 
  12.   default: 
  13.     cerr.Errors = ... 
  14.   } 
  15.   ... 
  16.   continue 
  17. if k != pinned { 
  18.   c.Lock() 
  19.   c.pinned = k 
  20.   c.Unlock() 
  21. return resp, body, nil 
  22. return nil, nil, cerr 
  23. }  

该要领表白每次哀求时辰,会从pinned节点开始实行发送哀求,假如发送哀求非常,则凭证初始化时辰打乱次序的下一个节点(pinned++)开始实行发送数据。云云看来,假如API Server行使了某个endpoint发送数据,除非用坏了这个节点,不然会一向行使该节点(pinned)发送数据。这就声名白,没有非常环境下,一个API Server就对应往一个牢靠的etcd发送哀求。

对付etcd集群,假如是写哀求的话,follower节点会把哀求先转发给leader节点处理赏罚,然后leader再转发给follower同步。那么5个节点CPU负载不会这么不平衡,可是按照2.1排查API Server日记看到这里是大量的读哀求,相对付写哀求,读哀求是全部follower节点都能对外提供的。也就是大量哀求因为负载平衡计策失效都转发到A处事器,A再把查询哀求都打到个中一个牢靠的etcd,导致该节点忙于处理赏罚etcd查询哀求,负载就会飙高。

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读