阅读 601

云原生日志系统 EFK 实践(二)

前文回顾

在前面一篇文章,我们介绍了分布式日志系统的相关背景。云原生以容器为基础的日志收集方式与传统的日志收集有什么异同。随后介绍了 ELKB 分布式日志系统。本文将会接着上一篇文章继续介绍如何基于 EFK 搭建云原生日志平台。

前置条件:数据储存持久化

日志的存储涉及到持久化相关的问题。因此,部署前需要创建数据 k8s 持久化存储,pv 和 pvc。我们的实践涉及到 3 台主机,信息分别如下所示:

角色IP
master192.168.11.195
node1192.168.11.196
node2192.168.11.197

选择 Node1:192.168.11.196 作为 NFS 服务器 。

# 三台都安装 NFS 和 RPCBIND
yum -y install nfs-utils rpcbind
mkdir -pv /ifs/kubernetes
systemctl enable rpcbind
systemctl enable nfs
systemctl start nfs
复制代码
$ vim /etc/exports

/ifs/kubernetes *(rw,no_root_squash)

复制代码
exportfs -r

复制代码

执行完如上命令之后,在其他机器上面测试:

mount -t nfs 192.168.11.196:/ifs/kubernetes /mnt/
复制代码

在 NFS 服务器上面(即 k8snode1)新建三个文件夹:

mkdir -pv /ifs/kubernetes/{pv00001,pv00002,pv00003}
复制代码

采用动态分配 pv 的方式。

#生产动态存储卷
kubectl apply -f class.yaml
#生成pods
kubectl apply -f deployment.yaml
#赋权
kubectl apply -f rbac.yaml
# 最后自动创建存储卷
kubectl apply -f deployment-pvc.yaml
#验证效果
kubectl get pv,pvc
复制代码

执行完上面的命令之后,既可以查看 pv,pvc 的信息:

相关的配置文件 class.yaml、deployment.yaml、rbac.yaml、deployment-pvc.yaml 较为简单,此处就不一一列出来了,如有需要,公众号后台领取。

安装 EFK

依据上面创建的 pv 存储,我们启动如下的服务:

# 启动 es
kubectl apply -f  elasticsearch.yaml

# filebeat.yaml
kubectl apply -f  filebeat.yaml

# kibana.yaml
kubectl apply -f  kibana.yaml

复制代码

通过上面的命令,即可部署这三个组价。下面我们分别看看这三个组件的配置文件。

elasticsearch.yaml

elasticsearch 的资源文件如下:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch
  namespace: kube-system
  labels:
    k8s-app: elasticsearch
spec:
  serviceName: elasticsearch
  selector:
    matchLabels:
      k8s-app: elasticsearch
  template:
    metadata:
      labels:
        k8s-app: elasticsearch
    spec:
      containers:
      - image: elasticsearch:7.3.2
        name: elasticsearch
        resources:
          limits:
            cpu: 1
            memory: 2Gi
          requests:
            cpu: 0.5
            memory: 500Mi
        env:
          - name: "discovery.type"
            value: "single-node"
          - name: ES_JAVA_OPTS
            value: "-Xms512m -Xmx2g"
        ports:
        - containerPort: 9200
          name: db
          protocol: TCP
        volumeMounts:
        - name: elasticsearch-data
          mountPath: /usr/share/elasticsearch/data
  volumeClaimTemplates:
  - metadata:
      name: elasticsearch-data
    spec:
      storageClassName: "managed-nfs-storage"
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 20Gi

---

apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  namespace: kube-system
spec:
  clusterIP: None
  ports:
  - port: 9200
    protocol: TCP
    targetPort: db
  selector:
    k8s-app: elasticsearch

复制代码

指定了 elasticsearch 镜像的版本为 7.3.2,设定 1 核 2G 的配置,挂载了 managed-nfs-storage 存储,Service 将 elasticsearch 的 db 端口暴露出来。

filebeat.yaml

接着安装 filebeat,filebeat 轻量级数据收集引擎。我们这里同样也是基于 k8s 平台。配置文件如下:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: kube-system
  labels:
    k8s-app: filebeat
data:
  filebeat.yml: |-
    filebeat.config:
      inputs:
        reload.enabled: false
      modules:
        path: ${path.config}/modules.d/*.yml
    output.elasticsearch:
      hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-inputs
  namespace: kube-system
  labels:
    k8s-app: filebeat
data:
  kubernetes.yml: |-
    - type: docker
      containers.ids:
      - "*"
      processors:
        - add_kubernetes_metadata:
            in_cluster: true
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat
  namespace: kube-system
  labels:
    k8s-app: filebeat
spec:
  selector:
    matchLabels:
      k8s-app: filebeat
  template:
    metadata:
      labels:
        k8s-app: filebeat
    spec:
      serviceAccountName: filebeat
      terminationGracePeriodSeconds: 30
      containers:
      - name: filebeat
        image: elastic/filebeat:7.3.2
        args: [
          "-c", "/etc/filebeat.yml",
          "-e",
        ]
        env:
        - name: ELASTICSEARCH_HOST
          value: elasticsearch
        - name: ELASTICSEARCH_PORT
          value: "9200"
        securityContext:
          runAsUser: 0
          # If using Red Hat OpenShift uncomment this:
          #privileged: true
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        volumeMounts:
        - name: config
          mountPath: /etc/filebeat.yml
          readOnly: true
          subPath: filebeat.yml
        - name: inputs
          mountPath: /usr/share/filebeat/inputs.d
          readOnly: true
        - name: data
          mountPath: /usr/share/filebeat/data
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      volumes:
      - name: config
        configMap:
          defaultMode: 0600
          name: filebeat-config
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: inputs
        configMap:
          defaultMode: 0600
          name: filebeat-inputs
      - name: data
        hostPath:
          path: /var/lib/filebeat-data
          type: DirectoryOrCreate
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: filebeat
subjects:
- kind: ServiceAccount
  name: filebeat
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: filebeat
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: filebeat
  labels:
    k8s-app: filebeat
rules:
- apiGroups: [""] # "" indicates the core API group
  resources:
  - namespaces
  - pods
  verbs:
  - get
  - watch
  - list
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: filebeat
  namespace: kube-system
  labels:
    k8s-app: filebeat
---

复制代码

filebeat 镜像的版本为 7.3.2,通过 configMap 配置采集的数据源。filebeat 基于 Logstash-fowarder 的源码改造出来。换句话说:Filebeat就是新版的 Logstash-fowarder,也会是 ELK Stack 在 shipper 端的第一选择。

kibana.yaml

kibana 用于日志的可视化展示。它能够搜索、展示存储在 Elasticsearch 中索引数据。使用它可以很方便的用图表、表格、地图展示和分析数据。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kibana
  namespace: kube-system
  labels:
    k8s-app: kibana
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: kibana
  template:
    metadata:
      labels:
        k8s-app: kibana
    spec:
      containers:
      - name: kibana
        image: kibana:7.3.2
        resources:
          limits:
            cpu: 1
            memory: 500Mi
          requests:
            cpu: 0.5
            memory: 200Mi
        env:
          - name: ELASTICSEARCH_HOSTS
            value: http://elasticsearch-0.elasticsearch.kube-system:9200
          - name: I18N_LOCALE
            value: zh-CN
        ports:
        - containerPort: 5601
          name: ui
          protocol: TCP

---
apiVersion: v1
kind: Service
metadata:
  name: kibana
  namespace: kube-system
spec:
  type: NodePort
  ports:
  - port: 5601
    protocol: TCP
    targetPort: ui
    nodePort: 30601
  selector:
    k8s-app: kibana

复制代码

kibana 对外暴露了 nodePort 为 30601。我们就是通过这个主机端口进行访问。

此时,我们查看 pod,svc,发现都已经是 running 的状态了。三个组件成功安装。

查询日志结果

通过上面的组件安装,我们就可以构建索引,来搜索日志信息了。

访问 k8s mater 对应的宿主机 IP + 30601 端口,结果如下所示:

接下来,我们需要建立索引:filebeat-7.3.2-*

索引创建完成之后,就可以在搜索页面进行检索对应的关键词了。

查看 K8S 一些 pod,命名空间,service 的日志,如上图所示全都收集到了。

微服务日志检索

上面是对 k8s 组件相关的日志进行了采集和搜索,那么我们的微服务日志该如何采集呢。首先,我们部署一个 webdemo 这样的微服务。

kubectl create deployment webdemo --image=nginx

kubectl expose deployment webdemo --port=80 --target-port=80 --name=webdemo --type=NodePort
复制代码

执行的过程如上图所示。我们来查看下是否创建成功:

为了从浏览器模拟请求,来制造日志,我们需要查看 webdemo 的端口号:

通过 service 的配置可以知道 webdemo 的 nodeport 为 32008。通过命令行进行请求:

curl http://192.168.11.195:32008/
复制代码

同时,打开 webdemo 的容器服务日志,看看是否对应产生日志:

可以看到上面在对应的产生日志,接着就可以到 kibana 上面进行检索日志了。

成功获取日志。上述的配置表明这种方式能够正常的获取微服务的日志。

小结

通过两篇文章,我们介绍了云原生日志采集相关的概念和基于 EFK 组件的实践,从安装到日志检索的过程。

K8s 的特性是容器日志输出控制台,Docker 本身提供了一种日志采集能力。通过 k8s 搭建 elasticsearch + filebeat + kibana 的日志平台,成功地将容器、k8s 组件和微服务日志都采集到,并通过 kibana 进行图形化展示。

阅读最新文章,关注公众号:aoho求索

文章分类
后端