kubernetes 之 prometheus 监控第二篇 - alertmanager 监控告警:
在前期的博文中, 我已经简单的介绍过了 prometheus 的安装, 以及通过 grafana 来实施监控. 这篇博文, 我们更深入的介绍一下 prometheus 的监控. 本篇博文主要分为以下几个知识点:
1. 使用 prometheus 监控 ceph 存储;
2. 学习简单的 PromQL 语言, 在 grafana 里面根据业务自定义 dashboard;
3. alertmanager 自定义告警的配置; 讲述邮件告警和企业微信告警;
1. 使用 prometheus 监控 ceph 存储:
使用 prometheus 监控 ceph 存储还是比较简单的, 在任何一台 k8s 节点上面运行一个独立的 docker 镜像即可;
首先在 GitHub 上面下载 ceph-exporter 的压缩包:
下载下来之后解压目录, 打包镜像, 推送镜像到私有仓库, 拷贝 ceph 配置到本地, 运行 ceph 镜像容器:
- [[email protected] ~]# ll
- total 16620
- -rw-------. 1 root root 1270 Apr 5 00:24 anaconda-ks.cfg
- -rw-r--r-- 1 root root 2571 May 8 18:23 ceph-deploy-ceph.log
- drwxr-xr-x 6 root root 289 May 14 10:05 ceph_exporter
- drwxr-xr-x 3 root root 39 May 14 09:12 ceph_exporter-2.0.0-jewel
- -rw-r--r-- 1 root root 317324 May 14 09:06 ceph_exporter-2.0.0-jewel.tar.gz
- -rw-r--r--. 1 root root 130 Apr 17 14:22 Dockerfile
- drwxr-xr-x. 3 root root 52 Apr 30 15:07 gy
- drwxr-xr-x. 2 root root 24 Apr 30 19:01 jenkins-slae
- -rw-r--r-- 1 root root 12209 May 15 14:18 jira.py
- drwxr-xr-x. 2 root root 24 Apr 29 14:45 jnlp
- -rw-r--r--. 1 root root 118 Apr 17 14:23 kibana.YAML
- drwxr-xr-x 2 root root 244 May 8 15:46 my-cluster
- -rw-r--r--. 1 root root 16574127 Apr 28 13:39 pinpoint-agent.zip
- -rw-r--r-- 1 root root 90250 May 9 15:51 v2.13.1
- [[email protected] ~]#
- # 构建镜像并上传镜像到私有仓库
- [[email protected] ceph_exporter-2.0.0-jewel]# docker build -t k8s.harbor.test.site/system/ceph_exporter:latest ./
- [[email protected] ceph_exporter-2.0.0-jewel]# docker push k8s.harbor.test.site/system/ceph_exporter:v2
- # 运行一个 ceph-exporter 的容器, 需要提前把 ceph 管理机器上面的 ceph.conf 和 ceph.client.admin.keyring 文件拷贝到 / software 目录, 这两个文件一个是 ceph 的配置文件
里面有 ceph 的配置内容, 包括 mon 节点 ip 等, 另外一个是认证信息;
[[email protected] ceph_exporter-2.0.0-jewel]# docker run -d -v /software/:/etc/ceph --net=host -p 9128:9128 k8s.harbor.test.site/system/ceph_exporter
启动完成 ceph-exporter 容器之后, 在宿主机就会有 9128 端口暴露(因为启动容器的时候配置了 --net=host 参数), 可以通过测试 curl http://ip:9128/metrics 看看是否有 metrics 数据. 如果有数据的话, 就可以配置 prometheus 了;
- # 在 prometheus.YAML 文件中增加 ceph-exporter 的配置即可;
- prometheus.YAML: |-
- global:
- scrape_interval: 1m
- evaluation_interval: 1m
- rule_files:
- - "/etc/prometheus/prometheus.rules"
- scrape_configs:
- - job_name: 'prometheus'
- static_configs:
- - targets: ['localhost:9090']
- - job_name: "traefik"
- static_configs:
- - targets: ['traefik2-dashboard:80']
- - job_name: 'ceph-exporter'
- static_configs:
- - targets: ['10.83.32.229:9128']
- labels:
- alias: ceph-exporter
- - job_name: "mysql"
- # 重新更新 configmap, 并且激活配置不用重启服务
- kubectl replace -f /data/prometheus2/k8s-prometheus-grafana/prometheus/configmap.YAML --force
- curl -X POST "http://10.200.66.236:9090/-/reload"
通过打开 prometheus 的监控页面, 可以看到 ceph 的存储已经有 metrics 的数据了. 然后配置 grafana,
We will use dashboard IDs 917, 926 and 923 when importing dashboards on Grafana.
2. 学习简单的 PromQL 语言, 在 grafana 里面根据业务自定义 dashboard;
前面我们讲到 grafana 的 dashboard, 都是在官方网站下载别人已经配置好的 dashboard. 比如 k8s node 监控的 dashboard 等, 那如何自己制作 dashboard 呢. 想要实现自己定义 dashboard, 必须要会一些简单的 PromQL 语言. 下面讲一下一些简单的 PromQL 语言:
Prometheus 通过指标名称 (metrics name) 以及对应的一组标签 (labelset) 唯一定义一条时间序列. 指标名称反映了监控样本的基本标识, 而 label 则在这个基本特征上为采集到的数据提供了多种特征维度. 用户可以基于这些特征维度过滤, 聚合, 统计从而产生新的计算后的一条时间序列.
PromQL 是 Prometheus 内置的数据查询语言, 其提供对时间序列数据丰富的查询, 聚合以及逻辑运算能力的支持. 并且被广泛应用在 Prometheus 的日常应用当中, 包括对数据查询, 可视化, 告警处理当中. 可以这么说, PromQL 是 Prometheus 所有应用场景的基础, 理解和掌握 PromQL 是 Prometheus 入门的第一课.
查询时间序列
- # 通过 prometheus 查询的语句和结果
- http_requests_total
- Element Value
- http_requests_total{
- code="200",handler="prometheus",instance="10.83.32.226:6443",job="kubernetes-apiservers",method="get"
- } 546
- http_requests_total{
- code="200",handler="prometheus",instance="10.83.32.227:6443",job="kubernetes-apiservers",method="get"
- } 548
- http_requests_total{
- code="200",handler="prometheus",instance="10.83.32.228:6443",job="kubernetes-apiservers",method="get"
- } 547
- http_requests_total{
- code="200",handler="prometheus",instance="localhost:9090",job="prometheus",method="get"
- } 134
- http_requests_total{
- code="200",handler="prometheus",instance="my-mysql:9104",job="mysql",method="get"
- } 133
- http_requests_total{
- code="200",handler="query_range",instance="localhost:9090",job="prometheus",method="get"
- } 59
- http_requests_total{
- code="200",handler="series",instance="localhost:9090",job="prometheus",method="get"
- } 2
- http_requests_total{
- code="200",handler="static",instance="localhost:9090",job="prometheus",method="get"
- } 3
- http_requests_total{
- code="200",handler="targets",instance="localhost:9090",job="prometheus",method="get"
- }
- # PromQL 还支持用户根据时间序列的标签匹配模式来对时间序列进行过滤, 目前主要支持两种匹配模式: 完全匹配和正则匹配.
- # PromQL 支持使用 = 和!= 两种完全匹配模式: 可以通过 key=value 的模式匹配固定的查询内容
- http_requests_total{
- instance="localhost:9090"
- }
- Element Value
- http_requests_total{
- code="200",handler="graph",instance="localhost:9090",job="prometheus",method="get"
- } 1
- http_requests_total{
- code="200",handler="label_values",instance="localhost:9090",job="prometheus",method="get"
- } 1
- http_requests_total{
- code="200",handler="prometheus",instance="localhost:9090",job="prometheus",method="get"
- } 136
- http_requests_total{
- code="200",handler="query",instance="localhost:9090",job="prometheus",method="get"
- } 2
- http_requests_total{
- code="200",handler="query_range",instance="localhost:9090",job="prometheus",method="get"
- } 59
- http_requests_total{
- code="200",handler="series",instance="localhost:9090",job="prometheus",method="get"
- } 2
- http_requests_total{
- code="200",handler="static",instance="localhost:9090",job="prometheus",method="get"
- } 4
- http_requests_total{
- code="200",handler="targets",instance="localhost:9090",job="prometheus",method="get"
- }
范围查询:
直接通过类似于 PromQL 表达式 httprequeststotal 查询时间序列时, 返回值中只会包含该时间序列中的最新的一个样本值, 这样的返回结果我们称之为瞬时向量. 而相应的这样的表达式称之为__瞬时向量表达式.
而如果我们想过去一段时间范围内的样本数据时, 我们则需要使用区间向量表达式. 区间向量表达式和瞬时向量表达式之间的差异在于在区间向量表达式中我们需要定义时间选择的范围, 时间范围通过时间范围选择器 [] 进行定义. 例如, 通过以下表达式可以选择最近 5 分钟内的所有样本数据:
- http_requests_total{
- instance="localhost:9090"
- }[5m]
- http_requests_total{
- code="200",handler="graph",instance="localhost:9090",job="prometheus",method="get"
- } 1 @1558010956.845
- 1 @1558011016.845
- 1 @1558011076.845
- # 除了使用 m 表示分钟以外, PromQL 的时间范围选择器支持其它时间单位:
s - 秒
m - 分钟
h - 小时
d - 天
w - 周
y - 年
时间位移操作:
而如果我们想查询, 5 分钟前的瞬时样本数据, 或昨天一天的区间内的样本数据呢? 这个时候我们就可以使用位移操作, 位移操作的关键字为 offset.
- http_requests_total{
- instance="localhost:9090"
- } offset 5m
- Element Value
- http_requests_total{
- code="200",handler="prometheus",instance="localhost:9090",job="prometheus",method="get"
- } 135
使用聚合操作:
- # 查询系统所有 http 请求的总量
- sum(http_requests_total{
- instance="localhost:9090"
- })
- # 查询 CPU 的平均值, 并且按照 CPU 的模式排序
- avg(node_cpu_seconds_total) by (mode)
- Element Value
- {
- mode="iowait"
- } 875.1003124999999
- {
- mode="irq"
- } 0
- {
- mode="nice"
- } 4.0337499999999995
- {
- mode="softirq"
- } 21.6546875
- {
- mode="steal"
- } 0
- {
- mode="system"
- } 414.46062499999994
- {
- mode="user"
- } 1247.3525000000002
- {
- mode="idle"
- } 21781.5896875
- # 按照主机查询各个主机的 CPU 使用率
- sum(sum(irate(node_cpu_seconds_total{
- mode!='idle'
- }[5m])) / sum(irate(node_cpu_seconds_total[5m]))) by (instance)
更多关于 PromQL 的语法可以参考网址, 里面有详细的学习资料:
:
紧接着我们根据上面学习的简单的 PromQL 语法来制作一个 Dashboard, 把一个业务系统的 pod 资源专门放在一个 Dashboard 里面;
- # cim 业务网络流量的
- sum (rate (container_network_receive_bytes_total{
- image!="",name=~"^k8s_.*",pod_name=~"^cim.*"}[1m])) by (pod_name)
- sum (rate (container_network_transmit_bytes_total{image!="",name=~"^k8s_.*",pod_name=~"^cim.*"}[1m])) by (pod_name)
- # cim 业务内存使用率
- sum (container_memory_working_set_bytes{image!="",name=~"^k8s_.*",pod_name=~"^cim.*"}) by (pod_name)
- # cim 业务 CPU 负载
- sum (rate (container_cpu_usage_seconds_total{image!="",name=~"^k8s_.*",pod_name=~"^cim.*"
- }[1m])) by (pod_name)
- #
3. alertmanager 自定义告警的配置; 讲述邮件告警和企业微信告警;
prometheus 监控可以通过 grafana 将数据优美的展示出来, 但是 IT 监控最主要的还是告警; 如果出现故障运维人员需要第一时间能够收到告警才可以; prometheus 有一个组件 alertmanager 来实现告警; 关于告警有几个概念需要和大家聊一下:
Alertmanager 处理由类似 Prometheus 服务器等客户端发来的警报, 之后需要删除重复, 分组, 并将它们通过路由发送到正确的接收器, 比如电子邮件, Slack 等. Alertmanager 还支持沉默和警报抑制的机制.
分组:
分组是指当出现问题时, Alertmanager 会收到一个单一的通知, 而当系统宕机时, 很有可能成百上千的警报会同时生成, 这种机制在较大的中断中特别有用.
例如, 当数十或数百个服务的实例在运行, 网络发生故障时, 有可能服务实例的一半不可达数据库. 在告警规则中配置为每一个服务实例都发送警报的话, 那么结果是数百警报被发送至 Alertmanager.
但是作为用户只想看到单一的报警页面, 同时仍然能够清楚的看到哪些实例受到影响, 因此, 人们通过配置 Alertmanager 将警报分组打包, 并发送一个相对看起来紧凑的通知.
分组警报, 警报时间, 以及接收警报的 receiver 是在配置文件中通过路由树配置的.
抑制:
抑制是指当警报发出后, 停止重复发送由此警报引发其他错误的警报的机制.
例如, 当警报被触发, 通知整个集群不可达, 可以配置 Alertmanager 忽略由该警报触发而产生的所有其他警报, 这可以防止通知数百或数千与此问题不相关的其他警报.
抑制机制可以通过 Alertmanager 的配置文件来配置
沉默:
沉默是一种简单的特定时间静音提醒的机制. 一种沉默是通过匹配器来配置, 就像路由树一样. 传入的警报会匹配 RE, 如果匹配, 将不会为此警报发送通知.
沉默机制可以通过 Alertmanager 的 Web 页面进行配置.
alertmanager 路由:
路由块定义了路由树及其子节点. 如果没有设置的话, 子节点的可选配置参数从其父节点继承.
每个警报进入配置的路由树的顶级路径, 顶级路径必须匹配所有警报(即没有任何形式的匹配). 然后匹配子节点. 如果 continue 的值设置为 false, 它在匹配第一个孩子后就停止; 如果在子节点匹配, continue 的值为 true, 警报将继续进行后续兄弟姐妹的匹配. 如果警报不匹配任何节点的任何子节点(没有匹配的子节点, 或不存在), 该警报基于当前节点的配置处理.
接收器 receiver
顾名思义, 警报接收的配置. 比如邮件配置和企业微信配置等
报警规则:
报警规则允许你定义基于 Prometheus 语言表达的报警条件, 并发送报警通知到外部服务. 一般在 prometheus 的配置文件里面配置.
FOR 子句使得 Prometheus 等待第一个传进来的向量元素(例如高 HTTP 错误的实例), 并计数一个警报. 如果元素是 active, 但是没有 firing 的, 就处于 pending 状态.
LABELS(标签)子句允许指定一组附加的标签附到警报上. 现有的任何标签都会被覆盖, 标签值可以被模板化.
ANNOTATIONS(注释)子句指定另一组未查明警报实例的标签, 它们被用于存储更长的其他信息, 例如警报描述或者链接, 注释值可以被模板化.
发送警报通知
Prometheus 可以周期性的发送关于警报状态的信息到 Alertmanager 实例, 然后 Alertmanager 调度来发送正确的通知. 该 Alertmanager 可以通过 - alertmanager.url 命令行 flag 来配置.
首先启动一个 alertmanager 的 deployment, 配置清单如下:
- # 第一个文件是 alertmanager 的 configmap, 其中定义了邮件和企业微信通知
- [[email protected] altermanager]# cat altermanager-configmap.YAML
- kind: ConfigMap
- apiVersion: v1
- metadata:
- name: alertmanager-config
- namespace: kube-system
- data:
- config.YAML: |-
- global:
- resolve_timeout: 5m #该参数定义了当 Alertmanager 持续多长时间未接收到告警后标记告警状态为 resolved(已解决)
- smtp_smarthost: 'smtp.exmail.qq.com:25'
- smtp_from: '[email protected]'
- smtp_auth_username: '[email protected]'
- smtp_auth_password: '111111'
- smtp_hello: 'test.cn'
- smtp_require_tls: false
- wechat_api_url: "https://qyapi.weixin.qq.com/cgi-bin/" #企业微信的 API 参数, 后续会介绍
- wechat_api_secret: "dfadfadsfsdgfsdgdfhgfhggsfadf"
- wechat_api_corp_id: "1223435sdfsdfsd"
- templates:
- - '/usr/local/prometheus/alertmanager/template/default.tmpl'
- route:
- receiver: 'alert-emailer' #定义第一个邮件接受器
- group_by: ['alertname','priority']
- group_wait: 10s #发送一组新的警报的初始等待时间, 也就是初次发警报的延时
- group_interval: 5m #初始警报组如果已经发送, 需要等待多长时间再发送同组新产生的其他报警
- repeat_interval: 30m #如果警报已经成功发送, 间隔多长时间再重复发送
- routes:
- - receiver: email
- group_wait: 10s
- match: #这里定义了匹配的标签, 需要和 prometheus 里面的规则文件的标签一致, 也就是有 team: node 标签的告警, 通过邮件来告警, 如果有 team: node2 标签的通过企业微信来告警
- team: node
- - receiver: wechat
- group_wait: 10s
- match:
- team: node2
- receivers:
- - name: 'wechat'
- wechat_configs:
- - send_resolved: true
- to_user: "GaoYang" #企业微信的用户 ID
- agent_id: "1000002" # 企业微信的 App 应用 ID, 需要提前在企业微信里面创建应用;
- corp_id: "1223435sdfsdfsd" # 企业微信公司 ID
- api_secret: "dfadfadsfsdgfsdgdfhgfhggsfadf"
- - name: 'alert-emailer'
- email_configs:
- - to: [email protected]
- send_resolved: true
- - name: email
- email_configs:
- - to: '[email protected]'
- send_resolved: true
- # 第二个文件是定义企业微信发送的模板格式文件
- [[email protected] altermanager]# cat altermanager-template-configmap.YAML
- apiVersion: v1
- kind: ConfigMap
- metadata:
- creationTimestamp: null
- name: alertmanager-templates
- namespace: kube-system
- data:
- default.tmpl: |
- {{ define "wechat.default.message" }}
- {{ range .Alerts }}
- ========start==========
告警程序: prometheus_alert
告警级别:{{ .Labels.severity }}
告警类型:{{ .Labels.alertname }}
故障主机: {{ .Labels.instance }}
告警主题: {{ .Annotations.summary }}
告警详情: {{ .Annotations.description }}
触发时间: {{ .StartsAt.Format "2006-01-02 15:04:05" }}
- ========end==========
- {{ end }}
- {{ end }}
- [[email protected] altermanager]#
- # 定义一个持久化的存储
- [[email protected] altermanager]# cat altermanager-pvc.YAML
- kind: PersistentVolumeClaim
- apiVersion: v1
- metadata:
- name: alertmanager
- namespace: kube-system
- spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 50Gi
- [[email protected] altermanager]#
- # 定义一个 deployment 文件
- [[email protected] altermanager]# cat altermanager-Deployment.YAML
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: alertmanager
- namespace: kube-system
- spec:
- replicas: 1
- selector:
- matchLabels:
- App: alertmanager
- template:
- metadata:
- name: alertmanager
- labels:
- App: alertmanager
- spec:
- containers:
- - name: alertmanager
- image: prom/alertmanager:latest
- args:
- - "--config.file=/etc/alertmanager/config.yml"
- - "--storage.path=/alertmanager"
- ports:
- - name: alertmanager
- containerPort: 9093
- volumeMounts:
- - name: config-volume #挂载配置文件
- mountPath: /etc/alertmanager
- - name: alertmanager
- mountPath: /alertmanager
- - name: alertmanager-templates #挂载模板文件
- mountPath: /usr/local/prometheus/alertmanager/template/
- volumes:
- - name: config-volume
- configMap:
- name: alertmanager-config
- - name: alertmanager-templates
- configMap:
- name: alertmanager-templates
- - name: alertmanager
- persistentVolumeClaim:
- claimName: alertmanager
- # 定义一个 ingress
- [[email protected] altermanager]# cat altermanager-ing.YAML
- apiVersion: extensions/v1beta1
- kind: Ingress
- metadata:
- name: altermanager
- namespace: kube-system
- spec:
- rules:
- - host: k8s.altermanager.test.site
- http:
- paths:
- - path: /
- backend:
- serviceName: alertmanager
- servicePort: 9093
- # 定义一个时区文件, 更正容器中的时区
- [[email protected] altermanager]# cat presetpod.YAML
- apiVersion: settings.k8s.io/v1alpha1
- kind: PodPreset
- metadata:
- name: alert-timezone2
- namespace: kube-system
- spec:
- selector:
- matchLabels:
- App: alertmanager
- env:
- - name: TZ
- value: Asia/Shanghai
- # 定义一个服务文件
- [[email protected] altermanager]# cat alertmanager-Service.YAML
- apiVersion: v1
- kind: Service
- metadata:
- name: alertmanager
- namespace: kube-system
- annotations:
- prometheus.io/scrape: 'true'
- prometheus.io/path: /
- prometheus.io/port: '8080'
- spec:
- selector:
- App: alertmanager
- type: NodePort
- ports:
- - port: 9093
- targetPort: 9093
- nodePort: 31000
- [[email protected] altermanager]#
另外说下 Alert 的三种状态:
1. pending: 警报被激活, 但是低于配置的持续时间. 这里的持续时间即 rule 里的 FOR 字段设置的时间. 改状态下不发送报警.
2. firing: 警报已被激活, 而且超出设置的持续时间. 该状态下发送报警.
3. inactive: 既不是 pending 也不是 firing 的时候状态变为 inactive
配置 prometheus 的告警规则
- [[email protected] prometheus]# cat configmap.YAML
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: prometheus-config
- namespace: kube-system
- data:
- prometheus.rules: |-
- groups:
- - name: node-resource #规则组名称
- rules:
- - alert: InstanceDown #单个规则的名称
- expr: up == 0 #匹配规则, 就是 prometheus 里面的 targets 属于 down 的状态
- for: 1m #持续时间
- labels: #标签
- team: node # 自定义标签, 和前面的 alertmanager configmap 里面的标签关联起来
- annotations: # 告警正文
- description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minutes.'
- summary: Instance {{ $labels.instance }} down
- - alert: NodeFilesystemUsage
- expr: (node_filesystem_size_bytes{device="rootfs"} - node_filesystem_free_bytes{device="rootfs"}) / node_filesystem_size_bytes{device="rootfs"} * 100> 90
- for: 2m
- labels:
- team: node
- annotations:
- summary: "{{$labels.instance}}: High Filesystem usage detected"
- description: "{{$labels.instance}}: Filesystem usage is above 80% (current value is: {{ $value }}"
- - alert: NodeMemoryUsage
- expr: (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes+node_memory_Buffers_bytes+node_memory_Cached_bytes )) / node_memory_MemTotal_bytes * 100> 90
- for: 2m
- labels:
- team: node
- annotations:
- summary: "{{$labels.instance}}: High Memory usage detected"
- description: "{{$labels.instance}}: Memory usage is above 20% (current value is: {{ $value }}"
- - alert: NodeCPUUsage
- expr: (100 - (avg by (instance) (irate(node_cpu{job="kubernetes-node-exporter",mode="idle"}[5m])) * 100))> 90
- for: 2m
- labels:
- team: node
- annotations:
- summary: "{{$labels.instance}}: High CPU usage detected"
- description: "{{$labels.instance}}: CPU usage is above 80% (current value is: {{ $value }}"
- - alert: node_memory_Dirty
- expr: node_memory_Dirty_bytes>200000
- for: 2m
- labels:
- team: node
- annotations:
- summary: "{{$labels.instance}}: node_memory_dirty_bytes detected"
- description: "{{$labels.instance}}: node_memory_dirty_bytes is above 200K (current value is: {{ $value }}"
- prometheus.YAML: |-
- global:
- scrape_interval: 1m #Server 端抓取数据的时间间隔
- evaluation_interval: 1m #评估报警规则的时间间隔
- rule_files:
- - "/etc/prometheus/prometheus.rules" #定义告警文件, 这个文件是通过 configmap 映射到容器的 etc 目录
4. 通过企业微信创建企业和应用;
1. 申请一个企业微信号:
2. 管理员登录企业微信 Web 管理控制台:
3. 创建接收消息的子部门:
4. 添加子部门成员:
5. 新建 "自建"->"创建应用":
6. 点创建应用完成后, 会生成 AgentId 和 Secret:
7. 企业微信收到告警的效果
关于博文详细内容请关注我的个人微信公众号 "云时代 IT 运维", 本公众号旨在共享互联网运维新技术, 新趋势; 包括 IT 运维行业的咨询, 运维技术文档分享. 重点关注 devops,jenkins,zabbix 监控, kubernetes,ELK, 各种中间件的使用, 比如 Redis,MQ 等; shell 和 python 等运维编程语言; 本人从事 IT 运维相关的工作有十多年. 2008 年开始专职从事 Linux/Unix 系统运维工作; 对运维相关技术有一定程度的理解. 本公众号所有博文均是我的实际工作经验总结, 基本都是原创博文. 我很乐意将我积累的经验, 心得, 技术与大家分享交流! 希望和大家在 IT 运维职业道路上一起成长和进步;
来源: http://www.bubuko.com/infodetail-3064135.html