2

我们目前正在对 ElasticSearch 集群的特定 Kubernetes 服务 (LoadBalancer) 的问题进行故障排除,该问题似乎在客户端随机提供 ECONNRESET 变得不可用。设置如下:

  • 使用 Kops 部署的 AWS 上的 Kubernetes 1.6
  • Elasticsearch 2.4 集群(Fabric8 发现插件部署)。它将自己暴露为 Service / LoadBalancer
  • NodeJS API部署作为客户端,使用request模块连接到上述Elasticsearch服务

在运行足够长的时间(不多,大约 10-15 分钟)后,不一定在大量负载下(大约每秒 1 个请求),ElasticSearch 服务似乎变得不可用,这是来自 API 端的 ECONNRESET 错误症状:

{ Error: connect ECONNRESET 100.69.12.100:9200 at 
 Object.exports._errnoException (util.js:953:11) at 
 exports._exceptionWithHostPort (util.js:976:20) at 
 TCPConnectWrap.afterConnect [as oncomplete] (net.js:1080:14) cause: { 
 Error: connect ECONNRESET 100.69.12.100:9200 at 
 Object.exports._errnoException (util.js:953:11) at 
 exports._exceptionWithHostPort (util.js:976:20) at 
 TCPConnectWrap.afterConnect [as oncomplete] (net.js:1080:14) code: 
 'ECONNRESET', errno: 'ECONNRESET', syscall: 'connect', address: 
 '100.69.12.100', port: 9200 }, isOperational: true, code: 
 'ECONNRESET', errno: 'ECONNRESET', syscall: 'connect', address: 
 '100.69.12.100', port: 9200 }

这个错误是随机发生的,不需要高负载,而不是定义的时间段。在这些 ECONNRESET 的确切时间,kube-dnsElasticSearch 服务(和其他服务)的插件日志创建(重新创建?):

I0515 08:11:49.941166       1 dns.go:264] New service: elasticsearch
I0515 08:11:49.941226       1 dns.go:462] Added SRV record &{Host:elasticsearch.prod.svc.cluster.local. Port:9200 Priority:10 Weight:10 Text: Mail:false Ttl:30 TargetStrip:0 Group: Key:}
I0515 08:11:49.941275       1 dns.go:462] Added SRV record &{Host:elasticsearch.prod.svc.cluster.local. Port:9300 Priority:10 Weight:10 Text: Mail:false Ttl:30 TargetStrip:0 Group: Key:}

对于每个 Kubernetes 服务,这些行几乎每 5 分钟连续重复一次。如果这是正常行为或与我们观察到的故障绝对相关,我完全不知道它们的含义。

API 和 ElasticSearch 在网络上的交互基本上是一组搜索查询(最多 30/50 并行)。在交互过程中,在 ElasticSearch 端没有观察到错误日志。

这在几个月前运行良好,变化是:

  • Kubernetes 使用 Kops 从版本 1.4 升级到 1.6
  • 为 ElasticSearch 集群添加了 CPU / 内存限制。遵循 Elastic 建议
  • 向 Elastic 添加了额外的初始 30 次调用,这些调用在第一次调用后被缓存

尝试的操作:

  • 减少和增加 ElasticSearch 端的资源限制(CPU/内存)以查看行为的任何变化。对 ECONNRESET 没有影响
  • 增加了 ElasticSearch 端搜索的线程池和队列大小。它处理更多负载,但问题本身在低负载下表现出来。

考虑回滚到 Kubernetes 1.4,并取消任何限制。任何指针或信息都将受到高度赞赏。

更新 1:有关服务的一些额外信息elasticsearch

$ kubectl get svc elasticsearch
NAME             CLUSTER-IP       EXTERNAL-IP    PORT(S)            AGE
elasticsearch   100.65.113.208    [AWS ELB] 9200:30295/TCP,9300:32535/TCP   6d

$ kubectl describe svc elasticsearch
  Name:         elasticsearch
  Namespace:        ppe
  Labels:           <none>
  Annotations:      kubernetes.io/change-cause=kubectl create --filename=app/elasticsearch/manifest/ --recursive=true --record=true --namespace=ppe --context=
  Selector:     component=elasticsearch,provider=fabric8,type=client
  Type:         LoadBalancer
  IP:           100.65.113.208
  LoadBalancer Ingress: [AWS ELB]
  Port:         http    9200/TCP
  NodePort:     http    30295/TCP
  Endpoints:        100.96.1.25:9200,100.96.1.26:9200,100.96.2.24:9200 + 5 more...
  Port:         transport   9300/TCP
  NodePort:     transport   32535/TCP
  Endpoints:        100.96.1.25:9300,100.96.1.26:9300,100.96.2.24:9300 + 5 more...
  Session Affinity: None
  Events:           <none>

更新 2

我现在能够通过使用官方 ElasticSearch NodeJS 客户端进行搜索查询并与服务通信来缓解这个问题。API 上的代码使用request模块直接调用 ElasticSearch REST API。

我仍在调查这个问题,因为问题仍然存在,但似乎在使用具有以下配置的 NodeJS 客户端时它并没有表现出来:

const elasticSearchClient = elasticSearch.Client({host: config.endpoints.elasticsearch, apiVersion: '2.3',
maxRetries: 5, requestTimeout: 15000, deadTimeout: 30000, keepAlive: true});

更新 3

我们不仅通过与 Elastic 通信的 NodeJS API 观察到这种行为,还观察到与kibana-loggingKubernetes 服务和elasticdump

Mon, 15 May 2017 13:32:31 GMT | sent 1000 objects to destination 
elasticsearch, wrote 1000
Mon, 15 May 2017 13:32:42 GMT | got 1000 objects from source 
elasticsearch (offset: 24000)
Mon, 15 May 2017 13:32:44 GMT | Error Emitted => failed to parse json 
(message: "Unexpected token E in JSON at position 0") - source: "Error: 
'read tcp 172.20.33.123:46758->100.96.4.15:9200: read: connection reset 
by peer'\nTrying to reach: 'http://100.96.4.15:9200/ghs.products-2017-
05-13/_bulk'"

这两个模块和原始的 NodeJS API 都使用requestNPM 模块与 ElasticSearch 进行通信。有趣的是,ElasticSearch NodeJS 客户端(https://github.com/elastic/elasticsearch-js)似乎没有使用request.

仍在调查,但这可能最终成为 Elastic Kubernetes Service 暴露 + NodeJSrequest模块之间的问题/不兼容

4

0 回答 0