Kubernetes部署ELK並使用Filebeat收集容器日志


本文的試驗環境為CentOS 7.3,Kubernetes集群為1.11.2,安裝步驟參見kubeadm安裝kubernetes V1.11.1 集群

1. 環境准備

Elasticsearch運行時要求vm.max_map_count內核參數必須大於262144,因此開始之前需要確保這個參數正常調整過。

$ sysctl -w vm.max_map_count=262144

也可以在ES的的編排文件中增加一個initContainer來修改內核參數,但這要求kublet啟動的時候必須添加了--allow-privileged參數,但是一般生產中不會給加這個參數,因此最好在系統供給的時候要求這個參數修改完成。

ES的配置方式

  • 使用Cluster Update Setting API動態修改配置
  • 使用配置文件的方式,配置文件默認在 config 文件夾下,具體位置取決於安裝方式。
    • elasticsearch.yml 配置Elasticsearch
    • jvm.options 配置ES JVM參數
    • log4j.properties 配置ES logging參數
  • 使用Prompt方式在啟動時輸入

最常使用的配置方式為使用配置文件,ES的配置文件為yaml格式,格式要求和Kubernetes的編排文件一樣。配置文件中可以引用環境變量,例如node.name: ${HOSTNAME}

ES的節點

ES的節點Node可以分為幾種角色:

  • Master-eligible node,是指有資格被選為Master節點的Node,可以統稱為Master節點。設置node.master: true
  • Data node,存儲數據的節點,設置方式為node.data: true
  • Ingest node,進行數據處理的節點,設置方式為node.ingest: true
  • Trible node,為了做集群整合用的。

對於單節點的Node,默認是master-eligible和data,對於多節點的集群,就要仔細規划每個節點的角色。

2. 單實例方式部署ELK

單實例部署ELK的方法非常簡單,可以參考我Github上的elk-single.yaml文件,整體就是創建一個ES的部署,創建一個Kibana的部署,創建一個ES的Headless服務,創建一個Kiana的NodePort服務,本地通過節點的NodePort訪問Kibana。

[root@devops-101 ~]# curl -L -O https://raw.githubusercontent.com/cocowool/k8s-go/master/elk/elk-single.yaml
[root@devops-101 ~]# kubectl apply -f elk-single.yaml 
deployment.apps/kb-single created
service/kb-single-svc unchanged
deployment.apps/es-single created
service/es-single-nodeport unchanged
service/es-single unchanged
[root@devops-101 ~]# kubectl get all
NAME                             READY     STATUS    RESTARTS   AGE
pod/es-single-5b8b696ff8-9mqrz   1/1       Running   0          26s
pod/kb-single-69d6d9c744-sxzw9   1/1       Running   0          26s

NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
service/es-single            ClusterIP   None             <none>        9200/TCP,9300/TCP               19m
service/es-single-nodeport   NodePort    172.17.197.237   <none>        9200:31200/TCP,9300:31300/TCP   13h
service/kb-single-svc        NodePort    172.17.27.11     <none>        5601:32601/TCP                  19m
service/kubernetes           ClusterIP   172.17.0.1       <none>        443/TCP                         14d

NAME                        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/es-single   1         1         1            1           26s
deployment.apps/kb-single   1         1         1            1           26s

NAME                                   DESIRED   CURRENT   READY     AGE
replicaset.apps/es-single-5b8b696ff8   1         1         1         26s
replicaset.apps/kb-single-69d6d9c744   1         1         1         26s

可以看看效果如下:

3. 集群部署ELK

3.1 不區分集群中的節點角色

[root@devops-101 ~]# curl -L -O https://raw.githubusercontent.com/cocowool/k8s-go/master/elk/elk-cluster.yaml
[root@devops-101 ~]# kubectl apply -f elk-cluster.yaml 
deployment.apps/kb-single created
service/kb-single-svc created
statefulset.apps/es-cluster created
service/es-cluster-nodeport created
service/es-cluster created

效果如下

3.2 區分集群中節點角色

如果需要區分節點的角色,就需要建立兩個StatefulSet部署,一個是Master集群,一個是Data集群。Data集群的存儲我這里為了簡單使用了emptyDir,可以使用localStorage或者hostPath,關於存儲的介紹,可以參考Kubernetes存儲系統介紹。這樣就可以避免Data節點在本機重啟時發生數據丟失而重建索引,但是如果發生遷移的話,如果想保留數據,只能采用共享存儲的方案了。具體的編排文件在這里elk-cluster-with-role

[root@devops-101 ~]# curl -L -O https://raw.githubusercontent.com/cocowool/k8s-go/master/elk/elk-cluster-with-role.yaml 
[root@devops-101 ~]# kubectl apply -f elk-cluster-with-role.yaml 
deployment.apps/kb-single created
service/kb-single-svc created
statefulset.apps/es-cluster created
statefulset.apps/es-cluster-data created
service/es-cluster-nodeport created
service/es-cluster created
[root@devops-101 ~]# kubectl get all
NAME                             READY     STATUS              RESTARTS   AGE
pod/es-cluster-0                 1/1       Running             0          13s
pod/es-cluster-1                 0/1       ContainerCreating   0          2s
pod/es-cluster-data-0            1/1       Running             0          13s
pod/es-cluster-data-1            0/1       ContainerCreating   0          2s
pod/kb-single-5848f5f967-w8hwq   1/1       Running             0          14s

NAME                          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
service/es-cluster            ClusterIP   None             <none>        9200/TCP,9300/TCP               13s
service/es-cluster-nodeport   NodePort    172.17.207.135   <none>        9200:31200/TCP,9300:31300/TCP   13s
service/kb-single-svc         NodePort    172.17.8.137     <none>        5601:32601/TCP                  14s
service/kubernetes            ClusterIP   172.17.0.1       <none>        443/TCP                         16d

NAME                        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kb-single   1         1         1            1           14s

NAME                                   DESIRED   CURRENT   READY     AGE
replicaset.apps/kb-single-5848f5f967   1         1         1         14s

NAME                               DESIRED   CURRENT   AGE
statefulset.apps/es-cluster        3         2         14s
statefulset.apps/es-cluster-data   2         2         13s

效果如下

4. 使用Filebeat監控收集容器日志

使用Logstash,可以監測具有一定命名規律的日志文件,但是對於容器日志,很多文件名都是沒有規律的,這種情況比較適合使用Filebeat來對日志目錄進行監測,發現有更新的日志后上送到Logstash處理或者直接送入到ES中。

每個Node節點上的容器應用日志,默認都會在/var/log/containers目錄下創建軟鏈接,這里我遇到了兩個小問題,第一個就是當時掛載hostPath的時候沒有掛載軟鏈接的目的文件夾,導致在容器中能看到軟鏈接,但是找不到對應的文件;第二個問題是宿主機上這些日志權限都是root,而Pod默認用filebeat用戶啟動的應用,因此要單獨設置下。

效果如下

具體的編排文件可以參考我的Github主頁,提供了Deployment方式的編排和DaemonSet方式的編排。

對於具體日志的格式,因為時間問題沒有做進一步的解析,這里如果有朋友做過,可以分享出來。

主要的編排文件內容摘抄如下。

kind: List
apiVersion: v1
items:
- apiVersion: v1
  kind: ConfigMap
  metadata:
    name: filebeat-config
    labels:
      k8s-app: filebeat
      kubernetes.io/cluster-service: "true"
      app: filebeat-config
  data:
    filebeat.yml: |
      processors:
        - add_cloud_metadata:
      filebeat.modules:
      - module: system
      filebeat.inputs:
      - type: log
        paths:
          - /var/log/containers/*.log
        symlinks: true
        # json.message_key: log
        # json.keys_under_root: true
      output.elasticsearch:
        hosts: ['es-single:9200']
      logging.level: info        
- apiVersion: extensions/v1beta1
  kind: DaemonSet 
  metadata:
    name: filebeat
    labels:
      k8s-app: filebeat
      kubernetes.io/cluster-service: "true"
  spec:
    template:
      metadata:
        name: filebeat
        labels:
          app: filebeat
          k8s-app: filebeat
          kubernetes.io/cluster-service: "true"
      spec:
        containers:
        - image: docker.elastic.co/beats/filebeat:6.4.0
          name: filebeat
          args: [
            "-c", "/home/filebeat-config/filebeat.yml",
            "-e",
          ]
          securityContext:
            runAsUser: 0
          volumeMounts:
          - name: filebeat-storage
            mountPath: /var/log/containers
          - name: varlogpods
            mountPath: /var/log/pods
          - name: varlibdockercontainers
            mountPath: /var/lib/docker/containers
          - name: "filebeat-volume"
            mountPath: "/home/filebeat-config"
        nodeSelector:
          role: front
        volumes:
          - name: filebeat-storage
            hostPath:
              path: /var/log/containers
          - name: varlogpods
            hostPath:
              path: /var/log/pods
          - name: varlibdockercontainers
            hostPath:
              path: /var/lib/docker/containers
          - name: filebeat-volume
            configMap:
              name: filebeat-config

參考資料:

  1. Elasticsearch cluster on top of Kubernetes made easy
  2. Install Elasticseaerch with Docker
  3. Docker Elasticsearch
  4. Running Kibana on Docker
  5. Configuring Elasticsearch
  6. Elasticsearch Node
  7. Loggin Using Elasticsearch and kibana
  8. Configuring Logstash for Docker
  9. Running Filebeat on Docker
  10. Filebeat中文指南
  11. Add experimental symlink support


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM