Kubernetes 部署 Elasticsearch + Kibana 指南

Kubernetes 部署 Elasticsearch + Kibana 指南

本文介绍如何在 Kubernetes 集群中部署 Elasticsearch 6.8.23 三节点集群与 Kibana 6.8.23 可视化面板。Elasticsearch 采用 DaemonSet 部署确保每个指定节点运行一个实例,Kibana 采用 Deployment 部署并通过 NodePort 对外暴露访问。


一、架构概述

组件 部署方式 节点数 端口 说明
Elasticsearch DaemonSet 3 :9200 / :9300 数据存储与检索引擎
Kibana Deployment 1 :5601 可视化面板
Service NodePort 1 :30056 → :5601 Kibana 外部访问入口

关键设计决策

  • DaemonSet — 每个标记节点精确运行一个 ES Pod,与节点绑定
  • hostNetwork: true — ES 直接使用宿主机网络,免去 Service 转发
  • hostAliases — Kibana Pod 内注入 ES 主机名解析
  • hostPath 挂载 — ES 数据和日志持久化到宿主机目录
  • postStart lifecycle — Pod 启动后自动设置 vm.max_map_countulimit

二、部署配置文件

完整的 elastic.yaml 配置:

2.1 Kibana Service

apiVersion: v1
kind: Service
metadata:
  labels:
    app: elastic-kibana
  name: elastic-kibana
  namespace: bjac-elastic
spec:
  type: NodePort
  ports:
    - port: 5601
      targetPort: 5601
      nodePort: 30056
  selector:
    app: elastic-kibana

2.2 Elasticsearch DaemonSet

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: elastic
  namespace: bjac-elastic
  labels:
    app: elastic
spec:
  selector:
    matchLabels:
      app: elastic
  template:
    metadata:
      labels:
        app: elastic
    spec:
      imagePullSecrets:
        - name: aliyunregsecret
      nodeSelector:
        elastic-server: "true"
      hostNetwork: true
      volumes:
      - name: elastic-data
        hostPath:
          path: /home/elastic/data
      - name: elastic-logs
        hostPath:
          path: /home/elastic/logs
      containers:
      - name: elastic
        env:
        - name: network.host
          value: "0.0.0.0"
        - name: transport.host
          value: "0.0.0.0"
        - name: discovery.zen.ping.unicast.hosts
          value: "elasticserver1"
        - name: discovery.zen.minimum_master_nodes
          value: "1"
        - name: cluster.name
          value: "k8s-es"
        - name: ES_JAVA_OPTS
          value: "-Xms8g -Xmx8g"
        - name: xpack.security.enabled
          value: "false"
        - name: xpack.monitoring.enabled
          value: "true"
        - name: xpack.ml.enabled
          value: "true"
        - name: xpack.graph.enabled
          value: "true"
        - name: xpack.watcher.enabled
          value: "true"
        - name: http.cors.enabled
          value: "true"
        - name: http.cors.allow-origin
          value: "*"
        image: registry.cn-beijing.aliyuncs.com/<YOUR_REPO>/es-cn:6.8.23
        lifecycle:
          postStart:
            exec:
              command:
              - /bin/sh
              - -c
              - |
                sysctl -w vm.max_map_count=262144
                ulimit -l unlimited
                ulimit -n 65536
        ports:
        - containerPort: 9200
        - containerPort: 9300
        volumeMounts:
        - name: elastic-data
          mountPath: /usr/share/elasticsearch/data/
        - name: elastic-logs
          mountPath: /usr/share/elasticsearch/logs/

2.3 Kibana Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: elastic-kibana
  name: elastic-kibana
  namespace: bjac-elastic
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elastic-kibana
  template:
    metadata:
      labels:
        app: elastic-kibana
    spec:
      hostAliases:
      - ip: "<ES_NODE_IP_1>"
        hostnames:
        - "elasticserver1"
      - ip: "<ES_NODE_IP_2>"
        hostnames:
        - "elasticserver2"
      - ip: "<ES_NODE_IP_3>"
        hostnames:
        - "elasticserver3"
      containers:
        - name: elastic-kibana
          env:
          - name: ELASTICSEARCH_URL
            value: "http://elasticserver1:9200"
          image: docker.elastic.co/kibana/kibana:6.8.23
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 5601
      nodeSelector:
        elastic-server: "true"

配置要点说明

配置项 说明
kind DaemonSet / Deployment ES 用 DaemonSet,Kibana 用 Deployment
hostNetwork true (ES) ES 直接使用宿主机网络栈
nodeSelector elastic-server: "true" 只在标记节点上部署
discovery.zen.ping.unicast.hosts elasticserver1 ES 集群节点发现(单播)
discovery.zen.minimum_master_nodes 1 最少 Master 节点数
ES_JAVA_OPTS -Xms8g -Xmx8g JVM 堆内存,建议设为相同值
xpack.security.enabled false 关闭安全认证(内网环境)
http.cors.enabled true 允许跨域请求(方便前端工具接入)
postStart lifecycle sysctl/ulimit Pod 启动后设置内核参数
hostAliases (Kibana) 3 个 ES 节点 IP Kibana 内通过主机名连接 ES

三、部署步骤

3.1 为节点打标签

kubectl get node --show-labels=true
kubectl label nodes <NODE_1> elastic-server=true
kubectl label nodes <NODE_2> elastic-server=true
kubectl label nodes <NODE_3> elastic-server=true

3.2 创建数据目录

每个 ES 节点上执行:

mkdir -p /home/elastic/data /home/elastic/logs
chmod -R 777 /home/elastic

3.3 配置内核参数

Elasticsearch 要求 vm.max_map_count 至少为 262144,在每个 ES 节点上执行:

cat <<EOF | tee -a /etc/sysctl.conf
vm.max_map_count = 262144
EOF

sysctl -w vm.max_map_count=262144

# 验证
grep vm.max_map_count /etc/sysctl.conf

说明:Pod 的 postStart hook 中也设置了此参数,但宿主机级别设置更可靠,Pod 内 sysctl 可能因权限不足而失败。

3.4 配置 hosts 解析

每个 ES 节点/etc/hosts 中添加:

echo "<ES_NODE_IP_1> elasticserver1" >> /etc/hosts
echo "<ES_NODE_IP_2> elasticserver2" >> /etc/hosts
echo "<ES_NODE_IP_3> elasticserver3" >> /etc/hosts

3.5 创建命名空间和镜像 Secret

kubectl create namespace bjac-elastic

kubectl create secret docker-registry aliyunregsecret \
  --docker-server=registry.cn-beijing.aliyuncs.com \
  --docker-username=<YOUR_USERNAME> \
  --docker-password=<YOUR_PASSWORD> \
  -n bjac-elastic

3.6 执行部署

kubectl apply -f elastic.yaml

3.7 验证部署

# 查看 Pod
kubectl get pod -n bjac-elastic -o wide

# 查看 Pod 详情(排错用)
kubectl -n bjac-elastic describe pod <POD_NAME>

# 查看 Pod 日志
kubectl -n bjac-elastic logs <ES_POD_NAME> --all-containers=true
kubectl -n bjac-elastic logs <KIBANA_POD_NAME> --all-containers=true

3.8 验证 Elasticsearch 集群

进入 ES Pod 检查集群状态:

kubectl exec -it pod/<ES_POD_NAME> -n bjac-elastic -- bash

curl http://localhost:9200/_cluster/health?pretty
curl http://localhost:9200/_cat/nodes?v

3.9 访问 Kibana

通过 NodePort 访问 Kibana 面板:

http://<ANY_NODE_IP>:30056

四、访问控制

生产环境中,Elasticsearch 的 9200 端口不应对外开放。通过 iptables 限制访问:

4.1 限制 9200 端口访问

# 默认拒绝所有 9200 端口访问
iptables -I INPUT -p tcp --dport 9200 -j DROP

# 允许内网网段访问
iptables -I INPUT -s <INTERNAL_SUBNET>/24 -p tcp --dport 9200 -j ACCEPT

# 允许指定 IP 访问
iptables -I INPUT -s <SPECIFIC_IP> -p tcp --dport 9200 -j ACCEPT

4.2 删除规则

iptables -D INPUT -p tcp --dport 9200 -j DROP
iptables -D INPUT -s <INTERNAL_SUBNET>/24 -p tcp --dport 9200 -j ACCEPT
iptables -D INPUT -s <SPECIFIC_IP> -p tcp --dport 9200 -j ACCEPT

最佳实践:iptables 规则的顺序很重要 — ACCEPT 规则必须在 DROP 规则之前(使用 -I 插入到链头),否则会被 DROP 规则拦截。


五、常见问题排查

问题 原因 解决方案
Pod 启动失败,max_map_count 错误 宿主机内核参数未设置 在宿主机执行 sysctl -w vm.max_map_count=262144
Pod 启动失败,ulimit 错误 容器内资源限制不足 确保 postStart hook 正确执行
集群无法发现节点 hosts 解析未配置 确保宿主机 /etc/hosts 配置正确
Kibana 无法连接 ES hostAliases 未配置 确保 Kibana Deployment 中 hostAliases 包含所有 ES 节点
数据目录权限错误 目录权限不足 chmod -R 777 /home/elastic
镜像拉取失败 Secret 未创建 创建 aliyunregsecret

六、注意事项

  1. vm.max_map_count 必须设置 — ES 6.x 要求此值至少 262144,否则无法启动
  2. 目录权限 — ES 进程需要对数据目录有写入权限,建议 chmod -R 777
  3. JVM 堆内存XmsXmx 建议设为相同值,避免动态调整带来的性能抖动
  4. minimum_master_nodes — 三节点集群建议设为 2,此处设为 1 是因为初始只有一个 Master
  5. xpack.security — 内网环境可关闭,公网环境必须开启并配置认证
  6. hostNetwork — ES 使用宿主机网络,9200/9300 端口直接绑定宿主机,需确保端口未被占用
  7. postStart hook — 容器内 sysctl 可能因权限问题失败,建议在宿主机层面持久化设置

附录:资源清单

资源类型 名称 数量
Namespace bjac-elastic 1
Service elastic-kibana (NodePort :30056) 1
DaemonSet elastic 3 Pod (按节点数)
Deployment elastic-kibana 1 Pod
Secret aliyunregsecret 1
hostPath Volume /home/elastic/data 每节点 1
hostPath Volume /home/elastic/logs 每节点 1

阅读更多

Skills系统:可扩展AI能力设计

Skills系统:可扩展AI能力设计

概述 Skills系统是AI-Native架构中的重要组件,它允许通过声明式配置扩展AI的能力。本文将介绍Skills系统的设计与实现,让大模型能够像人类专家一样具备特定领域的能力。 什么是Skills系统 概念 Skills(技能)是一种声明式的AI能力扩展机制,类似于人类的"专业技能": 通用AI助手 专业AI助手(带Skills) ┌──────────────────────┐ ┌──────────────────────────────┐ │ │ │ │ │ 用户:请帮我写代码 │ │ 用户:请帮我审查这段代码 │ │ │ │ │ │ AI:我是一个AI助手 │ │ AI:[激活

By 菱角
插件化架构设计模式

插件化架构设计模式

概述 插件化架构是一种将核心功能与扩展功能分离的设计模式,允许系统在运行时动态加载和卸载功能模块。本文将介绍如何在微服务平台中设计和实现插件化架构。 为什么需要插件化 插件化优势 1. 模块化:功能独立,边界清晰 2. 可扩展:按需加载,动态增删 3. 隔离性:插件间互不干扰 4. 可维护:独立开发、测试、部署 5. 可定制:用户按需选择功能 核心设计 架构概览 核心组件实现 1. 插件接口定义 // core/plugin.interface.ts // 插件接口 export interface IPlugin { // 插件名称 readonly name: string // 插件版本 readonly version: string // 插件配置 getConfig(): PluginConfig // 插件清单

By 菱角
gRPC服务通信设计与实践

gRPC服务通信设计与实践

概述 在微服务架构中,服务间通信是关键环节。相比REST API,gRPC提供了更高的性能和更强的类型安全。本文将介绍如何在微服务平台中设计和实现gRPC服务通信。 为什么选择gRPC gRPC vs REST对比 特性 gRPC REST 协议 HTTP/2 HTTP/1.1 序列化 Protocol Buffers (二进制) JSON (文本) 性能 高(二进制+压缩) 中(文本开销) 类型安全 强(代码生成) 弱(运行时检查) 流式通信 原生支持(双向流) 需额外实现(SSE/WebSocket) 代码生成 自动生成 手动编写 浏览器支持 需gRPC-Web 原生支持 调试难度

By 菱角
多语言微服务架构:Node.js与Python协作

多语言微服务架构:Node.js与Python协作

概述 在微服务架构中,根据场景选择最适合的编程语言是最佳实践。本文将介绍如何在微服务平台中实现Node.js与Python的协作,发挥各自技术优势。 技术选型策略 为什么混合使用 服务划分 Node.js服务(7个) 服务 功能 选择Node.js的原因 llm.api 大模型服务 高并发SSE流式响应 ucenter.api 用户中心 RESTful API标准实践 doc.api 文件服务 流式上传下载处理 resource.api 资源管理 gRPC高性能通信 rag.api 知识库服务 MongoDB集成便利 statistic.api 统计分析 事件驱动架构 pptonline.api PPT服务 与前端技术栈统一 Python服务(1个) 服务 功能 选择Python的原因

By 菱角