09.10 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
/<none>/<none>/<none>/<none>

可以看看效果如下:

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

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

效果如下

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

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

/<none>/<none>/<none>/<none>

效果如下

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

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

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

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

效果如下

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

Kubernetes部署ELK並使用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


分享到:


相關文章: