一、集群规划

  1. 由于当前环境中没有分布式存储,所以只能使用本地 PV 的方式来实现数据持久化。
  2. ES 集群的 master 节点至少需要三个,防止脑裂。
  3. 由于 master 在配置过程中需要保证主机名固定和唯一,所以搭建 master 使用 StatefulSet 控制器
  4. node 节点需要固定的主机名和固定的物理节点以及物理节点上的本地PV,所以需要使用 StatefulSet,配合 StorageClass 来固定。
  5. kibana为无状态服务,使用deployment。

二、修改 elasticsearch 镜像

在部署 elasticsearch 的时候建议配置 memlock:true,这个要求系统必须配置ulimit。所以需要修改镜像,使其在容器内自动执行。

Dockerfile 内容如下:

FROM docker.elastic.co/elasticsearch/elasticsearch:7.3.0

MAINTAINER haha@xxx.com

COPY run.sh /
RUN chmod 755 /run.sh CMD ["/run.sh"]

run.sh 脚本内容如下:

#!/bin/bash

ulimit -l unlimited

exec su elasticsearch /usr/local/bin/docker-entrypoint.sh

elasticsearch 用户是官方镜像中已经创建好的用户

在 Dockerfile 目录中执行如下命令构建镜像:

docker build --tag elasticsearch:7.3.0 -f Dockerfile .

构建完成的镜像可以选择推送到私有镜像仓库中,也可以选择将镜像导出到本地,然后再导入到各个 k8s node 节点中。这里选择首先将镜像导出到本地:

docker save elasticsearch:7.3.0 -o elasticsearch_ulimit_7.3.0.tar

再将镜像导入到各个 node 节点中:

docker load --input elasticsearch_ulimit_7.3.0.tar

三、创建命名空间

将 ES 集群统一放到一个单独的命名空间中,yaml 文件内容如下:

---
apiVersion: v1
kind: Namespace
metadata:
name: ns-elasticsearch
labels:
name: ns-elasticsearch

四、创建 ServiceAccount 并绑定角色

设置 ES 使用单独的 ServiceAccount,所以需要手动创建一个并分配进群角色,yaml 文件内容如下:

---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
elastic-app: elasticsearch
name: elasticsearch-admin
namespace: ns-elasticsearch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: elasticsearch-admin
labels:
elastic-app: elasticsearch
rules: # 根据需要配置相应的api/资源/权限
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","watch","list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: elasticsearch-admin
labels:
elastic-app: elasticsearch
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: elasticsearch-admin
namespace: ns-elasticsearch

五、创建本地持久化存储

1. 存储规划

首先在 k8s-node1 至 k8s-node5 节点中创建 /opt/es/es-node-data 目录,用于存储 ES Data 节点的数据。在 k8s-node3 至 k8s-node5 节点中创建 /opt/es/es-master-data 目录用于存储 ES Master 节点的数据。在 k8s-node3 节点中创建 /opt/es/kibana-data 目录用于存储 kibana 数据。需要注意的是,es-node-data、es-master-data、kibana-data 这三个目录都需要设置 777 权限。

2. 设置 label

为了确保 Pod 调度到指定机器中,需要设置以下 label:

  • 为 k8s-node1 至 k8s-node5 节点添加 es-data-node=true 标签;
kubectl label nodes k8s-node1 es-data-node=true
kubectl label nodes k8s-node2 es-data-node=true
kubectl label nodes k8s-node3 es-data-node=true
kubectl label nodes k8s-node4 es-data-node=true
kubectl label nodes k8s-node5 es-data-node=true
  • 为 k8s-node3 至 k8s-node5 节点添加 es-data-master=true 标签;
kubectl label nodes k8s-node3 es-data-master=true
kubectl label nodes k8s-node4 es-data-master=true
kubectl label nodes k8s-node5 es-data-master=true
  • 为 k8s-node3 节点添加 es-kibana-data=true 标签;
kubectl label nodes k8s-node3 es-kibana-data=true

3. 创建 StorageClass

创建 StorageClass 的 yaml 文件内容如下:

---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-es-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer # 绑定模式为等待消费者,即当Pod分配到节点后,进行与PV的绑定

4. 创建 PV 和 PVC

由于有三个服务需要进行持久化存储,所以需要创建三个 PV 和 PVC。

4.1 ES Master 存储

创建用于 ES Master 节点数据存储的 PV 和 PVC yaml 文件内容如下:

---
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-es-master-pv
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 200Gi
local:
path: /opt/es/es-master-data # 需要在指定的节点创建相应的目录
nodeAffinity: # 指定节点,对节点配置label
required:
nodeSelectorTerms:
- matchExpressions:
- key: es-data-master
operator: In
values:
- "true"
persistentVolumeReclaimPolicy: Retain # 回收策略为保留,不会删除数据,即当pod重新调度的时候,数据不会发生变化.
storageClassName: local-es-storage ---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: local-es-master-pvc
namespace: ns-elasticsearch
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-es-storage
resources:
requests:
storage: 200Gi
4.2 ES Node 存储

创建用于 ES Node 节点数据存储的 PV 和 PVC yaml 文件内容如下:

---
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-es-node-pv
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 1024Gi
local:
path: /opt/es/es-node-data # 需要在指定的节点创建相应的目录
nodeAffinity: # 指定节点,对节点配置label
required:
nodeSelectorTerms:
- matchExpressions:
- key: es-data-node
operator: In
values:
- "true"
persistentVolumeReclaimPolicy: Retain # 回收策略为保留,不会删除数据,即当pod重新调度的时候,数据不会发生变化.
storageClassName: local-es-storage
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: local-es-node-pvc
namespace: ns-elasticsearch
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-es-storage
resources:
requests:
storage: 1024Gi
4.3 Kibana 存储

创建用于 Kibana 节点数据存储的 PV 和 PVC yaml 文件内容如下:

---
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-kibana-pv
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 2Gi
local:
path: /opt/es/kibana-data # 需要在指定的节点创建相应的目录
nodeAffinity: # 指定节点,对节点配置label
required:
nodeSelectorTerms:
- matchExpressions:
- key: es-kibana-data
operator: In
values:
- "true"
persistentVolumeReclaimPolicy: Retain # 回收策略为保留,不会删除数据,即当pod重新调度的时候,数据不会发生变化.
storageClassName: local-es-storage
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: local-kibana-pvc
namespace: ns-elasticsearch
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-es-storage
resources:
requests:
storage: 2Gi

六、创建 ES Master 节点

1. 创建 StatefulSet

Master 主节点采用三个节点的方式,避免出现脑裂的情况,由于Master所占资源较低,可以配置其容忍 k8s 主节点的污点并调度到该节点上,yaml 文件内容如下:

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
elastic-app: elasticsearch
role: master
name: elasticsearch-master
namespace: ns-elasticsearch
spec:
replicas: 3
serviceName: elasticsearch-discovery # 用于给每一个pod提供一个podname.serviceName的域名进行访问.
selector:
matchLabels:
elastic-app: elasticsearch
role: master
template:
metadata:
labels:
elastic-app: elasticsearch
role: master
spec:
serviceAccountName: elasticsearch-admin
restartPolicy: Always
containers:
- name: elasticsearch-master
image: elasticsearch:7.3.0
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "20480Mi"
cpu: "1000m"
securityContext:
privileged: true # 获取root权限,这样才能进行初始化命令执行.
lifecycle:
postStart: # 初始化命令,配置系统参数
exec:
command:
- /bin/bash
- -c
- sysctl -w vm.max_map_count=262144; ulimit -l unlimited;
ports: # 开放端口一个是集群端口,一个是数据端口
- containerPort: 9200
protocol: TCP
- containerPort: 9300
protocol: TCP
env: # 环境变量,非容器下在配置文件配置的,这里对应配置为环境变量就可以了
- name: cluster.name
value: "es_cluster"
- name: bootstrap.memory_lock
value: "true"
- name: node.master
value: "true"
- name: node.data
value: "false"
- name: discovery.seed_hosts
value: "elasticsearch-discovery"
- name: cluster.initial_master_nodes
value: "elasticsearch-master-0,elasticsearch-master-1,elasticsearch-master-2"
- name: node.ingest
value: "false"
- name: ES_JAVA_OPTS
value: "-Xms10g -Xmx10g"
volumeMounts:
- name: es-master-data
mountPath: /usr/share/elasticsearch/data
volumes:
- name: es-master-data
persistentVolumeClaim:
claimName: local-es-master-pvc
tolerations: # 使其可以运行在k8s主节点上
- effect: NoSchedule
key: node-role.kubernetes.io/master

2. 创建 Service

Master 主节点不需要对外暴露端口,所以 yaml 文件内容如下:

---
kind: Service
apiVersion: v1
metadata:
labels:
elastic-app: elasticsearch
name: elasticsearch-discovery
namespace: ns-elasticsearch
spec:
ports:
- port: 9300
targetPort: 9300
selector:
elastic-app: elasticsearch
role: master

七、创建 ES Data 节点

1. 创建 StatefulSet

Data 节点用于存储收集到的日志信息,为了便于部署,此次实施将 Ingest 和 Data 节点部署在一起(在配置文件中同时启动 data 和 ingest),yaml 文件内容如下:

apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
elastic-app: elasticsearch
role: node
name: elasticsearch-node
namespace: ns-elasticsearch
spec:
replicas: 5
serviceName: elasticsearch-service
selector:
matchLabels:
elastic-app: elasticsearch
role: node
template:
metadata:
labels:
elastic-app: elasticsearch
role: node
spec:
serviceAccountName: elasticsearch-admin
restartPolicy: Always
containers:
- name: elasticsearch-node
lifecycle:
postStart:
exec:
command: ["/bin/bash", "-c", "sysctl -w vm.max_map_count=262144; ulimit -l unlimited;"]
image: elasticsearch:7.3.0
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "30720Mi"
cpu: "2000m"
securityContext:
privileged: true
ports:
- containerPort: 9200
protocol: TCP
- containerPort: 9300
protocol: TCP
env:
- name: cluster.name
value: "es_cluster"
- name: "bootstrap.memory_lock"
value: "true"
- name: node.master
value: "false"
- name: node.data
value: "true"
- name: discovery.seed_hosts
value: "elasticsearch-discovery"
- name: cluster.initial_master_nodes
value: "elasticsearch-master-0,elasticsearch-master-1,elasticsearch-master-2,elasticsearch-master-3,elasticsearch-master-4"
- name: node.ingest
value: "true"
- name: ES_JAVA_OPTS
value: "-Xms10g -Xmx10g"
volumeMounts:
- name: es-node-data
mountPath: /usr/share/elasticsearch/data # 需要localPV绑定到该目录,这个官方指定的容器内数据目录
volumes:
- name: es-node-data
persistentVolumeClaim:
claimName: local-es-node-pvc

2. 创建 Service

需要将 Data 节点的 9200 端口暴露出来,同时也用于 Ingest 接收 Filebeat 传送过来的日志信息,yaml 文件内容如下:

---
kind: Service
apiVersion: v1
metadata:
labels:
elastic-app: elasticsearch-service
name: elasticsearch-service
namespace: ns-elasticsearch
spec:
ports:
- port: 9200
protocol: TCP
targetPort: 9200
selector:
elastic-app: elasticsearch
type: NodePort

八、创建 Kibana

1. 创建 Deployment

Kibana 作为一个无状态服务,直接使用 Deployment 创建即可,yaml 文件内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
name: kibana
labels:
elastic-app: kibana
namespace: ns-elasticsearch
spec:
replicas: 1
selector:
matchLabels:
elastic-app: kibana
template:
metadata:
name: kibana
labels:
elastic-app: kibana
spec:
serviceAccountName: elasticsearch-admin
restartPolicy: Always
containers:
- name: kibana
image: kibana:7.3.0
imagePullPolicy: IfNotPresent
env:
- name: SERVER_NAME
value: "kibana"
- name: SERVER_HOST
value: "0.0.0.0"
- name: ELASTICSEARCH_HOSTS
value: "http://elasticsearch-service.ns-elasticsearch:9200"
- name: I18N_LOCALE
value: zh-CN
volumeMounts:
- name: kibana-data
mountPath: /usr/share/kibana/data
volumes:
- name: kibana-data
persistentVolumeClaim:
claimName: local-kibana-pvc

2. 创建 Service

需要将 Kibana 的 5601 端口暴露出来,yaml 文件内容如下:

---
apiVersion: v1
kind: Service
metadata:
name: kibana-service
labels:
elastic-app: kibana-service
namespace: ns-elasticsearch
spec:
ports:
- port: 5601
targetPort: 5601
selector:
elastic-app: kibana
type: NodePort

Kibana 创建完成后查看 Service 信息:

[@k8s-master1 ~]# kubectl get svc -n ns-elasticsearch
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch-discovery ClusterIP 10.102.167.126 <none> 9300/TCP 77m
elasticsearch-service NodePort 10.101.60.203 <none> 9200:30187/TCP 74m
kibana-service NodePort 10.98.206.184 <none> 5601:31837/TCP 73m

可以看到将 Kibana 的 5601 端口映射到 31837 端口中,直接在浏览器中使用 NodeIP:31837 即可访问 Kibana 页面。

九、启动 Filebeat 收集日志

在此次实施过程中没有在 K8S 的 POD 中安装 filebeat,所以直接使用物理机中已有的 filebeat 服务。

首先在 /opt/filebeat-7.3.0/conf 目录下(提前在 /opt 目录下安装 filebeat)创建一个名为 ES-test.yml 的配置文件,内容如下:

filebeat.idle_timeout: 2s
filebeat.inputs:
- backoff: 1s
backoff_factor: 2
close_inactive: 1h
enabled: true
encoding: plain
harvester_buffer_size: 262144
max_backoff: 10s
max_bytes: 10485760
paths:
- /opt/test.log
scan_frequency: 10s
tail_lines: true
type: log
filebeat.name: filebeat-shiper
filebeat.spool_zie: 50000
output.elasticsearch:
bulk_max_size: 8192
hosts:
- k8s-node1:30187
index: es-test
workers: 4
processors:
- drop_fields:
fields:
- agent.ephemeral_id
- agent.hostname
- agent.id
- agent.type
- agent.version
- ecs.version
- input.type
- log.offset
- version
- decode_json_fields:
fields:
- message
max_depth: 1
overwrite_keys: true
setup.ilm.enabled: false
setup.template.name: es-test
setup.template.pattern: es-test-*

启动 filebeat:

nohup /opt/filebeat-7.3.0/filebeat run -c /opt/filebeat-7.3.0/conf/ES-test.yml -httpprof 0.0.0.0:18521 -path.logs /opt/filebeat-7.3.0/logs/filebeat_18521 &

此时在 kibana 中可以看到新建了一个名为 es-test 的索引,根据这个索引创建对应的索引模式,即可查看收集的相关日志。

十、查看 ES 集群状态

通过查看 Service 信息可以看到 ES Data node 节点暴露出来的端口号信息:

[@k8s-master1 ~]# kubectl get svc -n ns-elasticsearch
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch-discovery ClusterIP 10.102.167.126 <none> 9300/TCP 77m
elasticsearch-service NodePort 10.101.60.203 <none> 9200:30187/TCP 74m
kibana-service NodePort 10.98.206.184 <none> 5601:31837/TCP 73m

9200 对外映射的端口为 30187,在浏览器中输入 NodeIP:30187/_cat/nodes?v 可以查看到各个节点的信息:

[@k8s-master1 ~]# curl http://10.11.16.211:30187/_cat/nodes?v
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
100.111.156.90 59 29 2 0.25 0.28 0.48 di - elasticsearch-node-0
100.102.107.215 11 33 2 0.43 0.51 0.70 di - elasticsearch-node-4
100.67.139.19 1 17 1 0.40 0.39 0.59 m * elasticsearch-master-0
100.100.52.26 1 17 1 0.31 0.36 0.60 m - elasticsearch-master-1
100.67.139.20 39 17 2 0.40 0.39 0.59 di - elasticsearch-node-2
100.102.107.214 1 33 2 0.43 0.51 0.70 m - elasticsearch-master-2
100.100.52.27 30 17 1 0.31 0.36 0.60 di - elasticsearch-node-3
100.64.169.149 53 26 2 0.69 0.74 0.79 di - elasticsearch-node-1

在浏览器中输入 NodeIP:30187/_cat/health?v 可以查看集群的健康信息:

[@k8s-master1 ~]# curl http://10.11.16.211:30187/_cat/health?v
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks
1594709799 06:56:39 es_cluster green 8 5 34 17 0 0 0 0

Kubernetes 搭建 ES 集群(存储使用 local pv)的更多相关文章

  1. Kubernetes 搭建 ES 集群(存储使用 cephfs)

    一.集群规划 使用 cephfs 实现分布式存储和数据持久化 ES 集群的 master 节点至少需要三个,防止脑裂. 由于 master 在配置过程中需要保证主机名固定和唯一,所以搭建 master ...

  2. 本地虚拟机搭建ES集群

    一.环境说明 1.物理机信息(主要): 内存:8G 系统/主频:Win7(旗舰版)64位/3.70GHZ 2.虚拟机信息: VMware Workstation 14 Pro 下载地址: 链接:htt ...

  3. 搭建ES集群

    服务版本选择 TEG的ctsdb当前最高版本采用的是es的6.4.3版本,为了日后与ctsdb衔接方便,部署开源版es时也采用该版本.6.4.3版本的es依赖的jdk版本要求在8u181以上,测试环境 ...

  4. ELK搭建<一>:搭建ES集群

    1.首先进入官网下载ES,如果下载最新之前的版本 点击past releases就行了. 2.解压后进入config修改配置文件elasticsearch.yml #集群名称 cluster.name ...

  5. Docker搭建ES集群

    Spring Boot连接ES,spring-boot-starter-data-elasticsearch. 必须为集群方式!否则报错! 报错: None of the configured nod ...

  6. elasticsearch系列八:ES 集群管理(集群规划、集群搭建、集群管理)

    一.集群规划 搭建一个集群我们需要考虑如下几个问题: 1. 我们需要多大规模的集群? 2. 集群中的节点角色如何分配? 3. 如何避免脑裂问题? 4. 索引应该设置多少个分片? 5. 分片应该设置几个 ...

  7. ES 集群管理(集群规划、集群搭建、集群管理)

    一.集群规划 搭建一个集群我们需要考虑如下几个问题: 1. 我们需要多大规模的集群? 2. 集群中的节点角色如何分配? 3. 如何避免脑裂问题? 4. 索引应该设置多少个分片? 5. 分片应该设置几个 ...

  8. elasticsearch 集群管理(集群规划、集群搭建、集群管理)

    一.集群规划 搭建一个集群我们需要考虑如下几个问题: 1. 我们需要多大规模的集群? 2. 集群中的节点角色如何分配? 3. 如何避免脑裂问题? 4. 索引应该设置多少个分片? 5. 分片应该设置几个 ...

  9. 通过docker搭建ELK集群

    单机ELK,另外两台服务器分别有一个elasticsearch节点,这样形成一个3节点的ES集群. 可以先尝试单独搭建es集群或单机ELK https://www.cnblogs.com/lz0925 ...

随机推荐

  1. 源码分析springboot自定义jackson序列化,默认null值个性化处理返回值

    最近项目要实现一种需求,对于后端返回给前端的json格式的一种规范,不允许缺少字段和字段值都为null,所以琢磨了一下如何进行将springboot的Jackson序列化自定义一下,先看看如何实现,再 ...

  2. SpringBoot一统江湖

    一 SpringBoot简介 SpringBoot是Spring框架的一个新子项目 用于创建Spring4.0项目 它的开发始于2013年 2014年4月发布1.0.0版本 它可以自动配置Spring ...

  3. Kafka处理请求的全流程分析

    大家好,我是 yes. 这是我的第三篇Kafka源码分析文章,前两篇讲了日志段的读写和二分算法在kafka索引上的应用 今天来讲讲 Kafka Broker端处理请求的全流程,剖析下底层的网络通信是如 ...

  4. JVM内存模型不再是秘密

    前言 上篇文章我们一起了解了jvm虚拟机类的加载机制,而且是以一种纯大白话进行的一场闲聊,相信小伙伴们应该印象深刻,感兴趣的小伙伴可以重温一下上一篇文章大白话谈JVM的类加载机制. 当jvm加载了类后 ...

  5. Solr常见异常

    RemoteSolrException: Expected mime type application/octet-stream but got text/html 解决方法: 在使用Tomcat部署 ...

  6. 【Vulhub】CVE-2019-3396 Confluence RCE漏洞复现

    CVE-2019-3396 Confluence RCE漏洞复现 一.环境搭建 选择的vulhub里的镜像,进入vulhub/Confluence/CVE-2019-3396目录下,执行 docker ...

  7. 007 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 01 Java标识符

    007 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 01 Java标识符 Java变量与常量主要内容 Java变量与常量主要内容如下,主要是对以下内容的学习,没 ...

  8. Charles 模拟弱网

    1.Charles安装方法: 1)在官网下载安装: 2)输入如下注册码破解,Charles 4.2.7 目前版本,可用. Registered Name: https://zhile.io       ...

  9. 多台centos7服务器实现SSH免密登陆

    一.环境 centos7.x 三台 node1.node2.node3 二.实现免密登陆 2.1.node1上,生成公钥与私钥 [root@node1 ~]# ssh-keygen Generatin ...

  10. postgresql 和 mysql 数据库备份恢复以及时区问题

    概要 postgesql 12 备份/恢复脚本 时区设置 mysql 5.6 备份/恢复脚本 时区设置 概要 postgresql 和 mysql 是最常用的 2 种开源关系数据库, 很多项目也会优先 ...