概述
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
方案细节和注意事项
- 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也利用不了老的数据。但是为了防止删除数据失败,还是建议调度到不同的服务器。
- client和master的/data目录都有持久化的数据吗?
- client /data也有元数据信息,作为“smart router”来接受集群请求并转发。
- master的/data目录也有集群元数据,不能和data node共享/data目录。
- 如何保证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.
- 如何设置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
- 如何关闭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
- ES配置项
minimum_master_nodes
设置也是通过env注入,然后在容器启动脚本run.sh中重新生成elasticsearch.yml。- POD中注入环境变量
NUMBER_OF_MASTERS
; - 如果集群scale up/down后,可能需要动态设置这个环境变量;
- 个人觉得,不人为设定ES集群的
minimum_master_nodes
配置项,由ES集群触发选举时自己根据master node数动态调整。
- POD中注入环境变量
- 修改file descriptors,建议212644(64K)。
- 修改容器内/etc/security/limits.conf, 也应该是需要privilege,或者对应Linux capability。
- 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/*)
- 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
- 其他检查
- 某个物理服务器要下线,该如何操作?
- 第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实例。
- 某个服务器突然down了,接下来是什么自动流程?
- 服务器down了以后,由于调度部署时考虑了HA,因此不会影响正规的ES集群的使用。
- 接着大概5min(通过pod-eviction-timeout设置)时间,会在新的Node上recreate新的client/master/data容器。这样就继续维持原有ES集群的规模。
- 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集群共用)
- 自研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。
- Kibana服务的部署如何与ES集群对接?
- 初始化部署ES集群时,用户可以勾选是否一并自动创建对应的Kibana服务;
- 也提供单独创建Kibana服务的页面入口,要求用户选择对接的ES集群;
- 通过注入环境变量ELASTICSEARCH_URL: http://es-client.namespace-1.svc.pro.es::9200
- 所有ES nodes的elasticsearch.yaml中的discovery hosts只需要配置master nodes的域名或者IP列表,当然如果配置所有的(client, data, master nodes)IP列表,也不会有异常。
- 初始化创建ES集群的时候,注意确保成功启动所有master nodes后,再去创建data nodes。client nodes的创建顺序没有要求。
- ES node的JVM内存配置,支持8,16,32g。最大不允许超过32g,否则反而会因为GC问题等导致性能更差。
- ES集群的日志收集,接入EFK日志系统。同时提供ES集群各个容器的web console能力,让用户能在web console查看(慢)日志等操作。
- ES zen discovery我们通过域名(K8S Service Name)来解析es master IP List, 需要注意hosts.resolve_timeout,默认5s。
- ES 2.x和5.x,6.x在node角色划分不一样,目前我只考了2.x版本,5.x和6.x需做适度调整。
- 引导检查
- 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
- 启动报错:max virtual memory areas
- 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垃圾回收器检查
- 用户在ESaaS Portal上自助申请ES集群时,除了指定每个nodes的cpu,mem之外,还需要指定需要的本地存储空间大小,Kubernetes 1.9在调度时需要考虑服务器存储空间是否能满足需求。