基于Kubernetes的ESaaS架构及实现细节(二)


【编者的话】ESaaS(ElasticSearch as a Service)是ElasticSearch on Kubernetes的产品实现,是利用Docker和Kubernetes等容器虚拟化和编排调度系统,将ElasticSearch抽象为CaaS(Container as a Service)平台上的一种服务,实现秒级创建和扩缩容一个用户自定义的ElasticSerach集群,并且保证高可用和数据安全等方面。上一篇《基于Kubernetes的ESaaS架构及实现细节(一)》介绍了基于LocalDisk构建ESaaS的架构探索,这篇将介绍这个方案需要注意和考虑的关键实现细节。

概述

ESaaS(ElasticSearch as a Service)是ElasticSearch on Kubernetes的产品实现,是利用Docker和Kubernetes等容器虚拟化和编排调度系统,将ElasticSearch抽象为CaaS(Container as a Service)平台上的一种服务,实现秒级创建和扩缩容一个用户自定义的ElasticSerach集群,并且保证高可用和数据安全等方面。

关键组件

  • ElasticSearch 2.x
  • Kubernetes 1.9
  • Docker 1.12.6


方案细节和注意事项

1、ES集群中,某个data/master/client节点挂了之后,分别该怎么办?


PS:我的环境中,所有data节点都是client,不会独立部署client。
  • 如果独立部署client,那么client挂了recreate一个新的即可,注意要清理旧的/data数据。
  • master /data保存集群元数据,某个master down了recreate一个新的即可,新的master node 其实可以利用旧的master node的/data数据,也可以不用。调度上不需要干预。但是建议要清理/data数据。
  • data节点挂了后,不允许利用原来的数据进行重启,需要recreate一个新的空白的data node。调度上需要干预,确保新的这个data node没有用之前的老的data node的/data数据。其实删除旧data Node挂了之后,需要清理/data目录的,新的data node也利用不了老的数据。但是为了防止删除数据失败,还是建议调度到不同的服务器。


2、client和master的/data目录都有持久化的数据吗?
  • client /data也有元数据信息,作为“smart router”来接受集群请求并转发。
  • master的/data目录也有集群元数据,不能和data node共享/data目录。


3、如何保证data node的HA?跨服务器,跨机架。

  • 首先给服务器打上机柜机架的Lable(esaas.hosts.rack=${rack_id})

  • 通过Pod Anti-affinity做Pod调度的反亲和性;


podAntiAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
  - weight: 100
    podAffinityTerm:
      labelSelector:
        matchExpressions:
        - key: es-cluster-name
          operator: In
          values:
          - ${es-cluster-name}
      topologyKey: esaas.hosts.rack=${rack_id} 


  • 注意使用requiredDuringSchedulingIgnoredDuringExecution类型的pod anti-affinity时,需要k8s admission controller disable LimitPodHardAntiAffinityTopology,否则会默认使用topologyKey: kubernetes.io/hostname,而不能使用自定义topologyKey。

  • 线上按照上面的方式进行跨机架部署,在开发测试环境,跨服务器部署就行了,使用topologyKey: kubernetes.io/hostname.


4、如何设置ES容器的vm属性vm.max_map_count?

  • 通过init container进行设置,要求init contaienr的privilege为true。

  • 所有类型的node(client, master, data)都默认使用一样的vm配置。

initContainers:
  - name: init-sysctl
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["sysctl", "-w", "vm.max_map_count=262144"]
    securityContext:
      privileged: true


5、如何关闭ES swap的配置?

  • 方法1:关闭物理服务器的swap;

  • 方法2:配置每个ES node的配置项bootstrap.mlockall: true,要求es容器添加CAP_IPC_LOCK,SYS_RESOURCE这两个Linux Capacity。

securityContext:
  privileged: false
  capabilities:
    add:
      - IPC_LOCK
      - SYS_RESOURCE


6、ES配置项minimum_master_nodes设置也是通过env注入,然后在容器启动脚本run.sh中重新生成elasticsearch.yml。
  • POD中注入环境变量NUMBER_OF_MASTERS;
  • 如果集群scale up/down后,可能需要动态设置这个环境变量;
  • 个人觉得,不人为设定ES集群的minimum_master_nodes配置项,由ES集群触发选举时自己根据master node数动态调整。


7、修改file descriptors,建议212644(64K)。
  • 修改容器内/etc/security/limits.conf, 也应该是需要privilege,或者对应Linux capability。


8、es data通过K8S StatefulSet部署,每个es data Pod都会通过volumeClaimTemplates创建对应的PV, 将宿主机上的/data/${es_cluster_name}挂载到es data容器内的/data目录。容器漂移或者recreate时,旧的服务器上es垃圾数据需要做清理。
  • HostPath PV支持Recycle这种Reclain Policy。(目前只有HostPath和NFS支持Recycle)
  • Recycle —> basic scrub (rm -rf /thevolume/*)


9、scale down 和 scale up时具体分别该如何操作?

  • scale down/up es-clients,直接按照HA的思路进行scale,无需其他操作;

  • scale down/up es-masters,按照HA的思路进行scale后,需要调ES接口修改minimum_master_nodes。

  • scale down/up es-datas, 按照HA的思路进行scale up后,无需其他操作;scale down时,需要将对应hostpath上的目录(数据)进行清理。每次缩容只允许减1个es data node,scale down操作前需要检查:
    • ES集群的监控状态是green;
    • 确保缩容后,max(index1.replicas, index2.replicas,…) + 1 < data-node-num
    • 其他检查


10、某个物理服务器要下线,该如何操作?
  • 第3点提到HA方案,可以保证每个服务器上最多只会存在某个ES集群中的单个cient/master/data节点,因此服务器下线最多只会down掉ES集群的单个cient/master/data节点,对于正规的ES集群是不影响的。这种情况,直接在服务器上执行kubectl drain将deployment,StatefulSet pods驱逐出去,并会自动在其他合适的服务器上recreate一个新的cient/master/data节点。ES集群在整个过程中始终保持正常工作。
  • 如果用户部署的是单节点的ES实例,那么按照上面的步骤,必然会导致用户的数据丢失,ES服务长时间不能用。因此需要对用户进行风险提示,并建议先进行扩容,然后待新节点同步数据完成后,才能干掉原来的es实例。


11、某个服务器突然down了,接下来是什么自动流程?
  • 服务器down了以后,由于调度部署时考虑了HA,因此不会影响正规的ES集群的使用。
  • 接着大概5min(通过pod-eviction-timeout设置)时间,会在新的Node上recreate新的client/master/data容器。这样就继续维持原有ES集群的规模。


12、ES插件的安装流程?
  • CaaS集群内部提供ElastcSearch Plugin仓库,存放常用插件提供下载;
  • 用户在初始化部署ES集群时可以选择想要安装plugins(支持site和jar类型),在init container中下载插件文件到plugin-volume,ES启动时自动加载这些plugins;
  • 如果在ES集群使用过程中用户想安装plugins,对于site类型的plugin,调用Kubernetes exec接口下载对应Site plugin文件到对应的插件目录即可;对于jar类型的plugin,同样的先现在插件到对应的plugin-volume目录,由于需要重启ES实例,通过执行kubectl exec POD_NAME -c CONTAINER_NAME reboot 或者 docker kill $containerName来重启ES容器而不用recreate Pod。
  • 由于多个ES不能共享同一个plugin目录,因此需要给每个ES实例都划分独立的plugin-volume,挂载宿主机上不同的hostpath;
    对于ES管理类plugin,需要指定插件部署到哪个ES node上(建议部署在某个master node上),后面访问该plugin只能通过访问该ES node的plugin API;
  • 对于ES功能类plugin(比如ik分词器),需要在所有ES集群 nodes(client, master, data)上安装该plugin。
  • 安装jar插件重启es节点前,必须检查es集群健康状态为green。
  • es节点重启时,注意ES的Fault Detection机制,配置discovery.zen.fd.ping_interval(1s), ping_timeout(30s),ping_retries(3),也就是说默认90s内没ping通就认为节点失败,然后进行分片迁移。我们关注这个配置,有需要可以适当调大。
  • 讨论决定,先只支持jar类型的插件,后续考虑sites类的插件(比如通过ESaaS本地存放sites plugin,所有ES集群共用)


13、自研ES监控工具如何与ES集群对接?
  • 监控工具支持API动态增加ES集群信息,只需要把集群中任一node(client/master/data)的IP和Port(9200)添加到监控工具中,有client就给client的信息,如果只有data node,则给data node的9200到监控工具;
  • ESaaS创建ES集群时,配置是否自动添加到监控平台,如果是,则部署完ES集群后回调监控平台的”ADD_ES_CLUSTER“接口;
  • ESaaS页面提供到监控平台的跳转链接,由监控平台做好监控信息的权限管理。监控添加ES集群时需要带上用户的ID。


14、Kibana服务的部署如何与ES集群对接?
  • 初始化部署ES集群时,用户可以勾选是否一并自动创建对应的Kibana服务;
  • 也提供单独创建Kibana服务的页面入口,要求用户选择对接的ES集群;
  • 通过注入环境变量ELASTICSEARCH_URL: http://es-client.namespace-1.svc.pro.es::9200


15、所有ES nodes的elasticsearch.yaml中的discovery hosts只需要配置master nodes的域名或者IP列表,当然如果配置所有的(client, data, master nodes)IP列表,也不会有异常。

16、初始化创建ES集群的时候,注意确保成功启动所有master nodes后,再去创建data nodes。client nodes的创建顺序没有要求。

17、ES node的JVM内存配置,支持8,16,32g。最大不允许超过32g,否则反而会因为GC问题等导致性能更差。

18、ES集群的日志收集,接入EFK日志系统。同时提供ES集群各个容器的web console能力,让用户能在web console查看(慢)日志等操作。

19、ES zen discovery我们通过域名(K8S Service Name)来解析es master IP List, 需要注意hosts.resolve_timeout,默认5s。

20、ES 2.x和5.x,6.x在node角色划分不一样,目前我只考了2.x版本,5.x和6.x需做适度调整。

21、引导检查
  • Heap size check 堆大小检查

  • File descriptor check 文件描述符(文件句柄)检查

    • 启动报错:max file descriptors [65535] for elasticsearch process likely too low, increase to at least [65536]

    • 解决方式:ulimit -n 65536 或者 vi /etc/security/limits.conf

    soft nofile 65536
    hard nofile 65536

  • Memory lock check 内存锁住检查

  • Maximum number of threads check 线程最大值检查

    • 启动报错:max number of threads [1024] for user [push] is too low, increase to at least [2048]

    • 解决方法:vi /etc/security/limits.d/90-nproc.conf
      soft nproc 2048

  • Maximum size virtual memory check 虚拟内存最大值检查

  • Maximum map count check map count最大值检查

    • 启动报错:max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

    • 解决方法:vi /etc/sysctl.conf
      vm.max_map_count=262144
      sysctl -p

  • Client JVM check JVM客户端检查
  • Use serial collector check

  • System call filter check
    • 启动报错:system call filters failed to install; check the logs and fix your configuration or disable system call filters at your own risk
    • 解决方法:elasticsearch.yml加上bootstrap.system_call_filter: false

  • OnError and OnOutOfMemoryError checks
  • Early-access check
  • G1GC check G1垃圾回收器检查


22、用户在ESaaS Portal上自助申请ES集群时,除了指定每个nodes的cpu,mem之外,还需要指定需要的本地存储空间大小,Kubernetes 1.9在调度时需要考虑服务器存储空间是否能满足需求。

原文链接:https://my.oschina.net/jxcdwangtao/blog/1621106

0 个评论

要回复文章请先登录注册