日志系统elfk

前言

经过上周的技术预研,在本周一通过开会研究,根据公司的现有业务流量和技术栈,决定选择的日志系统方案为:elasticsearch(es)+logstash(lo)+filebeat(fi)+kibana(ki)组合。es选择使用aliyun提供的es,lo&fi选择自己部署,ki是阿里云送的。因为申请ecs需要一定的时间,暂时选择部署在测试&生产环境(吐槽一下,我司测试和生产公用一套k8s并且托管与aliyun......)。用时一天(前期有部署的差不多过)完成在kubernetes上部署完成elfk(先部署起来再说,优化什么的后期根据需要再搞)。

组件简介

es 是一个实时的、分布式的可扩展的搜索引擎,允许进行全文、结构化搜索,它通常用于索引和搜索大量日志数据,也可用于搜索许多不同类型的文。

lo 主要的有点就是它的灵活性,主要因为它有很多插件,详细的文档以及直白的配置格式让它可以在多种场景下应用。我们基本上可以在网上找到很多资源,几乎可以处理任何问题。

作为 Beats 家族的一员,fi 是一个轻量级的日志传输工具,它的存在正弥补了 lo 的缺点fi作为一个轻量级的日志传输工具可以将日志推送到中心lo。

ki是一个分析和可视化平台,它可以浏览、可视化存储在es集群上排名靠前的日志数据,并构建仪表盘。ki结合es操作简单集成了绝大多数es的API,是专业的日志展示应用。

数据采集流程图

日志流向:logs_data---> fi ---> lo ---> es---> ki。

logs_data通过fi收集日志,输出到lo,通过lo做一些过滤和修改之后传送到es数据库,ki读取es数据库做分析。

部署

根据我司的实际集群状况,此文档部署将完全还原日志系统的部署情况。

在本地MAC安装kubectl连接aliyun托管k8s

在客户端(随便本地一台虚机上)安装和托管的k8s一样版本的kubectl

  1. curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.14.8/bin/linux/amd64/kubectl
  2. chmod +x ./kubectl
  3. mv ./kubectl /usr/local/bin/kubectl
  4. 将阿里云托管的k8skubeconfig 复制到$HOME/.kube/config 目录下,注意用户权限的问题
部署ELFK

申请一个名称空间(一般一个项目一个名称空间)。

  1. # cat kube-logging.yaml
  2. apiVersion: v1
  3. kind: Namespace
  4. metadata:
  5. name: loging

部署es。网上找个差不多的资源清单,根据自己的需求进行适当的修改,运行,出错就根据日志进行再修改。

  1. # cat elasticsearch.yaml
  2. apiVersion: storage.k8s.io/v1
  3. kind: StorageClass
  4. metadata:
  5. name: local-class
  6. namespace: loging
  7. provisioner: kubernetes.io/no-provisioner
  8. volumeBindingMode: WaitForFirstConsumer
  9. # Supported policies: Delete, Retain
  10. reclaimPolicy: Delete
  11. ---
  12. kind: PersistentVolume
  13. apiVersion: v1
  14. metadata:
  15. name: datadir1
  16. namespace: logging
  17. labels:
  18. type: local
  19. spec:
  20. storageClassName: local-class
  21. capacity:
  22. storage: 5Gi
  23. accessModes:
  24. - ReadWriteOnce
  25. hostPath:
  26. path: "/data/data1"
  27. ---
  28. apiVersion: apps/v1
  29. kind: StatefulSet
  30. metadata:
  31. name: elasticsearch
  32. namespace: loging
  33. spec:
  34. serviceName: elasticsearch
  35. selector:
  36. matchLabels:
  37. app: elasticsearch
  38. template:
  39. metadata:
  40. labels:
  41. app: elasticsearch
  42. spec:
  43. containers:
  44. - name: elasticsearch
  45. image: elasticsearch:7.3.1
  46. resources:
  47. limits:
  48. cpu: 1000m
  49. requests:
  50. cpu: 100m
  51. ports:
  52. - containerPort: 9200
  53. name: rest
  54. protocol: TCP
  55. - containerPort: 9300
  56. name: inter-node
  57. protocol: TCP
  58. volumeMounts:
  59. - name: data
  60. mountPath: /usr/share/elasticsearch/data
  61. env:
  62. - name: "discovery.type"
  63. value: "single-node"
  64. - name: cluster.name
  65. value: k8s-logs
  66. - name: node.name
  67. valueFrom:
  68. fieldRef:
  69. fieldPath: metadata.name
  70. - name: ES_JAVA_OPTS
  71. value: "-Xms512m -Xmx512m"
  72. initContainers:
  73. - name: fix-permissions
  74. image: busybox
  75. command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
  76. securityContext:
  77. privileged: true
  78. volumeMounts:
  79. - name: data
  80. mountPath: /usr/share/elasticsearch/data
  81. - name: increase-vm-max-map
  82. image: busybox
  83. command: ["sysctl", "-w", "vm.max_map_count=262144"]
  84. securityContext:
  85. privileged: true
  86. - name: increase-fd-ulimit
  87. image: busybox
  88. command: ["sh", "-c", "ulimit -n 65536"]
  89. securityContext:
  90. privileged: true
  91. volumeClaimTemplates:
  92. - metadata:
  93. name: data
  94. labels:
  95. app: elasticsearch
  96. spec:
  97. accessModes: [ "ReadWriteOnce" ]
  98. storageClassName: "local-class"
  99. resources:
  100. requests:
  101. storage: 5Gi
  102. ---
  103. kind: Service
  104. apiVersion: v1
  105. metadata:
  106. name: elasticsearch
  107. namespace: loging
  108. labels:
  109. app: elasticsearch
  110. spec:
  111. selector:
  112. app: elasticsearch
  113. clusterIP: None
  114. ports:
  115. - port: 9200
  116. name: rest
  117. - port: 9300
  118. name: inter-node

部署ki。因为根据数据采集流程图,ki是和es结合的,配置相对简单。

  1. # cat kibana.yaml
  2. apiVersion: extensions/v1beta1
  3. kind: Deployment
  4. metadata:
  5. name: kibana
  6. namespace: loging
  7. labels:
  8. k8s-app: kibana
  9. spec:
  10. replicas: 1
  11. selector:
  12. matchLabels:
  13. k8s-app: kibana
  14. template:
  15. metadata:
  16. labels:
  17. k8s-app: kibana
  18. spec:
  19. containers:
  20. - name: kibana
  21. image: kibana:7.3.1
  22. resources:
  23. limits:
  24. cpu: 1
  25. memory: 500Mi
  26. requests:
  27. cpu: 0.5
  28. memory: 200Mi
  29. env:
  30. - name: ELASTICSEARCH_HOSTS
  31. #注意value是es的services,因为es是有状态,用的无头服务,所以连接的就不仅仅是pod的名字了
  32. value: http://elasticsearch:9200
  33. ports:
  34. - containerPort: 5601
  35. name: ui
  36. protocol: TCP
  37. ---
  38. apiVersion: v1
  39. kind: Service
  40. metadata:
  41. name: kibana
  42. namespace: loging
  43. spec:
  44. ports:
  45. - port: 5601
  46. protocol: TCP
  47. targetPort: ui
  48. selector:
  49. k8s-app: kibana

配置ingress-controller。因为我司用的是阿里云托管的k8s自带的nginx-ingress,并且配置了强制转换https。所以kibana-ingress也要配成https。

  1. # openssl genrsa -out tls.key 2048
  2. # openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=kibana.test.realibox.com
  3. # kubectl create secret tls kibana-ingress-secret --cert=tls.crt --key=tls.key

kibana-ingress配置如下。提供两种,一种是https,一种是https。

  1. https:
  2. # cat kibana-ingress.yaml
  3. apiVersion: extensions/v1beta1
  4. kind: Ingress
  5. metadata:
  6. name: kibana
  7. namespace: loging
  8. spec:
  9. tls:
  10. - hosts:
  11. - kibana.test.realibox.com
  12. secretName: kibana-ingress-secret
  13. rules:
  14. - host: kibana.test.realibox.com
  15. http:
  16. paths:
  17. - path: /
  18. backend:
  19. serviceName: kibana
  20. servicePort: 5601
  21. http:
  22. # cat kibana-ingress.yaml
  23. apiVersion: extensions/v1beta1
  24. kind: Ingress
  25. metadata:
  26. name: kibana
  27. namespace: logging
  28. spec:
  29. rules:
  30. - host: kibana.test.realibox.com
  31. http:
  32. paths:
  33. - path: /
  34. backend:
  35. serviceName: kibana
  36. servicePort: 5601

部署lo。因为lo的作用是对fi收集到的日志进行过滤,需要根据不同的日志做不同的处理,所以可能要经常性的进行改动,要进行解耦。所以选择以configmap的形式进行挂载。

  1. # cat logstash.yaml
  2. apiVersion: extensions/v1beta1
  3. kind: Deployment
  4. metadata:
  5. name: logstash
  6. namespace: loging
  7. spec:
  8. replicas: 1
  9. selector:
  10. matchLabels:
  11. app: logstash
  12. template:
  13. metadata:
  14. labels:
  15. app: logstash
  16. spec:
  17. containers:
  18. - name: logstash
  19. image: elastic/logstash:7.3.1
  20. volumeMounts:
  21. - name: config
  22. mountPath: /opt/logstash/config/containers.conf
  23. subPath: containers.conf
  24. command:
  25. - "/bin/sh"
  26. - "-c"
  27. - "/opt/logstash/bin/logstash -f /opt/logstash/config/containers.conf"
  28. volumes:
  29. - name: config
  30. configMap:
  31. name: logstash-k8s-config
  32. ---
  33. apiVersion: v1
  34. kind: Service
  35. metadata:
  36. labels:
  37. app: logstash
  38. name: logstash
  39. namespace: loging
  40. spec:
  41. ports:
  42. - port: 8080
  43. targetPort: 8080
  44. selector:
  45. app: logstash
  46. type: ClusterIP
  47. # cat logstash-config.yaml
  48. ---
  49. apiVersion: v1
  50. kind: Service
  51. metadata:
  52. labels:
  53. app: logstash
  54. name: logstash
  55. namespace: loging
  56. spec:
  57. ports:
  58. - port: 8080
  59. targetPort: 8080
  60. selector:
  61. app: logstash
  62. type: ClusterIP
  63. ---
  64. apiVersion: v1
  65. kind: ConfigMap
  66. metadata:
  67. name: logstash-k8s-config
  68. namespace: loging
  69. data:
  70. containers.conf: |
  71. input {
  72. beats {
  73. port => 8080 #filebeat连接端口
  74. }
  75. }
  76. output {
  77. elasticsearch {
  78. hosts => ["elasticsearch:9200"] #es的service
  79. index => "logstash-%{+YYYY.MM.dd}"
  80. }
  81. }
  82. 注意:修改configmap 相当于修改镜像。必须重新apply 应用资源清单才能生效。根据数据采集流程图,lo的数据由fi流入,流向es

部署fi。fi的主要作用是进行日志的采集,然后将数据交给lo。

  1. # cat filebeat.yaml
  2. ---
  3. apiVersion: v1
  4. kind: ConfigMap
  5. metadata:
  6. name: filebeat-config
  7. namespace: loging
  8. labels:
  9. app: filebeat
  10. data:
  11. filebeat.yml: |-
  12. filebeat.config:
  13. inputs:
  14. # Mounted `filebeat-inputs` configmap:
  15. path: ${path.config}/inputs.d/*.yml
  16. # Reload inputs configs as they change:
  17. reload.enabled: false
  18. modules:
  19. path: ${path.config}/modules.d/*.yml
  20. # Reload module configs as they change:
  21. reload.enabled: false
  22. # To enable hints based autodiscover, remove `filebeat.config.inputs` configuration and uncomment this:
  23. #filebeat.autodiscover:
  24. # providers:
  25. # - type: kubernetes
  26. # hints.enabled: true
  27. output.logstash:
  28. hosts: ['${LOGSTASH_HOST:logstash}:${LOGSTASH_PORT:8080}'] #流向lo
  29. ---
  30. apiVersion: v1
  31. kind: ConfigMap
  32. metadata:
  33. name: filebeat-inputs
  34. namespace: loging
  35. labels:
  36. app: filebeat
  37. data:
  38. kubernetes.yml: |-
  39. - type: docker
  40. containers.ids:
  41. - "*"
  42. processors:
  43. - add_kubernetes_metadata:
  44. in_cluster: true
  45. ---
  46. apiVersion: extensions/v1beta1
  47. kind: DaemonSet
  48. metadata:
  49. name: filebeat
  50. namespace: loging
  51. labels:
  52. app: filebeat
  53. spec:
  54. selector:
  55. matchLabels:
  56. app: filebeat
  57. template:
  58. metadata:
  59. labels:
  60. app: filebeat
  61. spec:
  62. serviceAccountName: filebeat
  63. terminationGracePeriodSeconds: 30
  64. containers:
  65. - name: filebeat
  66. image: elastic/filebeat:7.3.1
  67. args: [
  68. "-c", "/etc/filebeat.yml",
  69. "-e",
  70. ]
  71. env: #注入变量
  72. - name: LOGSTASH_HOST
  73. value: logstash
  74. - name: LOGSTASH_PORT
  75. value: "8080"
  76. securityContext:
  77. runAsUser: 0
  78. # If using Red Hat OpenShift uncomment this:
  79. #privileged: true
  80. resources:
  81. limits:
  82. memory: 200Mi
  83. requests:
  84. cpu: 100m
  85. memory: 100Mi
  86. volumeMounts:
  87. - name: config
  88. mountPath: /etc/filebeat.yml
  89. readOnly: true
  90. subPath: filebeat.yml
  91. - name: inputs
  92. mountPath: /usr/share/filebeat/inputs.d
  93. readOnly: true
  94. - name: data
  95. mountPath: /usr/share/filebeat/data
  96. - name: varlibdockercontainers
  97. mountPath: /var/lib/docker/containers
  98. readOnly: true
  99. volumes:
  100. - name: config
  101. configMap:
  102. defaultMode: 0600
  103. name: filebeat-config
  104. - name: varlibdockercontainers
  105. hostPath:
  106. path: /var/lib/docker/containers
  107. - name: inputs
  108. configMap:
  109. defaultMode: 0600
  110. name: filebeat-inputs
  111. # data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart
  112. - name: data
  113. hostPath:
  114. path: /var/lib/filebeat-data
  115. type: DirectoryOrCreate
  116. ---
  117. apiVersion: rbac.authorization.k8s.io/v1beta1
  118. kind: ClusterRoleBinding
  119. metadata:
  120. name: filebeat
  121. subjects:
  122. - kind: ServiceAccount
  123. name: filebeat
  124. namespace: loging
  125. roleRef:
  126. kind: ClusterRole
  127. name: filebeat
  128. apiGroup: rbac.authorization.k8s.io
  129. ---
  130. apiVersion: rbac.authorization.k8s.io/v1beta1
  131. kind: ClusterRole
  132. metadata:
  133. name: filebeat
  134. labels:
  135. app: filebeat
  136. rules:
  137. - apiGroups: [""] # "" indicates the core API group
  138. resources:
  139. - namespaces
  140. - pods
  141. verbs:
  142. - get
  143. - watch
  144. - list
  145. ---
  146. apiVersion: v1
  147. kind: ServiceAccount
  148. metadata:
  149. name: filebeat
  150. namespace: loging
  151. labels:
  152. app: filebeat
  153. ---

至此完成在k8s上部署es+lo+fi+ki ,进行简单验证。

验证

查看svc、pod、ingress信息

  1. # kubectl get svc,pods,ingress -n loging
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. service/elasticsearch ClusterIP None <none> 9200/TCP,9300/TCP 151m
  4. service/kibana ClusterIP xxx.168.239.2xx <none> 5601/TCP 20h
  5. service/logstash ClusterIP xxx.168.38.1xx <none> 8080/TCP 122m
  6. NAME READY STATUS RESTARTS AGE
  7. pod/elasticsearch-0 1/1 Running 0 151m
  8. pod/filebeat-24zl7 1/1 Running 0 118m
  9. pod/filebeat-4w7b6 1/1 Running 0 118m
  10. pod/filebeat-m5kv4 1/1 Running 0 118m
  11. pod/filebeat-t6x4t 1/1 Running 0 118m
  12. pod/kibana-689f4bd647-7jrqd 1/1 Running 0 20h
  13. pod/logstash-76bc9b5f95-qtngp 1/1 Running 0 122m
  14. NAME HOSTS ADDRESS PORTS AGE
  15. ingress.extensions/kibana kibana.test.realibox.com xxx.xx.xx.xxx 80, 443 19h
web配置

配置索引





发现



至此算是简单完成。后续需要不断优化,不过那是后事了。

问题总结

这应该算是第一次亲自在测试&生产环境部署应用了,而且是自己很不熟悉的日子系统,遇到了很多问题,需要总结。

  1. 如何调研一项技术栈;
  2. 如何选定方案;
  3. 因为网上几乎没有找到类似的方案(也不晓得别的公司是怎么搞的,反正网上找不到有效的可能借鉴的)。需要自己根据不同的文档总结尝试;
  4. 一个组件的标签尽可能一致;
  5. 如何查看公司是否做了端口限制和https强制转换;
  6. 遇到IT的事一定要看日志,这点很重要,日志可以解决绝大多数问题;
  7. 一个人再怎么整也会忽略一些点,自己先尝试然后请教朋友,共同进步。
  8. 项目先上线再说别的,目前是这样,一件事又百分之20的把握就可以去做了。百分之80再去做就没啥意思了。
  9. 自学重点学的是理论,公司才能学到操作。

在k8s上部署日志系统elfk的更多相关文章

  1. 优化:在k8s上部署的gitlab

    gitlab组件图 gitlab在k8s上占用资源 # kubectl top pods -n default | grep git* gitlab-gitaly-0 9m 444Mi gitlab- ...

  2. kubernetes之三 使用kubectl在k8s上部署应用

    在上一篇中,我们学习了使用minikube来搭建k8s集群.k8s集群启动后,就可以在上面部署应用了.本篇,我们就来学习如何使用kubectl在k8s上部署应用. 学习之前,可以先从下面这篇博客上了解 ...

  3. 使用Rancher在K8S上部署高性能PHP应用程序

    介 绍 PHP是网络上最流行的编程语言之一,许多被广泛使用的内容管理系统都使用它开发,如WordPress和Drupal,并为现代服务器端框架(如Laravel和Symfony)提供核心代码. 尽管P ...

  4. k8s系列---EFK日志系统

    文章拷于:http://blog.itpub.net/28916011/viewspace-2216748/   用于自己备份记录错误 一个完整的k8s集群,应该包含如下六大部分:kube-dns.i ...

  5. 容器化 | 在 K8s 上部署 RadonDB MySQL Operator 和集群

    作者:程润科 数据库研发工程师 编辑:张莉梅 高级文档工程师 视频:钱芬 高级测试工程师 本文将演示在 Kubernetes 上部署 RadonDB MySQL Kubernetes 2.X(Oper ...

  6. k8s 上部署 Redis 三主三从 集群

    目录 介绍 为什么要使用Redis? 什么是Redis群集? 在Kubernetes中部署Redis集群 从 GitHub 上下载: 创建pv 创建statefulset 创建service 初始化 ...

  7. K8S 上部署 Redis-cluster 三主三从 集群

    介绍 Redis代表REmote DIctionary Server是一种开源的内存中数据存储,通常用作数据库,缓存或消息代理.它可以存储和操作高级数据类型,例如列表,地图,集合和排序集合. 由于Re ...

  8. 在k8s上部署第一个php应用

    一.搭建nginx+php 1.站点配置文件 1.1创建nginx-configmap.yaml [root@master k8s]# cat nginx-configmap.yaml apiVers ...

  9. 通过重新上传修改后的docker镜像来在kubeapps上实现k8s上部署的nginx版本更新,回退等

    docker操作:制作自定义镜像 # docker下载官方nginx镜像 docker pull nginx # 基于该镜像运行一个容器 docker run -it -d --name nginx_ ...

随机推荐

  1. centos6下filebeat多开问题

    centos6下filebeat多开问题 0. 场景 比如之前在用filebeat做收集,但是想新开一个实例把之前的日志全部重新导一遍,如果直接指定filebeat -c 是不行的,因为filebea ...

  2. 「雕爷学编程」Arduino动手做(12)——霍尔磁力模块

    37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...

  3. 输入一个整数n,输出契波那契数列的第n项

    package bianchengti; /* * 输入一个整数n,输出契波那契数列的第n项 * 斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89... */ p ...

  4. iOS 数组遍历过程中移除

    参考:https://blog.csdn.net/u011619283/article/details/53135502 常见crash 原因是数组在移除元素后,继续遍历会有越界问题. 解决思路: 遍 ...

  5. 设置键盘return键样式

    textField.returnKeyType = UIReturnKeySend; typedef NS_ENUM(NSInteger, UIReturnKeyType) { UIReturnKey ...

  6. 线程的 run() 和 start() ; 太骚了 ~~

    线程的 run() 和 start() ; 太骚了 ~~ 线程的 run() 和 start() ; 太骚了 ~~注:本文转载于:CodeCow · 程序牛 的个人博客:http://www.code ...

  7. ngnix随笔二

    ngnix配置文件 1.rpm -ql nginx /etc/logrotate.d/nginx /etc/nginx /etc/nginx/conf.d /etc/nginx/conf.d/defa ...

  8. [Objective-C] 001_Hello Objective-C

    "Hello Word"从来都是经典中的经典!今天我们就来个"Hello Objective-C"吧. 启动Xcode(6.3.1),从File菜单中选择New ...

  9. 坑爹的PostgreSQL的美元符号(有时需要替换成单引号)

    今天想在PostgeSQL数据库里建一个存储过程(或函数也行),由于对存储过程比较生疏,上网搜了很多教程和源代码例子,照着写,发现怎么都不行,甚至把网上教程包括官方教程的源代码原封不动的复制下来一执行 ...

  10. 02 . Prometheus告警处理

    Prometheus告警简介 告警能力在Prometheus的架构中被划分成两个独立的部分.如下所示,通过在Prometheus中定义AlertRule(告警规则),Prometheus会周期性的对告 ...