在 Kubernetes 上部署生产级 Elasticsearch 集群:基于 examples 仓库的三角色分离实战指南 示例工程【免费下载链接】examplesKubernetes application example tutorials项目地址https://gitcode.com/gh_mirrors/examp/examples点击查看免费下载导读本文基于 Kubernetes 官方示例仓库examples中的_archived/elasticsearch/production_cluster/目录系统讲解如何在 Kubernetes 上构建一个遵循 Elasticsearch 官方最佳实践、按Master / Client / Data三种角色分离的生产级集群。你将掌握从 ServiceAccount 与 RBAC 准备、两个 Service 与三个 ReplicationController 的完整配置解读到分阶段部署、日志验证、按角色扩缩容以及通过curl访问集群的完整流程并理解其中的cloud-kubernetes插件发现机制与存储选型要点。为什么需要三角色分离Master / Client / Data在生产环境中Elasticsearch 官方最佳实践建议将节点按职责划分为三种角色避免全能节点带来的相互干扰如数据节点参与选举造成索引压力与集群稳定性冲突角色职责是否存储数据是否开放 HTTP API9200集群端口9300Master仅负责集群管理、状态维护与节点选举否否是Client面向客户端请求的入口负责路由与转发否是是Data存储与索引实际数据是否是本示例中的三份 ReplicationController 清单严格执行了这一约定其角色差异正是通过环境变量NODE_MASTER、NODE_DATA、HTTP_ENABLE的组合实现的详见下文分角色 ReplicationController 详解。注意本示例_archived/elasticsearch/production_cluster/使用的 Elasticsearch 版本为1.7.1是 Kubernetes 早期实践中颇具代表性的范例仓库根目录 _archived/elasticsearch/README.md 还提供了5.6.2的单节点es-rc.yamlall-in-one 角色简化示例可作为对照阅读。依赖组件镜像、插件与集群发现机制Docker 镜像所有三种角色的容器统一使用预构建镜像quay.io/pires/docker-elasticsearch-kubernetes:1.7.1-4该镜像在容器启动时读取环境变量来配置节点角色见 es-master-rc.yaml。若你需要定制镜像请 fork 后同步修改所有 RC 清单中的image字段。cloud-kubernetes 插件与集群发现节点间的自动发现依赖io.fabric8:elasticsearch-cloud-kubernetes插件。从 master 节点日志可以看到插件被加载的痕迹[plugins] [Arc] loaded [cloud-kubernetes], sites []该插件通过调用 Kubernetes API 查询endpoints资源动态获取同一命名空间下 Elasticsearch 节点的地址列表从而实现无需手工维护 discovery.zen.ping.unicast.hosts 列表的自动组网。正因为如此集群需要一个具有最小权限的 Kubernetes 身份来读取 endpoints——这正是 ServiceAccount 与 RBAC 清单存在的意义。前置准备ServiceAccount 与 RBAC1. 创建 ServiceAccountservice-account.yaml 定义了一个名为elasticsearch的 ServiceAccount三个 RC 的 Pod 模板均通过serviceAccount: elasticsearch字段绑定它apiVersion: v1 kind: ServiceAccount metadata: name: elasticsearch2. RBAC为插件授权 endpoints 读取权限如果集群开启了 RBAC 授权模式还需要创建 rbac.yaml 中定义的Role与RoleBindingapiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: elasticsearch rules: - apiGroups: - resources: - endpoints verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: elasticsearch roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: elasticsearch subjects: - kind: ServiceAccount name: elasticsearch namespace: default该Role仅授予对endpoints资源的get权限是典型的最小权限实践——插件只需要这一项能力即可完成节点发现。两个 Service 的分工elasticsearch-discovery面向 Master 的传输层服务es-discovery-svc.yaml 通过selectorcomponent: elasticsearch, role: master将流量路由到所有 Master 节点仅暴露 9300 传输端口。它是集群内部节点相互发现、建立 gossip 通信的枢纽apiVersion: v1 kind: Service metadata: name: elasticsearch-discovery labels: component: elasticsearch role: master spec: selector: component: elasticsearch role: master ports: - name: transport port: 9300 protocol: TCPelasticsearch面向客户端的 HTTP 服务es-svc.yaml 的selector匹配 Client 节点component: elasticsearch, role: client对外暴露 9200 HTTP 端口type: LoadBalancer声明了云环境下的外部负载均衡支持是否启用取决于集群环境见下文访问服务apiVersion: v1 kind: Service metadata: name: elasticsearch labels: component: elasticsearch role: client spec: type: LoadBalancer selector: component: elasticsearch role: client ports: - name: http port: 9200 protocol: TCP分角色 ReplicationController 详解三份 RC 清单结构几乎一致差异集中在环境变量与端口声明上。以 Master 为例es-master-rc.yamlapiVersion: v1 kind: ReplicationController metadata: name: es-master labels: component: elasticsearch role: master spec: replicas: 1 template: metadata: labels: component: elasticsearch role: master spec: serviceAccount: elasticsearch containers: - name: es-master securityContext: capabilities: add: - IPC_LOCK image: quay.io/pires/docker-elasticsearch-kubernetes:1.7.1-4 env: - name: KUBERNETES_CA_CERTIFICATE_FILE value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: CLUSTER_NAME value: myesdb - name: NODE_MASTER value: true - name: NODE_DATA value: false - name: HTTP_ENABLE value: false ports: - containerPort: 9300 name: transport protocol: TCP volumeMounts: - mountPath: /data name: storage volumes: - name: storage emptyDir: {}环境变量决定节点角色所有 RC 都注入四个核心环境变量容器启动脚本据此生成对应的elasticsearch.yml配置环境变量MasterClientData作用CLUSTER_NAMEmyesdbmyesdbmyesdb集群名三份清单必须一致否则节点无法加入同一集群NODE_MASTERtruefalsefalse是否具备 master 选举资格NODE_DATAfalsefalse未设置是否存储数据Data 节点未显式设置镜像默认启用数据存储HTTP_ENABLEfalsetruefalse是否开放 9200 HTTP 接口关键细节Master 与 Data 均关闭 HTTPHTTP_ENABLEfalse仅暴露 9300 传输端口避免不必要的攻击面与资源开销仅 Client 开放 HTTPHTTP_ENABLEtrue对外暴露 9200 与 9300 两个端口作为所有请求的统一入口KUBERNETES_CA_CERTIFICATE_FILE指向 ServiceAccount 自动挂载的 CA 证书/var/run/secrets/kubernetes.io/serviceaccount/ca.crt用于插件访问 Kubernetes API 时校验 TLSNAMESPACE通过fieldRef: fieldPath: metadata.namespace动态注入插件据此确定查询 endpoints 的命名空间securityContext.capabilities.add: [IPC_LOCK]允许容器锁定内存满足 Elasticsearch 对mlockall内存锁定的要求防止堆内存被交换到磁盘。端口与存储Master/Data 仅声明9300/transportClient 同时声明9200/http与9300/transport每个数据节点的容器将/data挂载到emptyDir卷——这是刻意简化的演示选择emptyDir的生命周期与 Pod 绑定Pod 重建或节点重启后数据即丢失。生产环境应根据实际存储需求替换为 PersistentVolume见 Kubernetes 持久卷文档例如使用 PVC 或 StatefulSet 管理有状态数据。部署流程严格按角色顺序分阶段创建部署必须分阶段、按序进行先创建基础设施ServiceAccount、Service、RBAC再创建 Master等待其就绪并完成选举后创建 Client最后创建 Data。这与先有 master 集群视图、后有节点加入的 Elasticsearch 组网逻辑一致。第 1 步创建 ServiceAccount 与两个 Servicekubectl create -f _archived/elasticsearch/production_cluster/service-account.yaml kubectl create -f _archived/elasticsearch/production_cluster/es-discovery-svc.yaml kubectl create -f _archived/elasticsearch/production_cluster/es-svc.yaml kubectl create -f _archived/elasticsearch/production_cluster/es-master-rc.yaml若集群启用了 RBAC再创建Role与RoleBindingkubectl create -f _archived/elasticsearch/rbac.yaml第 2 步等待 es-master 就绪创建 Clientkubectl create -f _archived/elasticsearch/production_cluster/es-client-rc.yaml第 3 步等待 es-client 就绪创建 Datakubectl create -f _archived/elasticsearch/production_cluster/es-data-rc.yaml验证集群Pod 状态与 Master 日志检查 Pod 状态$ kubectl get pods NAME READY STATUS RESTARTS AGE es-client-2ep9o 1/1 Running 0 2m es-data-r9tgv 1/1 Running 0 1m es-master-vxl6c 1/1 Running 0 6m三个 Pod 分别对应三种角色均处于Running状态。解读 Master 日志$ kubectl logs es-master-vxl6c日志中的关键节点事件序列[2015-08-21 10:58:51,542][INFO ][plugins] [Arc] loaded [cloud-kubernetes], sites [] [2015-08-21 10:58:57,782][INFO ][transport] [Arc] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/10.244.15.2:9300]} [2015-08-21 10:59:05,167][INFO ][cluster.service] [Arc] new_master [Arc][...][es-master-vxl6c][inet[/10.244.15.2:9300]]{datafalse, mastertrue}, reason: zen-disco-join (elected_as_master) [2015-08-21 11:02:28,797][INFO ][cluster.service] [Arc] added {[Gideon][...][es-data-r9tgv][inet[/10.244.59.4:9300]]{masterfalse},}, reason: zen-disco-receive(join from node[[Gideon]... [2015-08-21 11:03:16,822][INFO ][cluster.service] [Arc] added {[Venomm][...][es-client-2ep9o][inet[/10.244.53.2:9300]]{datafalse, masterfalse},}, reason: zen-disco-receive(join from node[[Venomm]...阅读要点loaded [cloud-kubernetes]确认发现插件已加载publish_address {inet[/10.244.15.2:9300]}Master 节点在集群内网发布自己的传输地址elected_as_master首个节点通过 zen 发现被选举为 master集群状态收敛added {[Gideon]...{masterfalse}}与added {[Venomm]...{masterfalse}}Data 与 Client 节点相继加入注意日志中明确标注了各节点的角色属性masterfalse/data缺省证明角色分离按预期生效。按角色扩缩容扩缩容同样按角色独立进行粒度比单节点示例更精细。例如将 Master 扩到 3 个高可用选举、Client 与 Data 各扩到 2 个kubectl scale --replicas3 rc es-master kubectl scale --replicas2 rc es-client kubectl scale --replicas2 rc es-data验证结果$ kubectl get pods NAME READY STATUS RESTARTS AGE es-client-2ep9o 1/1 Running 0 4m es-client-ye5s1 1/1 Running 0 50s es-data-8az22 1/1 Running 0 47s es-data-r9tgv 1/1 Running 0 3m es-master-57h7k 1/1 Running 0 52s es-master-kuwse 1/1 Running 0 52s es-master-vxl6c 1/1 Running 0 8m从 Master 日志可以确认新增节点均已通过 zen 发现加入集群[2015-08-21 11:04:40,781][INFO ][cluster.service] [Arc] added {[Erik Josten][...][es-master-kuwse][inet[/10.244.59.5:9300]]{datafalse, mastertrue},} [2015-08-21 11:04:41,076][INFO ][cluster.service] [Arc] added {[Power Princess][...][es-master-57h7k][inet[/10.244.53.3:9300]]{datafalse, mastertrue},} [2015-08-21 11:04:53,966][INFO ][cluster.service] [Arc] added {[Cagliostro][...][es-client-ye5s1][inet[/10.244.15.3:9300]]{datafalse, masterfalse},} [2015-08-21 11:04:56,803][INFO ][cluster.service] [Arc] added {[Thog][...][es-data-8az22][inet[/10.244.15.4:9300]]{masterfalse},}可以看到新增 Master 节点的属性为{datafalse, mastertrue}新增 Client 为{datafalse, masterfalse}新增 Data 仅{masterfalse}三种角色各司其职。补充说明单节点示例_archived/elasticsearch/es-rc.yaml的扩缩容则是kubectl scale --replicas3 rc es一次性调整所有节点且日志中会出现discovery.zen.minimum_master_nodes过低告警生产级三角色方案通过独立 RC 避免了这类问题并允许针对每种角色设置不同的副本数。访问服务注意Kubernetes 中的 Service 默认仅对集群内可达运行kube-proxy的节点或集群内容器。若需从集群外访问应配置外部负载均衡器type: LoadBalancer。虽然 es-svc.yaml 已声明该类型但启用外部 LB 不在本文范围内。查看服务$ kubectl get service elasticsearch NAME LABELS SELECTOR IP(S) PORT(S) elasticsearch componentelasticsearch,roleclient componentelasticsearch,roleclient 10.100.134.2 9200/TCP在任意运行kube-proxy的主机上curl http://10.100.134.2:9200预期返回节点信息{ status : 200, name : Cagliostro, cluster_name : myesdb, version : { number : 1.7.1, build_hash : b88f43fc40b0bcd7f173a1f9ee2e97816de80b19, build_timestamp : 2015-07-29T09:54:16Z, build_snapshot : false, lucene_version : 4.10.4 }, tagline : You Know, for Search }注意响应中的name是某个 Client 节点的随机名称此处为Cagliostro说明请求被路由到了 Client 层。检查集群健康状态curl http://10.100.134.2:9200/_cluster/health?pretty预期返回扩缩容后为 7 节点、2 个数据节点状态green{ cluster_name : myesdb, status : green, timed_out : false, number_of_nodes : 7, number_of_data_nodes : 2, active_primary_shards : 0, active_shards : 0, relocating_shards : 0, initializing_shards : 0, unassigned_shards : 0, delayed_unassigned_shards : 0, number_of_pending_tasks : 0, number_of_in_flight_fetch : 0 }status: green表示所有分片均已正确分配集群可用。生产化改造要点持久化存储当前三个 RC 均使用emptyDir卷es-data-rc.yaml仅用于演示。生产环境应基于 PersistentVolume/PersistentVolumeClaim 提供独立于 Pod 生命周期的数据卷并评估是否需要 StatefulSet 来保证稳定的网络标识与存储绑定最小权限 RBAC本文的Role仅授予endpoints的get权限扩缩容、跨命名空间部署时应同步调整RoleBinding的namespace版本说明本示例基于 Elasticsearch1.7.1其配置项如NODE_MASTER/NODE_DATA/HTTP_ENABLE与现代版本5.x 的node.master/node.data等存在差异应用时请结合目标版本核对。总结本示例通过三个 ReplicationController 两个 Service 一个 ServiceAccount/RBAC的组合在 Kubernetes 上构建了角色严格分离的 Elasticsearch 生产级集群Master 负责选举与集群状态、Client 承载 HTTP 入口、Data 专注数据存储三者通过elasticsearch-discovery服务与cloud-kubernetes插件自动组网并可借助kubectl scale按角色独立扩缩容。仓库内所有清单es-master-rc.yaml、es-client-rc.yaml、es-data-rc.yaml、es-discovery-svc.yaml、es-svc.yaml、rbac.yaml均可直接作为理解 Kubernetes 有状态应用编排与 Elasticsearch 运维的最佳教材。赞分享示例工程【免费下载链接】examplesKubernetes application example tutorials项目地址https://gitcode.com/gh_mirrors/examp/examples点击查看免费下载相关推荐ComfyUI插件安装教程从入门到精通的插件管理指南ComfyUI插件安装教程从入门到精通的插件管理指南 ComfyUI作为强大的AI图像生成工具其扩展性很大程度上依赖于插件系统。本教程将帮助你掌握ComfyBitnami Elasticsearch Helm Chart 实战指南从单节点部署到生产级多角色集群Bitnami Elasticsearch Helm Chart 实战指南从单节点部署到生产级多角色集群 本篇指南以仓库中的 bitnami/elastics云原生容器编排SkyWalking OAP 高级部署指南基于 Mixed / Receiver / Aggregator 角色的集群角色拆分与 Kubernetes 实践SkyWalking OAP 高级部署指南基于 Mixed / Receiver / Aggregator 角色的集群角色拆分与 Kubernetes 实践可观测性后端微服务云原生上一篇显卡驱动彻底清理终极指南DDU工具解决NVIDIA、AMD、Intel驱动残留问题下一篇怎样完整备份QQ空间历史数据3步完成终极数据导出指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考