基于Kubernetes构建日志收集系统-搭建Elasticsearch集群(一)

 
简介
当您在kubernetes集群上,部署了很多服务和应用。这时,你应该需要一个集群级别的日志收集器,来帮助您快速整理和分析由您的Pods生成的大量日志数据。现在一种流行的解决方案是,采用Elasticsearch,Fluentd,Kibana。
ElasticSearch 通常采用三类型节点部署,由master、data、client节点构成。出于资源可以最大化的利用,方便后期扩容,我们部署3个类型的节点。client节点用于接收请求,内存可以高一些。data 节点用于存储数据,磁盘空间很重要。
思路
容器使用stdout/stderr 方式,将日志输出到宿主机。我们可以在容器logs目录(/var/log/containers/),查看生成的容器日志文件。之后使用fluentd读取日志文件内容,输入到Elasticsearch中,Kibana读取Elasticsearch 进行图形化界面展示。如下图所示。
 
0
正文
第一步:创建命令空间
在部署Elasticsearch集群之前,我们将首先创建一个命名空间,在其中安装所有日志记录工具。 在本指南中,我们将创建一个kube-logging命名空间,将EFK组件安装到该命名空间中。 该命名空间还将使我们能够快速清理并删除EFK,而不会给Kubernetes 集群带来任何功能损失。
 
创建一个kube-logging.yaml 文件。
touch kube-logging.yaml
在kube-logging.yaml 文件中,写入如下代码。
kind: Namespace
apiVersion: v1
metadata:
  name: kube-logging
使用kubectl create -f 执行这个文件。
kubectl create -f kube-logging.yaml
执行后,你可以看到如下输出。
namespace/kube-logging created
你也可以使用kubectl get namespaces 命令,确认命名空间是否创建成功。
kubectl get namespaces
你应该会看到如下输出。
NAME           STATUS    AGE
default        Active    23m
kube-logging   Active    1m
kube-public    Active    23m
kube-system    Active    23m
如果你看到,输出值中包含kube-logging,恭喜你第一步已经成功了。
 
第二步:部署ElasticSearch master(主节点)
集群中,第一个节点是master 节点,它负责控制集群。新建一个elasticsearch-master-configmap.yaml文件,写入一些ElasticSearch 配置参数,启用security模块(x-pack安全验证)。yaml文件内容如下:
---
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: kube-logging
  name: elasticsearch-master-config
  labels:
    app: elasticsearch
    role: master
data:
  elasticsearch.yml: |-
    cluster.name: ${CLUSTER_NAME}
    node.name: ${NODE_NAME}
    discovery.seed_hosts: ${NODE_LIST}
    cluster.initial_master_nodes: ${MASTER_NODES}
    network.host: 0.0.0.0
    node:
      master: true
      data: false
      ingest: false
    xpack.security.enabled: true
    xpack.monitoring.collection.enabled: true
---
然后,新建对应的Service yaml文件,命名elasticsearch-master-service.yaml。yaml文件内容如下:
---
apiVersion: v1
kind: Service
metadata:
  namespace: kube-logging
  name: elasticsearch-master
  labels:
    app: elasticsearch
    role: master
spec:
  ports:
  - port: 9300
    name: transport
  selector:
    app: elasticsearch
    role: master
---
最后, 新建Deployment (部署)yaml文件,命名elasticsearch-master-deployment.yaml。yaml文件内容如下:
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: kube-logging
  name: elasticsearch-master
  labels:
    app: elasticsearch
    role: master
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
      role: master
  template:
    metadata:
      labels:
        app: elasticsearch
        role: master
    spec:
      containers:
      - name: elasticsearch-master
        image: docker.elastic.co/elasticsearch/elasticsearch:7.3.0
        env:
        - name: CLUSTER_NAME
          value: elasticsearch
        - name: NODE_NAME
          value: elasticsearch-master
        - name: NODE_LIST
          value: elasticsearch-master,elasticsearch-data,elasticsearch-client
        - name: MASTER_NODES
          value: elasticsearch-master
        - name: "ES_JAVA_OPTS"
          value: "-Xms256m -Xmx256m"
        ports:
        - containerPort: 9300
          name: transport
        volumeMounts:
        - name: config
          mountPath: /usr/share/elasticsearch/config/elasticsearch.yml
          readOnly: true
          subPath: elasticsearch.yml
        - name: storage
          mountPath: /data
      volumes:
      - name: config
        configMap:
          name: elasticsearch-master-config
      - name: "storage"
        emptyDir:
          medium: ""
      initContainers:
      - name: increase-vm-max-map
        image: busybox
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        securityContext:
          privileged: true
---
使用如下命令执行yaml文件。
kubectl apply -f elasticsearch-master-configmap.yaml -f elasticsearch-master-service.yaml -f elasticsearch-master-deployment.yaml
使用如下命令,检查是否部署成功。
kubectl get pods -n kube-logging
下图为部署成功的状态:
 
0
 
 
第三步:部署ElasticSearch data node(数据节点)
集群的第二个节点设置为数据节点,里面保存存储的数据。我们这时候,需要一个持久卷来保证数据的高可靠性。我这里面使用的NFS存储日志数据。现在我们创建一个yaml文件,使用ConfigMap(配置对象) 配置变量,文件命名为elasticsearch-data-configmap.yaml。yaml文件内容如下:
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: kube-logging
  name: elasticsearch-data-config
  labels:
    app: elasticsearch
    role: data
data:
  elasticsearch.yml: |-
    cluster.name: ${CLUSTER_NAME}
    node.name: ${NODE_NAME}
    discovery.seed_hosts: ${NODE_LIST}
    cluster.initial_master_nodes: ${MASTER_NODES}
    network.host: 0.0.0.0
    node:
      master: false
      data: true
      ingest: false
    xpack.security.enabled: true
    xpack.monitoring.collection.enabled: true
数据节点,也和master一样,只需要暴露9300端口,用于es集群成员之间通信。新建elasticsearch-data-service.yaml,yaml文件内容如下:
apiVersion: v1
kind: Service
metadata:
  namespace: kube-logging
  name: elasticsearch-data
  labels:
    app: elasticsearch
    role: data
spec:
  ports:
  - port: 9300
    name: transport
  selector:
    app: elasticsearch
    role: data
部署data 节点,我们选择StatefulSet(有状态部署)。我这里简单引用下文档,来说明下,StatefulSet 与 Deployment 区别。
StatefulSet 是用来管理有状态应用的工作负载 API 对象。
StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。
和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。
如果希望使用存储卷为工作负载提供持久存储,可以使用 StatefulSet 作为解决方案的一部分。 尽管 StatefulSet 中的单个 Pod 仍可能出现故障, 但持久的 Pod 标识符使得将现有卷与替换已失败 Pod 的新 Pod 相匹配变得更加容易。
以上为StatefulSet 的概念。新建yaml文件,命名为elasticsearch-data-statefulset.yaml,文件内容如下:
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  namespace: kube-logging
  name: elasticsearch-data
  labels:
    app: elasticsearch
    role: data
spec:
  serviceName: "elasticsearch-data"
  replicas: 1
  template:
    metadata:
      labels:
        app: elasticsearch-data
        role: data
    spec:
      containers:
      - name: elasticsearch-data
        image: docker.elastic.co/elasticsearch/elasticsearch:7.3.0
        env:
        - name: CLUSTER_NAME
          value: elasticsearch
        - name: NODE_NAME
          value: elasticsearch-data
        - name: NODE_LIST
          value: elasticsearch-master,elasticsearch-data,elasticsearch-client
        - name: MASTER_NODES
          value: elasticsearch-master
        - name: "ES_JAVA_OPTS"
          value: "-Xms300m -Xmx300m"
        ports:
        - containerPort: 9300
          name: transport
        volumeMounts:
        - name: config
          mountPath: /usr/share/elasticsearch/config/elasticsearch.yml
          readOnly: true
          subPath: elasticsearch.yml
        - name: elasticsearch-data-persistent-storage
          mountPath: /usr/share/elasticsearch/data
      volumes:
      - name: config
        configMap:
          name: elasticsearch-data-config
      initContainers:
      - name: increase-vm-max-map
        image: busybox
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        securityContext:
          privileged: true
  volumeClaimTemplates:
  - metadata:
      name: elasticsearch-data-persistent-storage
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: nfs-es
      resources:
        requests:
          storage: 10Gi
下面用如下命令来执行这几个yaml文件。
kubectl apply -f elasticsearch-data-configmap.yaml -f elasticsearch-data-service.yaml -f elasticsearch-data-statefulset.yaml
使用如下命令,检查Deployment是否部署成功。
kubectl get pods -n kube-logging
下图为部署成功的状态:
0
 
第四步: 部署ElasticSearch 客户端节点
客户端节点接收数据,传送到数据节点。
新建yaml文件,命名为elasticsearch-client-configmap.yaml,文件内容如下:
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: kube-logging
  name: elasticsearch-client-config
  labels:
    app: elasticsearch
    role: client
data:
  elasticsearch.yml: |-
    cluster.name: ${CLUSTER_NAME}
    node.name: ${NODE_NAME}
    discovery.seed_hosts: ${NODE_LIST}
    cluster.initial_master_nodes: ${MASTER_NODES}
    network.host: 0.0.0.0
    node:
      master: false
      data: false
      ingest: true
    xpack.security.enabled: true
    xpack.monitoring.collection.enabled: true
client(客户端)节点,暴露两个端口,9300用于集群内节点互相访问,9200用于接收http请求。新建yaml文件,命名为elasticsearch-client-service.yaml,文件内容如下:
apiVersion: v1
kind: Service
metadata:
  namespace: kube-logging
  name: elasticsearch-client
  labels:
    app: elasticsearch
    role: client
spec:
  ports:
  - port: 9200
    name: client
  - port: 9300
    name: transport
  selector:
    app: elasticsearch
    role: client
---
使用Deployment 部署client节点,新建yaml文件,命名为elasticsearch-client-deployment.yaml,文件内容如下:
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: kube-logging
  name: elasticsearch-client
  labels:
    app: elasticsearch
    role: client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
      role: client
  template:
    metadata:
      labels:
        app: elasticsearch
        role: client
    spec:
      containers:
      - name: elasticsearch-client
        image: docker.elastic.co/elasticsearch/elasticsearch:7.3.0
        env:
        - name: CLUSTER_NAME
          value: elasticsearch
        - name: NODE_NAME
          value: elasticsearch-client
        - name: NODE_LIST
          value: elasticsearch-master,elasticsearch-data,elasticsearch-client
        - name: MASTER_NODES
          value: elasticsearch-master
        - name: "ES_JAVA_OPTS"
          value: "-Xms256m -Xmx256m"
        ports:
        - containerPort: 9200
          name: client
        - containerPort: 9300
          name: transport
        volumeMounts:
        - name: config
          mountPath: /usr/share/elasticsearch/config/elasticsearch.yml
          readOnly: true
          subPath: elasticsearch.yml
        - name: storage
          mountPath: /data
      volumes:
      - name: config
        configMap:
          name: elasticsearch-client-config
      - name: "storage"
        emptyDir:
          medium: ""
      initContainers:
      - name: increase-vm-max-map
        image: busybox
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        securityContext:
          privileged: true
下面用如下命令来执行这几个yaml文件。
kubectl apply -f elasticsearch-client-configmap.yaml -f elasticsearch-client-service.yaml -f elasticsearch-client-deployment.yaml
使用如下命令,检查Deployment是否部署成功。
kubectl get pods -n kube-logging
下图为部署成功的状态:
0
第五步:生成账号密码。
我们已经开启xpack验证,现在需要在client节点,执行bin/elasticsearch-setup-passwords 命令,用于生成密码。命令整合如下:
kubectl exec -it $(kubectl get pods -n kube-logging | grep elasticsearch-client | sed -n 1p | awk '{print $1}') -n kube-logging -- bin/elasticsearch-setup-passwords auto -b
0
查看生成的账号密码,使用elastic账号与对应密码数据,生成k8s secret,用于Kibana(展示器) 与 Fluentd(收集器),访问Elasticsearch。命令如下:
kubectl create secret generic elasticsearch-pw-elastic -n kube-logging --from-literal password=fjskjafiojewB 
Es集群3个节点已经部署完成。下一步,就是部署Kibana访问Elasticsearch集群。欢迎点赞,评论。 
 
 
posted @ 2021-02-07 22:23  Yun-Hai  阅读(802)  评论(0编辑  收藏  举报