使用 Fluentd 记录日志

此任务说明了如何配置 Istio 以创建自定义日志条目并将它们输出到一个 Fluentd 守护程序。Fluentd 是一个开源日志收集器,支持许多数据输出方式,而且是可插拔架构。一种流行的日志后端是 Elasticsearch,以及作为展示的 Kibana。在此任务结束时,将会实现一个新的日志流,把日志发送到一个示例 Fluentd / Elasticsearch / Kibana 工具栈。

Bookinfo 示例应用程序被用作贯穿全文的例子。

开始之前

  • 在您的集群中安装 Istio 并部署一个应用程序。此任务假设 Mixer 使用默认配置(—configDefaultNamespace=istio-system)进行设置。如果你使用不同的配置值,请更新此任务中的配置和命令以匹配该值。

安装 Fluentd

在您的集群中可能已经运行了一个 Fluentd 守护程序,例如通过这里这里描述的 add-on 进行安装,或者由您的集群提供商安装。这很可能会将日志配置为发送到 Elasticsearch 系统或日志提供者。

您可以使用这些 Fluentd 守护程序,或者您配置的其他 Fluentd。只要他们能够监听转发日志,Istio 的 Mixer 就可以连接他们。要使 Istio 的 Mixer 连接到一个运行的 Fluentd 守护程序,您需要为 Fluentd 添加一个 service。监听转发日志的 Fluentd 配置为:

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

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

示例 Fluentd、Elasticsearch、Kibana 工具栈

为了此任务的目标,您可以部署提供的示例工具栈。此栈在一个非生产就绪的 ServicesDeployments 集合中包含了 Fluentd、Elasticsearch 和 Kibana,它们都位于一个名为 logging 的新 Namespace 中。

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

  1. # Logging Namespace。下列内容都在此 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. # 在初始化时需要更多的 cpu,因此使用 burstable 级别。
  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,包含配置文件。
  124. kind: ConfigMap
  125. apiVersion: v1
  126. data:
  127. forward.input.conf: |-
  128. # 采用 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. # 设置 chunk limits.
  141. buffer_chunk_limit 2M
  142. buffer_queue_limit 8
  143. flush_interval 5s
  144. # 重试间隔绝对不要超过 5 分钟。
  145. max_retry_wait 30
  146. # 禁用重试次数限制(永远重试)。
  147. disable_retry_limit
  148. # 使用多线程。
  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
  2. namespace "logging" created
  3. service "elasticsearch" created
  4. deployment "elasticsearch" created
  5. service "fluentd-es" created
  6. deployment "fluentd-es" created
  7. configmap "fluentd-es-config" created
  8. service "kibana" created
  9. deployment "kibana" created

配置 Istio

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

将下列内容保存为 fluentd-istio.yaml

  1. # logentry 实例配置
  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.workload.name | "unknown"
  12. user: source.user | "unknown"
  13. destination: destination.labels["app"] | destination.workload.name | "unknown"
  14. responseCode: response.code | 0
  15. responseSize: response.size | 0
  16. latency: response.duration | "0ms"
  17. monitored_resource_type: '"UNSPECIFIED"'
  18. ---
  19. # 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. # 将 logentry 示例发送到 Fluentd handler 的 rule
  29. apiVersion: "config.istio.io/v1alpha2"
  30. kind: rule
  31. metadata:
  32. name: newlogtofluentd
  33. namespace: istio-system
  34. spec:
  35. match: "true" # 匹配所有请求
  36. actions:
  37. - handler: handler.fluentd
  38. instances:
  39. - newlog.logentry
  40. ---

创建资源:

  1. $ kubectl apply -f fluentd-istio.yaml
  2. Created config logentry/istio-system/newlog at revision 22374
  3. Created config fluentd/istio-system/handler at revision 22375
  4. Created config rule/istio-system/newlogtofluentd at revision 22376

请注意,handler 配置中的 address: "fluentd-es.logging:24224" 一行指向我们在示例工具栈中配置的 Fluentd 守护程序。

查看新的日志

  • 发送流量到示例应用程序。

对于 Bookinfo 示例,请在您的浏览器中访问 http://$GATEWAY_URL/productpage,或执行以下命令:

  1. $ curl http://$GATEWAY_URL/productpage
  • 在 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 退出。

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

  • 使用 * 作为索引模式,并点击 “Next step”。

  • 选择 @timestamp 作为 Time Filter 字段名称,并点击 “Create index pattern”。

  • 现在点击左侧目录中的 “Discover”,开始探索生成的日志。

清理

  • 删除新的遥测配置:
  1. $ kubectl delete -f fluentd-istio.yaml
  • 删除示例 Fluentd、Elasticsearch、Kibana 工具栈:
  1. $ kubectl delete -f logging-stack.yaml
  • 删除任何可能还在运行的 kubectl port-forward 进程:
  1. $ killall kubectl
  • 如果您不打算探索任何后续任务,请参考 Bookinfo 清理中的指示停止应用程序。

相关内容

深入遥测

演示如何使用 Istio Mixer 和 Istio sidecar 获取指标和日志,并在不同的服务间进行追踪。

Mixer 适配器模型

概要说明 Mixer 的插件架构。

Egress TLS 流量中的 SNI 监控及策略

如何为 Egress TLS 流量配置 SNI 监控并应用策略。

Jaeger

了解如何配置代理以向 Jaeger 发送追踪请求。

Zipkin

了解如何配置代理以向 Zipkin 发送追踪请求。

使用 Grafana 可视化指标度量

这个任务向您展示了如何设置和使用 Istio 仪表盘来监视网格流量。