使用 Fluentd 记录日志

此任务将展示如何配置 Istio 创建自定义日志条目并且发送给 Fluentd 守护进程。Fluentd 是一个开源的日志收集器,
支持多种数据输出并且有一个可插拔架构。
Elasticsearch是一个流行的后端日志记录程序,
Kibana 用于查看。在任务结束后,
一个新的日志流将被加载发送日志到示例 Fluentd/Elasticsearch/Kibana 栈。

在任务中,将使用 BookInfo 示例应用程序作为示例应用程序。

在开始之前

  • 安装 Istio 到您的集群并且部署一个应用程序。这个任务假定 Mixer 是
    以默认配置设置的(--configDefaultNamespace=istio-system)。
    如果您使用不同的值,则更新此任务中的配置和命令以匹配对应的值。

安装 Fluentd

在您的群集中,您可能已经有一个 Fluentd DaemonSet 运行,
就像 add-on 中这里
这里的描述,
或者特定于您的集群提供者的东西。这可能配置为将日志发送到 Elasticsearch 系统或其它日志记录提供程序。

您可以使用这些 Fluentd 守护进程或您已经设置的任何其他Fluentd守护进程,只要Fluentd守护进程正在侦听转发的日志, 并且
Istio 的 Mixer 可以连接Fluentd守护进程。为了让 Mixer 连接到正在运行的 Fluentd 守护进程, 您可能需要为 Fluentd 添加
service.
监听转发日志的 Fluentd 配置是:

  1. <source>
  2. type forward
  3. </source>

将 Mixer 连接到所有可能 Fluentd 配置的完整细节超出了此任务的范围。

Fluentd, Elasticsearch, Kibana 栈示例

为了这个任务的准备,您可以部署提供的示例栈。
该栈包括 Fluentd,Elasticsearch 和 Kibana 在一个非生产集合 ServicesDeployments
在一个新的叫做logging
Namespace 中.

将下面的内容保存为 logging-stack.yaml.

  1. # Logging Namespace. All below are a part of this namespace.
  2. apiVersion: v1
  3. kind: Namespace
  4. metadata:
  5. name: logging
  6. ---
  7. # Elasticsearch Service
  8. apiVersion: v1
  9. kind: Service
  10. metadata:
  11. name: elasticsearch
  12. namespace: logging
  13. labels:
  14. app: elasticsearch
  15. spec:
  16. ports:
  17. - port: 9200
  18. protocol: TCP
  19. targetPort: db
  20. selector:
  21. app: elasticsearch
  22. ---
  23. # Elasticsearch Deployment
  24. apiVersion: extensions/v1beta1
  25. kind: Deployment
  26. metadata:
  27. name: elasticsearch
  28. namespace: logging
  29. labels:
  30. app: elasticsearch
  31. annotations:
  32. sidecar.istio.io/inject: "false"
  33. spec:
  34. template:
  35. metadata:
  36. labels:
  37. app: elasticsearch
  38. spec:
  39. containers:
  40. - image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.1
  41. name: elasticsearch
  42. resources:
  43. # need more cpu upon initialization, therefore burstable class
  44. limits:
  45. cpu: 1000m
  46. requests:
  47. cpu: 100m
  48. env:
  49. - name: discovery.type
  50. value: single-node
  51. ports:
  52. - containerPort: 9200
  53. name: db
  54. protocol: TCP
  55. - containerPort: 9300
  56. name: transport
  57. protocol: TCP
  58. volumeMounts:
  59. - name: elasticsearch
  60. mountPath: /data
  61. volumes:
  62. - name: elasticsearch
  63. emptyDir: {}
  64. ---
  65. # Fluentd Service
  66. apiVersion: v1
  67. kind: Service
  68. metadata:
  69. name: fluentd-es
  70. namespace: logging
  71. labels:
  72. app: fluentd-es
  73. spec:
  74. ports:
  75. - name: fluentd-tcp
  76. port: 24224
  77. protocol: TCP
  78. targetPort: 24224
  79. - name: fluentd-udp
  80. port: 24224
  81. protocol: UDP
  82. targetPort: 24224
  83. selector:
  84. app: fluentd-es
  85. ---
  86. # Fluentd Deployment
  87. apiVersion: extensions/v1beta1
  88. kind: Deployment
  89. metadata:
  90. name: fluentd-es
  91. namespace: logging
  92. labels:
  93. app: fluentd-es
  94. annotations:
  95. sidecar.istio.io/inject: "false"
  96. spec:
  97. template:
  98. metadata:
  99. labels:
  100. app: fluentd-es
  101. spec:
  102. containers:
  103. - name: fluentd-es
  104. image: gcr.io/google-containers/fluentd-elasticsearch:v2.0.1
  105. env:
  106. - name: FLUENTD_ARGS
  107. value: --no-supervisor -q
  108. resources:
  109. limits:
  110. memory: 500Mi
  111. requests:
  112. cpu: 100m
  113. memory: 200Mi
  114. volumeMounts:
  115. - name: config-volume
  116. mountPath: /etc/fluent/config.d
  117. terminationGracePeriodSeconds: 30
  118. volumes:
  119. - name: config-volume
  120. configMap:
  121. name: fluentd-es-config
  122. ---
  123. # Fluentd ConfigMap, contains config files.
  124. kind: ConfigMap
  125. apiVersion: v1
  126. data:
  127. forward.input.conf: |-
  128. # Takes the messages sent over TCP
  129. <source>
  130. type forward
  131. </source>
  132. output.conf: |-
  133. <match **>
  134. type elasticsearch
  135. log_level info
  136. include_tag_key true
  137. host elasticsearch
  138. port 9200
  139. logstash_format true
  140. # Set the chunk limits.
  141. buffer_chunk_limit 2M
  142. buffer_queue_limit 8
  143. flush_interval 5s
  144. # Never wait longer than 5 minutes between retries.
  145. max_retry_wait 30
  146. # Disable the limit on the number of retries (retry forever).
  147. disable_retry_limit
  148. # Use multiple threads for processing.
  149. num_threads 2
  150. </match>
  151. metadata:
  152. name: fluentd-es-config
  153. namespace: logging
  154. ---
  155. # Kibana Service
  156. apiVersion: v1
  157. kind: Service
  158. metadata:
  159. name: kibana
  160. namespace: logging
  161. labels:
  162. app: kibana
  163. spec:
  164. ports:
  165. - port: 5601
  166. protocol: TCP
  167. targetPort: ui
  168. selector:
  169. app: kibana
  170. ---
  171. # Kibana Deployment
  172. apiVersion: extensions/v1beta1
  173. kind: Deployment
  174. metadata:
  175. name: kibana
  176. namespace: logging
  177. labels:
  178. app: kibana
  179. annotations:
  180. sidecar.istio.io/inject: "false"
  181. spec:
  182. template:
  183. metadata:
  184. labels:
  185. app: kibana
  186. spec:
  187. containers:
  188. - name: kibana
  189. image: docker.elastic.co/kibana/kibana-oss:6.1.1
  190. resources:
  191. # need more cpu upon initialization, therefore burstable class
  192. limits:
  193. cpu: 1000m
  194. requests:
  195. cpu: 100m
  196. env:
  197. - name: ELASTICSEARCH_URL
  198. value: http://elasticsearch:9200
  199. ports:
  200. - containerPort: 5601
  201. name: ui
  202. protocol: TCP
  203. ---

创建资源:

  1. kubectl apply -f logging-stack.yaml

你应该看到以下内容:

  1. namespace "logging" created
  2. service "elasticsearch" created
  3. deployment "elasticsearch" created
  4. service "fluentd-es" created
  5. deployment "fluentd-es" created
  6. configmap "fluentd-es-config" created
  7. service "kibana" created
  8. deployment "kibana" created

配置 Istio

现在有一个正在运行的 Fluentd 守护进程,请使用新的日志类型配置 Istio,
并将这些日志发送到监听守护进程。
创建一个新的 YAML 文件来保存日志流的配置,Istio 将自动生成并收集。

将下面的内容保存为 fluentd-istio.yaml:

  1. # Configuration for logentry instances
  2. apiVersion: "config.istio.io/v1alpha2"
  3. kind: logentry
  4. metadata:
  5. name: newlog
  6. namespace: istio-system
  7. spec:
  8. severity: '"info"'
  9. timestamp: request.time
  10. variables:
  11. source: source.labels["app"] | source.service | "unknown"
  12. user: source.user | "unknown"
  13. destination: destination.labels["app"] | destination.service | "unknown"
  14. responseCode: response.code | 0
  15. responseSize: response.size | 0
  16. latency: response.duration | "0ms"
  17. monitored_resource_type: '"UNSPECIFIED"'
  18. ---
  19. # Configuration for a fluentd handler
  20. apiVersion: "config.istio.io/v1alpha2"
  21. kind: fluentd
  22. metadata:
  23. name: handler
  24. namespace: istio-system
  25. spec:
  26. address: "fluentd-es.logging:24224"
  27. ---
  28. # Rule to send logentry instances to the fluentd handler
  29. apiVersion: "config.istio.io/v1alpha2"
  30. kind: rule
  31. metadata:
  32. name: newlogtofluentd
  33. namespace: istio-system
  34. spec:
  35. match: "true" # match for all requests
  36. actions:
  37. - handler: handler.fluentd
  38. instances:
  39. - newlog.logentry
  40. ---

创建资源:

  1. istioctl create -f fluentd-istio.yaml

预期的输出类似于:

  1. Created config logentry/istio-system/newlog at revision 22374
  2. Created config fluentd/istio-system/handler at revision 22375
  3. Created config rule/istio-system/newlogtofluentd at revision 22376

请注意在处理程序配置中 address: "fluentd-es.logging:24224" 行指向我们设置的Fluentd守护进程示例栈。

查看新的日志

  1. 将流量发送到示例应用程序。

    对于 BookInfo
    示例, 在浏览器中访问 http://$GATEWAY_URL/productpage
    或发送以下命令:

    1. curl http://$GATEWAY_URL/productpage
  2. 在 Kubernetes 环境中, 通过以下命令为 Kibana 建立端口转发:

    1. kubectl -n logging port-forward $(kubectl -n logging get pod -l app=kibana -o jsonpath='{.items[0].metadata.name}') 5601:5601

    退出运行命令。完成访问 Kibana UI 时输入 Ctrl-C 退出。

  3. 导航到 Kibana UI 并点击 右上角的 “Set up index patterns”。

  4. 使用 * 作为索引模式, 并单击 “Next step.”。

  5. 选择 @timestamp 作为时间筛选字段名称,然后单击 “Create index pattern”。

  6. 现在在左侧的菜单上点击 “Discover”,并开始检索生成的日志。

清理

  • 删除新的遥测配置:

    1. istioctl delete -f fluentd-istio.yaml
  • 删除 Fluentd, Elasticsearch, Kibana 示例栈:

    1. kubectl delete -f logging-stack.yaml
  • 如果您不打算探索任何后续任务, 参考
    BookInfo cleanup 关闭应用程序的说明。

进一步阅读