一、集群规划

  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. MATLAB中均值、方差、均方差的计算方法

    MATLAB中均值.方差.均方差的计算方法     1. 均值 数学定义: Matlab函数:mean >>X=[1,2,3] >>mean(X)=2 如果X是一个矩阵,则其均 ...

  2. Spring学习(六)--Spring的IOC

    1.autowiring(自动依赖装配)的实现 自动装配中不需要对Bean属性做显示的依赖管理方式,只需要配置好autowiring的属性就可以,IOC容器会自动根据这个属性的配置通过反射自动找到属性 ...

  3. java.lang.illegalArgumentException异常

    今天在使用spring3.2的时候,配置好注解开发后,运行出现异常 java.lang.illegalArgumentException 经查为 JRE 版本域spring3.2不兼容所致, 将项目J ...

  4. Python-字符编码-Unicode UTF-8

    什么是字符编码? --世界上有很多国家,每个国家都有自己独特的语言,所以在计算机普及的当今世界, 每个国家都有自己的字符编码,本国的软件运行在其他国家的机器上,会出现乱码, 有utf-8,gbk等各种 ...

  5. shiro认证流程源码分析--练气初期

    写在前面 在上一篇文章当中,我们通过一个简单的例子,简单地认识了一下shiro.在这篇文章当中,我们将通过阅读源码的方式了解shiro的认证流程. 建议大家边读文章边动手调试代码,这样效果会更好. 认 ...

  6. VID和PID

    今天很在一份datasheet上突然看到 VID 和 PID 很奇怪!!还不是很懂!!! 参考:https://blog.csdn.net/gaojinshan/article/details/787 ...

  7. Linux 安装Navicat Premium 15

    参考:https://gitee.com/andisolo/navicat-keygen 安装 aptitude 管理软件 $ sudo apt-get install aptitude 安装Navi ...

  8. ucore操作系统学习笔记(二) ucore lab2物理内存管理分析

    一.lab2物理内存管理介绍 操作系统的一个主要职责是管理硬件资源,并向应用程序提供具有良好抽象的接口来使用这些资源. 而内存作为重要的计算机硬件资源,也必然需要被操作系统统一的管理.最初没有操作系统 ...

  9. day29 Pyhton 面向对象 继承进阶

    一.内容回顾 初识继承 父类\基类\超类 子类\派生类 派生 :派生方法.派生属性 单继承 继承的语法class子类名(父类名) 解决开发中代码冗余的问题 子类继承了父类之后,可以调用父类中的方法 如 ...

  10. 接口管理平台Yapi

    1.介绍 YApi 是由去哪儿移动架构组推出的一款开源项目,是高效.易用.功能强大的 api 管理平台,旨在为开发.产品.测试人员提供更优雅的接口管理服务. 官网:https://yapi.ymfe. ...