一、集群信息

  • 方法因人而异,但大同小异,以下是我的部署方法。
  • elasticsearch 与 kibana 必须同一个版本来部署
  • 性能不够还是别跑了。
  • Kubernetes master 节点最小 2 核 2G 内存。
  • Kubernetes node 节点最小 1 核 2G 内存。
  • 性能实在性能不够,副本跑 1 个,2 个节点就是了。
  • 虽然 node 节点看起来能跑,但是随便跑点东西就吃紧,怎么说也要 2G 内存起步。

1.1、 主机信息

主机名 ip地址 描述 核心 内存
node-01 192.168.8.131 master 节点 2核 8G
node-02 192.168.8.132 node 节点 2核 8G
node-03 192.168.8.133 node 节点 2核 8G
node-04 192.168.8.134 node 节点 2核 8G

1.2、版本说明

服务 版本
helm 3.1.1
Kibana 7.9.1
Filebeat 7.9.1
Kubernetes 1.17.3
Elasticsearch 7.9.1
nfs-client-provisioner 1.2.8

二、部署 NFS 服务

2.1、 安装 NFS 与 rpcbind 服务

#   创建 NFS 存储目录
mkdir -p /data/NFS
#   安装nfs服务
yum -y install nfs-utils rpcbind
#   修改配置文件
echo "/data/NFS *(rw,sync,no_root_squash,no_subtree_check)" > /etc/exports
#   启动服务
systemctl start nfs && systemctl start rpcbind
#   设置开机启动
systemctl enable nfs-server && systemctl enable rpcbind

2.2、集群节点安装 nfs

#   安装nfs服务
yum -y install nfs-utils
kubectl create ns nfs

3.2、创建 EFK 存储目录

  • 该存储目录专门存放 EFK 数据包括: Elasticsearch Fluentd Kibana 数据
mkdir -p /data/NFS/EFK

3.3、使用 helm 安装 nfs-client-provisioner

  • 安装到 nfs 命名空间
  • 重点:nfs.path 让数据存储到指定目录,这样好区分数据
  • 重点:storageClass.name 这里填写 monitoring 专属名称,用于 PVC 自动绑定专属动态 PV 上。
#   下面代码直接复制黏贴即可
cat > elastic-client.yaml << EOF
# NFS 设置
nfs:
  server: 192.168.8.131
  path: /data/NFS/EFK
storageClass:
  # 此配置用于绑定 PVC 和 PV
  name: elastic-nfs-client
  # 资源回收策略
  reclaimPolicy: Retain
# 使用镜像
image:
  repository: kubesphere/nfs-client-provisioner
# 副本数量
replicaCount: 3
EOF

#   helm 部署 Prometheus 安装指定版本 Prometheus 5.0.4
helm install elastic-nfs-storage -n nfs --values elastic-client.yaml stable/nfs-client-provisioner --version 1.2.8

3.4、查看运行 nfs-client-provisioner Pod 状态

[root@Node-01 ~]# kubectl get pod -n nfs -w
NAME                                                             READY   STATUS    RESTARTS   AGE
efk-nfs-storage-nfs-client-provisioner-57d6c64f6b-hqb9p          1/1     Running   0          4s
efk-nfs-storage-nfs-client-provisioner-57d6c64f6b-jj5vr          1/1     Running   0          4s

四、部署 Elasticsearch

  • 内存低于 2G 可能会崩溃
  • 由于之前创建动态 PV 当节点启动完成会自动挂载目录,无需再次创建 PV

4.1、 创建 EFK 集群名称空间

  • 创建一个 monitoring 名称空间,将 efk 放在这个名称空间上
kubectl create ns efk

4.2、 添加 Helm Elastic 储存库

#   添加 helm elastic 储存库
helm repo add elastic https://helm.elastic.co

4.3、Elasticsearch 节点说明

  • es-master 搭建一个 elasticsearch 至少需要 3 个 Pod 以防止集群脑裂。
  • es-data 数据节点至少需要 2 个 Pod 。数据节点将保留数据、接收查询和索引请求。
  • es-client 做为协调 elasticsearch 集群。至少需要 2 个。用于集群连接,并充当 HTTP 代理。如果不使用 es-clinet 那么 es-data 充当协调,尽量避免在较大的集群上这样做。
集群名称 节点名称 节点角色 副本数量 分配空间 网络模式 备注
es-aka master master: "true" ingest: "false" data: "false" 3 4Gi ClusterIP 主节点
es-aka data master: "false" ingest: "false" data: "true" 3 60Gi ClusterIP 数据节点
es-aka client master: "false" ingest: "false" data: "false" 2 null NodePort 连接节点

4.4、开启 Elasticsearch 集群安全

4.4.1、 生成证书脚本
  • 新建脚本文件,运行成功后,会在目录生成证书
cat <<'EOF'> es-security.sh
#   拷贝下面内容到脚本中
#!/bin/bash
# 指定 elasticsearch 版本
RELEASE=7.9.1
# 运行容器生成证书
docker run --name elastic-charts-certs -i -w /app \
  elasticsearch:${RELEASE} \
  /bin/sh -c " \
    elasticsearch-certutil ca --out /app/elastic-stack-ca.p12 --pass '' && \
    elasticsearch-certutil cert --name security-master --dns security-master --ca /app/elastic-stack-ca.p12 --pass '' --ca-pass '' --out /app/elastic-certificates.p12" && \
# 从容器中将生成的证书拷贝出来
docker cp elastic-charts-certs:/app/elastic-certificates.p12 ./ && \
  # 证书生成成功该容器删除
  docker rm -f elastic-charts-certs && \
  openssl pkcs12 -nodes -passin pass:'' -in elastic-certificates.p12 -out elastic-certificate.pem
EOF
4.4.2、生成集群证书
  • 运行完成会获得 elastic-certificate.pem 与 elastic-certificates.p12
#   赋予脚本运行权限并运行
chmod +x es-security.sh && ./es-security.sh
4.4.3、添加证书到 K8S
  • 添加到集群命名空间 efk 中
  • 添加证书与设置集群密码
#   添加证书
kubectl create secret -n efk generic elastic-certificates --from-file=elastic-certificates.p12
kubectl create secret -n efk generic elastic-certificate-pem --from-file=elastic-certificate.pem
#   设置集群用户名密码,用户名不建议修改
kubectl create secret -n efk generic elastic-credentials  --from-literal=password=akiraka --from-literal=username=elastic

4.5、部署 es-master 节点

  • 副本数量 3
  • 创建配置文件
  • es-master 节点 PVC 创建 4Gi
  • 安装 Elasticsearch 7.9.1 版本
  • 如果数据持久化 master 也要做持久化否则一旦master与data节点断开 uuid就对不上了
#   下面代码直接复制黏贴即可
cat <<'EOF'> es-master.yaml
---
# 使用镜像
image: "elasticsearch"
# es 集群名称
clusterName: "es-aka"
# es 节点名称
nodeGroup: "master"
# es 节点角色
roles:
  master: "true"
  ingest: "false"
  data: "false"
# 副本数量
replicas: 3
# 资源限制
resources:
  requests:
    cpu: "300m"
    memory: "1Gi"
  limits:
    cpu: "1000m"
    memory: "2Gi"
volumeClaimTemplate:
  # 该volume只能被单个节点以读写的方式映射
  accessModes: [ "ReadWriteOnce" ]
  # 自动绑定动态 pv
  storageClassName: "elastic-nfs-client"
  resources:
    requests:
      storage: 4Gi
#   是否启用 PVC
persistence:
  enabled: true
# 是否 SSH 开启改为 https
protocol: http
# 添加配置
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # 是否启用 htpps 启用 head 无法连接,开启还需要将 protocol 修改为 https
    # xpack.security.http.ssl.enabled: true
    # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
# 环境变量
extraEnvs:
  - name: ELASTIC_PASSWORD
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: password
  - name: ELASTIC_USERNAME
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: username
# 证书
secretMounts:
  - name: elastic-certificates
    secretName: elastic-certificates
    path: /usr/share/elasticsearch/config/certs
EOF

#   helm 部署 es-master 节点并安装指定版本 elasticsearch 7.9.1
helm install es-master -n efk --values es-master.yaml elastic/elasticsearch --version 7.9.1

4.6、部署 es-data 节点

  • 副本数量 3
  • 创建配置文件
  • es-data 节点 PVC 创建 60Gi
  • 安装 Elasticsearch 7.9.1 版本
#   下面代码直接复制黏贴即可
cat <<'EOF'> es-data.yaml
---
# 使用镜像
image: "elasticsearch"
# es 集群名称
clusterName: "es-aka"
# es 节点名称
nodeGroup: "data"
# es 节点角色
roles:
  master: "false"
  ingest: "true"
  data: "true"
# 副本数量
replicas: 3
# 资源限制
resources:
  requests:
    cpu: "300m"
    memory: "1Gi"
  limits:
    cpu: "1000m"
    memory: "2Gi"
# PVC
volumeClaimTemplate:
  # 该volume只能被单个节点以读写的方式映射
  accessModes: [ "ReadWriteOnce" ]
  # 自动绑定动态 pv
  storageClassName: "elastic-nfs-client"
  resources:
    requests:
      storage: 60Gi
# 是否 SSH 开启改为 https
protocol: http
# 添加配置
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # 是否启用 htpps 启用 head 无法连接,开启还需要将 protocol 修改为 https
    # xpack.security.http.ssl.enabled: true
    # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
# 环境变量
extraEnvs:
  - name: ELASTIC_PASSWORD
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: password
  - name: ELASTIC_USERNAME
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: username
# 证书
secretMounts:
  - name: elastic-certificates
    secretName: elastic-certificates
    path: /usr/share/elasticsearch/config/certs
EOF

#   helm 部署 es-data 节点并安装指定版本 elasticsearch 7.9.1
helm install es-data -n efk --values es-data.yaml elastic/elasticsearch --version 7.9.1

4.7、部署 es-client 节点

  • 副本数量 2
  • 创建配置文件
  • es-client 无需创建 PV
  • 安装 Elasticsearch 7.9.1 版本
  • 默认为: NodePort 固定端口: 30920
#   下面代码直接复制黏贴即可
cat <<'EOF'> es-client.yaml
---
# 使用镜像
image: "elasticsearch"
# es 集群名称
clusterName: "es-aka"
# es 节点名称
nodeGroup: "client"
# es 节点角色
roles:
  master: "false"
  ingest: "false"
  data: "false"
# 副本数量
replicas: 2
# 资源限制
resources:
  requests:
    cpu: "300m"
    memory: "1Gi"
  limits:
    cpu: "1000m"
    memory: "2Gi"
#   是否启用 PVC
persistence:
  enabled: false
# 设置 es-clinet 默认为 NodePort
service:
  type: NodePort
  # 设置 NodePort 默认端口
  nodePort: 30920
# 是否 SSH 开启改为 https
protocol: http
# 添加配置
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # 是否启用 htpps 启用 head 无法连接,开启还需要将 protocol 修改为 https
    # xpack.security.http.ssl.enabled: true
    # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
# 环境变量
extraEnvs:
  - name: ELASTIC_PASSWORD
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: password
  - name: ELASTIC_USERNAME
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: username
# 证书
secretMounts:
  - name: elastic-certificates
    secretName: elastic-certificates
    path: /usr/share/elasticsearch/config/certs
EOF

#   helm 部署 es-client 节点并安装指定版本 elasticsearch 7.9.1
helm install es-client -n efk --values es-client.yaml elastic/elasticsearch --version 7.9.1

五、查看 Elasticsearch 部署状态

5.1、查看 Elasticsearch Pv 状态

  • 之前创建的动态 PV 就在这里体现了。
  • 可以看到 PVC 与 PV 均已绑定成功。
[root@Node-01 ~]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                               STORAGECLASS     REASON   AGE
pvc-b8d12daf-6ea1-431c-a259-230b5a3c3c08   60Gi       RWO            Retain           Bound    efk/es-aka-data-es-aka-data-0       elastic-nfs-client            3m16s
pvc-ec1e34d2-b732-4959-b1de-57afd32d62d4   60Gi       RWO            Retain           Bound    efk/es-aka-data-es-aka-data-1       elastic-nfs-client            3m16s
pvc-0bc003b3-3cea-4816-8dd2-e264729db108   60Gi       RWO            Retain           Bound    efk/es-aka-data-es-aka-data-2       elastic-nfs-client            3m16s
pvc-6a8725fa-e1c8-415d-802f-49a180f60ed1   4Gi        RWO            Retain           Bound    efk/es-aka-master-es-aka-master-0   elastic-nfs-client            4m56s
pvc-d2384c3b-035b-4bde-8749-96c8ffd68f54   4Gi        RWO            Retain           Bound    efk/es-aka-master-es-aka-master-1   elastic-nfs-client            4m56s
pvc-f28c610a-c709-40e3-b937-42b8ed74b001   4Gi        RWO            Retain           Bound    efk/es-aka-master-es-aka-master-2   elastic-nfs-client            4m55s

5.2、查看 Elasticsearch Pod 状态

  • 2 个 es-master 部署完成
  • 3 个 es-data 部署完成
  • 1 个 es-client 部署完成
[root@Node-01 ~]# kubectl get pods --namespace=efk  -w
NAME              READY   STATUS    RESTARTS   AGE
es-aka-data-0     1/1     Running   0          4m29s
es-aka-data-1     1/1     Running   0          4m29s
es-aka-data-2     1/1     Running   0          4m29s
es-aka-client-0   1/1     Running   0          3m41s
es-aka-client-1   1/1     Running   0          3m41s
es-aka-master-0   1/1     Running   0          6m9s
es-aka-master-1   1/1     Running   0          6m9s
es-aka-master-2   1/1     Running   0          6m9s

5.3、查看 Elasticsearch Svc 状态

  • elasticsearch-client 默认为: NodePort 固定端口: 30920
  • 除 elasticsearch-client 使用 NodePort 其余均为 ClusterIP
[root@Node-01 ~]# kubectl get svc -n efk
NAME                     TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                         AGE
es-aka-client            NodePort    10.1.25.120    <none>        9200:30920/TCP,9300:32696/TCP   4m17s
es-aka-client-headless   ClusterIP   None           <none>        9200/TCP,9300/TCP               4m17s
es-aka-data              ClusterIP   10.1.142.169   <none>        9200/TCP,9300/TCP               5m5s
es-aka-data-headless     ClusterIP   None           <none>        9200/TCP,9300/TCP               5m5s
es-aka-master            ClusterIP   10.1.28.147    <none>        9200/TCP,9300/TCP               6m45s
es-aka-master-headless   ClusterIP   None           <none>        9200/TCP,9300/TCP               6m45s

六、部署 Filebeat

6.1、 添加 Helm Elastic 储存库

#   添加 helm elastic 储存库
helm repo add elastic https://helm.elastic.co

6.2、使用 helm 安装 Filebeat

  • 安装 Filebeat 7.9.1 版本
  • 需要填写集群账号与密码
cat <<'EOF'> es-filebeat.yaml
# 覆盖资源的全名。如果未设置名称,则默认为 ".Release.Name-.Values.nameOverride or .Chart.Name"
fullnameOverride: filebeat
# 使用镜像
image: "elastic/filebeat"
# 添加配置
filebeatConfig:
  filebeat.yml: |
    filebeat.inputs:
    - type: docker
      containers.ids:
      - '*'
      processors:
      - add_kubernetes_metadata:
          in_cluster: true
    output.elasticsearch:
      # elasticsearch 用户
      username: 'elastic'
      # elasticsearch 密码
      password: 'akiraka'
      # elasticsearch 主机
      hosts: ["es-aka-client:9200"]
# 环境变量
extraEnvs:
  - name: 'ELASTICSEARCH_USERNAME'
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: username
  - name: 'ELASTICSEARCH_PASSWORD'
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: password
EOF

#   helm 安装指定版本 filebeat 7.9.1
helm install filebeat -n efk --values es-filebeat.yaml elastic/filebeat  --version 7.9.1

6.3、查看运行 Filebeat Pod 状态

[root@Node-01 ~]# kubectl get pods --namespace=efk -l app=filebeat-filebeat -w
NAME                      READY   STATUS    RESTARTS   AGE
filebeat-filebeat-7dp29   1/1     Running   0          24s
filebeat-filebeat-rp8kg   1/1     Running   0          24s
filebeat-filebeat-z4wcp   1/1     Running   0          24s

七、部署 Kibana

7.1、 添加 Helm Elastic 储存库

#   添加 helm elastic 储存库
helm repo add elastic https://helm.elastic.co

7.2、使用 helm 安装 Kibana

  • 安装 Kibana 7.9.1 版本
  • 设置 kibana 默认简体中文
  • Kibana 无需填写集群账号与密码
  • service.type 设置为: NodePort
  • service.nodePort 固定端口: 32323
  • elasticsearchHosts 填写集群地址,格式为: http://es-aka-client:9200
cat <<'EOF'> es-kibana.yaml
# 使用镜像
image: "kibana"
# 集群地址
elasticsearchHosts: "http://es-aka-client:9200"
# 添加配置
kibanaConfig:
  kibana.yml: |
    #  设置 kibana 简体中文
    i18n.locale: "zh-CN"
# 否 SSH 开启改为 https 确保集群也是 https
protocol: http
# 服务设置
service:
  type: NodePort
  nodePort: 32323
# 环境变量
extraEnvs:
  - name: 'ELASTICSEARCH_USERNAME'
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: username
  - name: 'ELASTICSEARCH_PASSWORD'
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: password
EOF

#   helm 安装指定版本 kibana 7.9.1
helm install kibana -n efk --values es-kibana.yaml elastic/kibana --version 7.9.1

7.3、查看运行 Kibana Pod 状态

[root@Node-01 ~]# kubectl get pods --namespace=efk -l app=kibana -w
NAME                             READY   STATUS    RESTARTS   AGE
kibana-kibana-6b65b974f5-w2gd6   1/1     Running   0          60s

八、访问仪表盘

8.1、 通过 Elasticsearch Head 访问

  • 其他浏览器我不清楚,Chrome 浏览器扩展商店搜索 ElasticSearch Head 然后安装该扩展
  • 条件已知 elasticsearch-client 使用了 NodePort 端口为: 30920
  • 使用方式: 集群随便一台机器 IP 地址,格式: http://节点IP:30920

8.2、访问 Kibana 仪表盘

  • Kibana 默认端口为:32323
  • 默认设置中文界面
  • 默认用户与密码为自己设置,我设置
  • 本集群默认用户为: elastic
  • 本集群默认用户为: akiraka

8.3、创建 Kibana 索引

  • 路径》管理》Kibana》索引模式》创建索引
  • 这里添加 Filebeat 索引



8.4、通过 Kibana 查看 Filebeat 日志