你們介紹了 Kubernetes 集羣中的幾種日誌收集方案,Kubernetes 中比較流行的日誌收集解決方案是 Elasticsearch、Fluentd 和 Kibana(EFK)技術棧,也是官方如今比較推薦的一種方案。html
Elasticsearch
是一個實時的、分佈式的可擴展的搜索引擎,容許進行全文、結構化搜索,它一般用於索引和搜索大量日誌數據,也可用於搜索許多不一樣類型的文檔。node
Elasticsearch 一般與 Kibana
一塊兒部署,Kibana 是 Elasticsearch 的一個功能強大的數據可視化 Dashboard,Kibana 容許你經過 web 界面來瀏覽 Elasticsearch 日誌數據。linux
Fluentd
是一個流行的開源數據收集器,咱們將在 Kubernetes 集羣節點上安裝 Fluentd,經過獲取容器日誌文件、過濾和轉換日誌數據,而後將數據傳遞到 Elasticsearch 集羣,在該集羣中對其進行索引和存儲。web
咱們先來配置啓動一個可擴展的 Elasticsearch 集羣,而後在 Kubernetes 集羣中建立一個 Kibana 應用,最後經過 DaemonSet 來運行 Fluentd,以便它在每一個 Kubernetes 工做節點上均可以運行一個 Pod。正則表達式
在建立 Elasticsearch 集羣以前,咱們先建立一個命名空間,咱們將在其中安裝全部日誌相關的資源對象。docker
新建一個 kube-logging.yaml 文件:shell
apiVersion: v1 kind: Namespace metadata: name: logging
而後經過 kubectl 建立該資源清單,建立一個名爲 logging 的 namespace:json
$ kubectl create -f kube-logging.yaml namespace/logging created $ kubectl get ns NAME STATUS AGE default Active 244d istio-system Active 100d kube-ops Active 179d kube-public Active 244d kube-system Active 244d logging Active 4h monitoring Active 35d
如今建立了一個命名空間來存放咱們的日誌相關資源,接下來能夠部署 EFK 相關組件,首先開始部署一個3節點的 Elasticsearch 集羣。後端
這裏咱們使用3個 Elasticsearch Pod 來避免高可用下多節點集羣中出現的「腦裂」問題,當一個或多個節點沒法與其餘節點通訊時會產生「腦裂」,可能會出現幾個主節點。api
瞭解更多 Elasticsearch 集羣腦裂問題,能夠查看文檔https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html#split-brain
一個關鍵點是您應該設置參數discover.zen.minimum_master_nodes=N/2+1
,其中N
是 Elasticsearch 集羣中符合主節點的節點數,好比咱們這裏3個節點,意味着N
應該設置爲2。這樣,若是一個節點暫時與集羣斷開鏈接,則另外兩個節點能夠選擇一個新的主節點,而且集羣能夠在最後一個節點嘗試從新加入時繼續運行,在擴展 Elasticsearch 集羣時,必定要記住這個參數。
首先建立一個名爲 elasticsearch 的無頭服務,新建文件 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 直接建立上面的服務資源對象:
$ kubectl create -f elasticsearch-svc.yaml
service/elasticsearch created
$ kubectl get services --namespace=logging Output NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elasticsearch ClusterIP None <none> 9200/TCP,9300/TCP 26s
如今咱們已經爲 Pod 設置了無頭服務和一個穩定的域名.elasticsearch.logging.svc.cluster.local
,接下來咱們經過 StatefulSet 來建立具體的 Elasticsearch 的 Pod 應用。
Kubernetes StatefulSet 容許咱們爲 Pod 分配一個穩定的標識和持久化存儲,Elasticsearch 須要穩定的存儲來保證 Pod 在從新調度或者重啓後的數據依然不變,因此須要使用 StatefulSet 來管理 Pod。
要了解更多關於 StaefulSet 的信息,能夠查看官網關於 StatefulSet 的相關文檔:https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/。
新建名爲 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
該內容中,咱們定義了一個名爲 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
標籤。
而後定義 Pod 模板部份內容:
... spec: containers: - name: elasticsearch image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.3 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
之類的版本,能夠去掉該後綴。而後暴露了9200和9300兩個端口,注意名稱要和上面定義的 Service 保持一致。而後經過 volumeMount 聲明瞭數據持久化目錄,下面咱們再來定義 VolumeClaims。最後就是咱們在容器中設置的一些環境變量了:
metadata.name
來獲取。這將解析爲 es-cluster-[0,1,2],取決於節點的指定順序。es-cluster-[0,1,2].elasticsearch.logging.svc.cluster.local
,所以咱們相應地設置此變量。因爲都在同一個 namespace 下面,因此咱們能夠將其縮短爲es-cluster-[0,1,2].elasticsearch
。要了解有關 Elasticsearch 發現的更多信息,請參閱 Elasticsearch 官方文檔:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery.html。(N/2) + 1
,N
是咱們的羣集中符合主節點的節點的數量。咱們有3個 Elasticsearch 節點,所以咱們將此值設置爲2(向下舍入到最接近的整數)。要了解有關此參數的更多信息,請參閱官方 Elasticsearch 文檔:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html#split-brain。-Xms512m -Xmx512m
,告訴JVM
使用512 MB
的最小和最大堆。您應該根據羣集的資源可用性和需求調整這些參數。要了解更多信息,請參閱設置堆大小的相關文檔:https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html。接下來添加關於 initContainer 的內容:
... initContainers: - name: fix-permissions image: busybox 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: busybox command: ["sysctl", "-w", "vm.max_map_count=262144"] securityContext: privileged: true - name: increase-fd-ulimit image: busybox command: ["sh", "-c", "ulimit -n 65536"] securityContext: privileged: true
這裏咱們定義了幾個在主應用程序以前運行的 Init 容器,這些初始容器按照定義的順序依次執行,執行完成後纔會啓動主應用容器。
第一個名爲 fix-permissions 的容器用來運行 chown 命令,將 Elasticsearch 數據目錄的用戶和組更改成1000:1000
(Elasticsearch 用戶的 UID)。由於默認狀況下,Kubernetes 用 root 用戶掛載數據目錄,這會使得 Elasticsearch 沒法方法該數據目錄,能夠參考 Elasticsearch 生產中的一些默認注意事項相關文檔說明:https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_notes_for_production_use_and_defaults。
第二個名爲 increase-vm-max-map 的容器用來增長操做系統對mmap
計數的限制,默認狀況下該值可能過低,致使內存不足的錯誤,要了解更多關於該設置的信息,能夠查看 Elasticsearch 官方文檔說明:https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html。
最後一個初始化容器是用來執行ulimit
命令增長打開文件描述符的最大數量的。
此外 Elastisearch Notes for Production Use 文檔還提到了因爲性能緣由最好禁用 swap,固然對於 Kubernetes 集羣而言,最好也是禁用 swap 分區的。
如今咱們已經定義了主應用容器和它以前運行的 Init Containers 來調整一些必要的系統參數,接下來咱們能夠添加數據目錄的持久化相關的配置,在 StatefulSet 中,使用 volumeClaimTemplates 來定義 volume 模板便可:
... volumeClaimTemplates: - metadata: name: data labels: app: elasticsearch spec: accessModes: [ "ReadWriteOnce" ] storageClassName: es-data-db resources: requests: storage: 50Gi
咱們這裏使用 volumeClaimTemplates 來定義持久化模板,Kubernetes 會使用它爲 Pod 建立 PersistentVolume,設置訪問模式爲ReadWriteOnce
,這意味着它只能被 mount 到單個節點上進行讀寫,而後最重要的是使用了一個名爲 es-data-db 的 StorageClass 對象,因此咱們須要提早建立該對象,咱們這裏使用的 NFS 做爲存儲後端,因此須要安裝一個對應的 provisioner 驅動,前面關於 StorageClass 的課程中已經和你們介紹過方法,新建一個 elasticsearch-storageclass.yaml 的文件,文件內容以下:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: es-data-db provisioner: fuseim.pri/ifs # 該值須要和 provisioner 配置的保持一致
最後,咱們指定了每一個 PersistentVolume 的大小爲 50GB,咱們能夠根據本身的實際須要進行調整該值。最後,完整的 Elasticsearch StatefulSet 資源清單文件內容以下:
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: docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.3 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: busybox 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: busybox command: ["sysctl", "-w", "vm.max_map_count=262144"] securityContext: privileged: true - name: increase-fd-ulimit image: busybox 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: 100Gi
如今直接使用 kubectl 工具部署便可:
$ kubectl create -f elasticsearch-storageclass.yaml
storageclass.storage.k8s.io "es-data-db" created $ kubectl create -f elasticsearch-statefulset.yaml statefulset.apps/es-cluster created
添加成功後,能夠看到 logging 命名空間下面的全部的資源對象:
$ kubectl get sts -n logging
NAME DESIRED CURRENT AGE
es-cluster 3 3 20h
$ kubectl get pods -n logging
NAME READY STATUS RESTARTS AGE
es-cluster-0 1/1 Running 0 20h
es-cluster-1 1/1 Running 0 20h
es-cluster-2 1/1 Running 0 20h
$ kubectl get svc -n logging
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elasticsearch ClusterIP None <none> 9200/TCP,9300/TCP 20h
Pods 部署完成後,咱們能夠經過請求一個 REST API 來檢查 Elasticsearch 集羣是否正常運行。使用下面的命令將本地端口9200轉發到 Elasticsearch 節點(如es-cluster-0)對應的端口:
$ kubectl port-forward es-cluster-0 9200:9200 --namespace=logging Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200
而後,在另外的終端窗口中,執行以下請求:
$ curl http://localhost:9200/_cluster/state?pretty
正常來講,應該會看到相似於以下的信息:
{ "cluster_name" : "k8s-logs", "compressed_size_in_bytes" : 348, "cluster_uuid" : "QD06dK7CQgids-GQZooNVw", "version" : 3, "state_uuid" : "mjNIWXAzQVuxNNOQ7xR-qg", "master_node" : "IdM5B7cUQWqFgIHXBp0JDg", "blocks" : { }, "nodes" : { "u7DoTpMmSCixOoictzHItA" : { "name" : "es-cluster-1", "ephemeral_id" : "ZlBflnXKRMC4RvEACHIVdg", "transport_address" : "10.244.4.191:9300", "attributes" : { } }, "IdM5B7cUQWqFgIHXBp0JDg" : { "name" : "es-cluster-0", "ephemeral_id" : "JTk1FDdFQuWbSFAtBxdxAQ", "transport_address" : "10.244.2.215:9300", "attributes" : { } }, "R8E7xcSUSbGbgrhAdyAKmQ" : { "name" : "es-cluster-2", "ephemeral_id" : "9wv6ke71Qqy9vk2LgJTqaA", "transport_address" : "10.244.40.4:9300", "attributes" : { } } }, ...
看到上面的信息就代表咱們名爲 k8s-logs 的 Elasticsearch 集羣成功建立了3個節點:es-cluster-0,es-cluster-1,和es-cluster-2,當前主節點是 es-cluster-0。
Elasticsearch 集羣啓動成功了,接下來咱們能夠來部署 Kibana 服務,新建一個名爲 kibana.yaml 的文件,對應的文件內容以下:
apiVersion: v1 kind: Service metadata: name: kibana namespace: logging labels: app: kibana spec: ports: - port: 5601 type: NodePort selector: app: kibana --- apiVersion: apps/v1 kind: Deployment metadata: name: kibana namespace: logging labels: app: kibana spec: selector: matchLabels: app: kibana template: metadata: labels: app: kibana spec: containers: - name: kibana image: docker.elastic.co/kibana/kibana-oss:6.4.3 resources: limits: cpu: 1000m requests: cpu: 100m env: - name: ELASTICSEARCH_URL value: http://elasticsearch:9200 ports: - containerPort: 5601
上面咱們定義了兩個資源對象,一個 Service 和 Deployment,爲了測試方便,咱們將 Service 設置爲了 NodePort 類型,Kibana Pod 中配置都比較簡單,惟一須要注意的是咱們使用 ELASTICSEARCH_URL 這個環境變量來設置Elasticsearch 集羣的端點和端口,直接使用 Kubernetes DNS 便可,此端點對應服務名稱爲 elasticsearch,因爲是一個 headless service,因此該域將解析爲3個 Elasticsearch Pod 的 IP 地址列表。
配置完成後,直接使用 kubectl 工具建立:
$ kubectl create -f kibana.yaml service/kibana created deployment.apps/kibana created
建立完成後,能夠查看 Kibana Pod 的運行狀態:
$ kubectl get pods --namespace=logging NAME READY STATUS RESTARTS AGE es-cluster-0 1/1 Running 0 20h es-cluster-1 1/1 Running 0 20h es-cluster-2 1/1 Running 0 20h kibana-7558d4dc4d-5mqdz 1/1 Running 0 20h $ kubectl get svc --namespace=logging NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elasticsearch ClusterIP None <none> 9200/TCP,9300/TCP 20h kibana NodePort 10.105.208.253 <none> 5601:31816/TCP 20h
若是 Pod 已是 Running 狀態了,證實應用已經部署成功了,而後能夠經過 NodePort 來訪問 Kibana 這個服務,在瀏覽器中打開http://<任意節點IP>:31816
便可,若是看到以下歡迎界面證實 Kibana 已經成功部署到了 Kubernetes集羣之中。
kibana welcome
Fluentd
是一個高效的日誌聚合器,是用 Ruby 編寫的,而且能夠很好地擴展。對於大部分企業來講,Fluentd 足夠高效而且消耗的資源相對較少,另一個工具Fluent-bit
更輕量級,佔用資源更少,可是插件相對 Fluentd 來講不夠豐富,因此總體來講,Fluentd 更加成熟,使用更加普遍,因此咱們這裏也一樣使用 Fluentd 來做爲日誌收集工具。
Fluentd 經過一組給定的數據源抓取日誌數據,處理後(轉換成結構化的數據格式)將它們轉發給其餘服務,好比 Elasticsearch、對象存儲等等。Fluentd 支持超過300個日誌存儲和分析服務,因此在這方面是很是靈活的。主要運行步驟以下:
fluentd 架構
通常來講咱們是經過一個配置文件來告訴 Fluentd 如何採集、處理數據的,下面簡單和你們介紹下 Fluentd 的配置方法。
好比咱們這裏爲了收集 Kubernetes 節點上的全部容器日誌,就須要作以下的日誌源配置:
<source> @id fluentd-containers.log @type tail path /var/log/containers/*.log pos_file /var/log/fluentd-containers.log.pos time_format %Y-%m-%dT%H:%M:%S.%NZ tag raw.kubernetes.* format json read_from_head true </source>
上面配置部分參數說明以下:
tail
表示 Fluentd 從上次讀取的位置經過 tail 不斷獲取數據,另一個是http
表示經過一個 GET 請求來收集數據。tail
類型下的特定參數,告訴 Fluentd 採集/var/log/containers
目錄下的全部日誌,這是 docker 在 Kubernetes 節點上用來存儲運行容器 stdout 輸出日誌數據的目錄。上面是日誌源的配置,接下來看看如何將日誌數據發送到 Elasticsearch:
<match **> @id elasticsearch @type elasticsearch @log_level info include_tag_key true type_name fluentd host "#{ENV['OUTPUT_HOST']}" port "#{ENV['OUTPUT_PORT']}" logstash_format true <buffer> @type file path /var/log/fluentd-buffers/kubernetes.system.buffer flush_mode interval retry_type exponential_backoff flush_thread_count 2 flush_interval 5s retry_forever retry_max_interval 30 chunk_limit_size "#{ENV['OUTPUT_BUFFER_CHUNK_LIMIT']}" queue_limit_length "#{ENV['OUTPUT_BUFFER_QUEUE_LIMIT']}" overflow_action block </buffer>
**
。info
,表示任何該級別或者該級別以上(INFO、WARNING、ERROR)的日誌都將被路由到 Elsasticsearch。true
,Fluentd 將會以 logstash 格式來轉發結構化的日誌數據。要收集 Kubernetes 集羣的日誌,直接用 DasemonSet 控制器來部署 Fluentd 應用,這樣,它就能夠從 Kubernetes 節點上採集日誌,確保在集羣中的每一個節點上始終運行一個 Fluentd 容器。固然能夠直接使用 Helm 來進行一鍵安裝,爲了可以瞭解更多實現細節,咱們這裏仍是採用手動方法來進行安裝。
首先,咱們經過 ConfigMap 對象來指定 Fluentd 配置文件,新建 fluentd-configmap.yaml 文件,文件內容以下:
kind: ConfigMap apiVersion: v1 metadata: name: fluentd-config namespace: logging labels: addonmanager.kubernetes.io/mode: Reconcile data: system.conf: |- <system> root_dir /tmp/fluentd-buffers/ </system> containers.input.conf: |- <source> @id fluentd-containers.log @type tail path /var/log/containers/*.log pos_file /var/log/es-containers.log.pos time_format %Y-%m-%dT%H:%M:%S.%NZ localtime tag raw.kubernetes.* format json read_from_head true </source> # Detect exceptions in the log output and forward them as one log entry. <match raw.kubernetes.**> @id raw.kubernetes @type detect_exceptions remove_tag_prefix raw message log stream stream multiline_flush_interval 5 max_bytes 500000 max_lines 1000 </match> system.input.conf: |- # Logs from systemd-journal for interesting services. <source> @id journald-docker @type systemd filters [{ "_SYSTEMD_UNIT": "docker.service" }] <storage> @type local persistent true </storage> read_from_head true tag docker </source> <source> @id journald-kubelet @type systemd filters [{ "_SYSTEMD_UNIT": "kubelet.service" }] <storage> @type local persistent true </storage> read_from_head true tag kubelet </source> forward.input.conf: |- # Takes the messages sent over TCP <source> @type forward </source> output.conf: |- # Enriches records with Kubernetes metadata <filter kubernetes.**> @type kubernetes_metadata </filter> <match **> @id elasticsearch @type elasticsearch @log_level info include_tag_key true host elasticsearch port 9200 logstash_format true request_timeout 30s <buffer> @type file path /var/log/fluentd-buffers/kubernetes.system.buffer flush_mode interval retry_type exponential_backoff flush_thread_count 2 flush_interval 5s retry_forever retry_max_interval 30 chunk_limit_size 2M queue_limit_length 8 overflow_action block </buffer> </match>
上面配置文件中咱們配置了 docker 容器日誌目錄以及 docker、kubelet 應用的日誌的收集,收集到數據通過處理後發送到 elasticsearch:9200 服務。
而後新建一個 fluentd-daemonset.yaml 的文件,文件內容以下:
apiVersion: v1 kind: ServiceAccount metadata: name: fluentd-es namespace: logging labels: k8s-app: fluentd-es kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: fluentd-es labels: k8s-app: fluentd-es kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile rules: - apiGroups: - "" resources: - "namespaces" - "pods" verbs: - "get" - "watch" - "list" --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: fluentd-es labels: k8s-app: fluentd-es kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile subjects: - kind: ServiceAccount name: fluentd-es namespace: logging apiGroup: "" roleRef: kind: ClusterRole name: fluentd-es apiGroup: "" --- apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd-es namespace: logging labels: k8s-app: fluentd-es version: v2.0.4 kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile spec: selector: matchLabels: k8s-app: fluentd-es version: v2.0.4 template: metadata: labels: k8s-app: fluentd-es kubernetes.io/cluster-service: "true" version: v2.0.4 # This annotation ensures that fluentd does not get evicted if the node # supports critical pod annotation based priority scheme. # Note that this does not guarantee admission on the nodes (#40573). annotations: scheduler.alpha.kubernetes.io/critical-pod: '' spec: serviceAccountName: fluentd-es containers: - name: fluentd-es image: cnych/fluentd-elasticsearch:v2.0.4 env: - name: FLUENTD_ARGS value: --no-supervisor -q resources: limits: memory: 500Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /data/docker/containers readOnly: true - name: config-volume mountPath: /etc/fluent/config.d nodeSelector: beta.kubernetes.io/fluentd-ds-ready: "true" tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule terminationGracePeriodSeconds: 30 volumes: - name: varlog hostPath: path: /var/log -