kubernetes日志采集方案EFK

本文详细介绍了如何在 Kubernetes 集群上部署 EFK(Elasticsearch、Fluentd、Kibana)日志采集解决方案。首先,创建了一个名为logging的namespace,部署了一个3节点的Elasticsearch集群,配置了Elasticsearch的headless service和StatefulSet。接着,创建并启动了Kibana服务,使用NodePort类型以便访问。最后,通过DaemonSet部署Fluentd,收集Kubernetes节点上的容器日志并发送到Elasticsearch。整个过程包括了各个组件的详细配置和测试验证。
摘要由CSDN通过智能技术生成

https://www.qikqiak.com/post/install-efk-stack-on-k8s/

EFK简介

Kubernetes中比较流行的日志收集解决方案是Elasticsearch、Fluentd 和 Kibana(EFK)技术栈,也是官方现在比较推荐的一种方案。

Elasticsearch是一个实时的、分布式的可扩展的搜索引擎,允许进行全文、结构化搜索,它通常用于索引和搜索大量日志数据,也可用于搜索许多不同类型的文档。

Fluentd是一个流行的开源数据收集器,是CNCF的毕业项目。我们将在Kubernetes集群节点上以DaemonSet的方式安装Fluentd,通过获取容器日志文件、过滤和转换日志数据,然后将数据传递到 Elasticsearch集群,在该集群中对其进行索引和存储。

Kibana是Elasticsearch的一个功能强大的数据可视化 dashboard,Kibana提供了web 界面来浏览 Elasticsearch 日志数据。

本文我们先配置启动一个可扩展的Elasticsearch集群,然后在 Kubernetes集群中创建一个Kibana应用,最后通过DaemonSet 来运行Fluentd,以便它在每个Kubernetes工作节点上都可以运行一个Pod。

创建 Elasticsearch 集群

在创建Elasticsearch集群之前,我们先创建一个命名空间,用来部署所有日志相关的资源对象。

[root@k8s-87 efk]# cat logging-ns.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: logging

通过kubectl创建该资源清单,创建一个名为logging的 namespace:

[root@k8s-87 efk]# kubectl apply -f logging-ns.yaml 
namespace/logging created
[root@k8s-87 efk]# kubectl get ns
NAME              STATUS   AGE
default           Active   7d5h
kube-node-lease   Active   7d5h
kube-public       Active   7d5h
kube-system       Active   7d5h
logging           Active   5s

现在创建了一个命名空间来存放我们的日志相关资源,接下来可以部署 EFK 相关组件,首先开始部署一个3节点的 Elasticsearch 集群。

为了避免出现脑裂现象,需要设置参数discover.zen.minimum_master_nodes=N/2+1,其中N是Elasticsearch 集群中符合主节点的节点数,比如我们这里3个节点,意味着我们应该设置为2。这样,如果一个节点暂时与集群断开连接,则另外两个节点可以选择一个新的主节点,并且集群可以在最后一个节点尝试重新加入时继续运行。

首先创建一个名为es的headless service,新建文件elasticsearch-svc.yaml,文件内容如下:

kind: Service
apiVersion: v1
metadata:
  name: elasticsearch
  namespace: logging
  labels:
    app: elasticsearch
spec:
  selector:
    app: elasticsearch
  clusterIP: None
  ports:
    - port: 9200
      name: rest
    - port: 9300
      name: inter-node

定义了一个名为elasticsearch的Service,指定标签app=elasticsearch,当我们将 Elasticsearch StatefulSet 与此服务关联时,服务将返回带有标签app=elasticsearch Elasticsearch Pods的DNS A 记录,然后设置clusterIP=None,将该服务设置成无头服务。最后,我们分别定义端口9200、9300,分别用于与 REST API 交互,以及用于节点间通信。

使用 kubectl 直接创建上面的服务资源对象:

[root@k8s-87 efk]# kubectl apply -f elasticsearch-svc.yaml 
service/elasticsearch created
[root@k8s-87 efk]# kubectl get svc --namespace=logging
NAME   TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)             AGE
elasticsearch     ClusterIP   None         <none>        9200/TCP,9300/TCP   22s

现在我们已经为Pod设置了headless service和一个稳定的域名.elasticsearch.logging.svc.cluster.local,接下来我们通过 StatefulSet 来创建具体的 Elasticsearch 的 Pod 应用。

Kubernetes StatefulSet 允许我们为Pod 分配一个稳定的标识和持久化存储,Elasticsearch 需要稳定的存储来保证 Pod 在重新调度或者重启后的数据依然不变,所以需要使用 StatefulSet 来管理 Pod。

我们先列出完整的资源清单文件elasticsearch-statefulset.yaml,然后在逐块分析。具体内容如下:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: es-cluster
  namespace: logging
spec:
  serviceName: elasticsearch
  replicas: 3
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - name: elasticsearch
        image: 192.168.200.197:80/apm/elasticsearch-oss:6.7.0
        resources:
            limits:
              cpu: 1000m
            requests:
              cpu: 100m
        ports:
        - containerPort: 9200
          name: rest
          protocol: TCP
        - containerPort: 9300
          name: inter-node
          protocol: TCP
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
        env:
          - name: cluster.name
            value: k8s-logs
          - name: node.name
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: discovery.zen.ping.unicast.hosts
            value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"
          - name: discovery.zen.minimum_master_nodes
            value: "2"
          - name: ES_JAVA_OPTS
            value: "-Xms512m -Xmx512m"
      initContainers:
      - name: fix-permissions
        image: 192.168.200.197:80/test-private/busybox:latest
        command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
        securityContext:
          privileged: true
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
      - name: increase-vm-max-map
        image: 192.168.200.197:80/test-private/busybox:latest
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        securityContext:
          privileged: true
      - name: increase-fd-ulimit
        image: 192.168.200.197:80/test-private/busybox:latest
        command: ["sh", "-c", "ulimit -n 65536"]
        securityContext:
          privileged: true
  volumeClaimTemplates:
  - metadata:
      name: data
      labels:
        app: elasticsearch
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: es-data-db
      resources:
        requests:
          storage: 20Gi
  1. 首先我们定义了一个名为es-cluster的StatefulSet 对象,然后定义serviceName=elasticsearch和前面创建的 Service 相关联,这可以确保使用以下 DNS 地址访问 StatefulSet 中的每一个Pod:es-cluster-[0,1,2].elasticsearch.logging.svc.cluster.local,其中[0,1,2]对应于已分配的 Pod 序号。

然后指定3个副本,将matchLabels设置为app=elasticsearch,所以Pod 的模板部分.spec.template.metadata.lables也必须包含app=elasticsearch。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: es-cluster
  namespace: logging
spec:
  serviceName: elasticsearch
  replicas: 3
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
  1. 然后定义Pod模板部分内容:
 spec:
      containers:
      - name: es
        image: 192.168.200.197:80/apm/elasticsearch-oss:6.7.0
        resources:
            limits:
              cpu: 1000m
            requests:
              cpu: 100m
        ports:
        - containerPort: 9200
          name: rest
          protocol: TCP
        - containerPort: 9300
          name: inter-node
          protocol: TCP
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
        env:
          - name: cluster.name
            value: k8s-logs
          - name: node.name
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: discovery.zen.ping.unicast.hosts
            value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"
          - name: discovery.zen.minimum_master_nodes
            value: "2"
          - name: ES_JAVA_OPTS
            value: "-Xms512m -Xmx512m"

该部分是定义StatefulSet中的Pod,我们这里使用一个-oss后缀的镜像,该镜像是Elasticsearch的开源版本,如果你想使用包含X-Pack之类的版本,可以去掉该后缀。然后

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正说杂谈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值