1 docker监控方式

Docker的监控,可以使⽤Docker⾃带的stats命令来获取当前主机上运⾏中的容器的资源使⽤情况。例如:容器的CPU使⽤率、内存占⽤、⽹络IO以及磁盘IO等指标。

Prometheus监控之Docker_nginx

# CONTAINER ID: 容器的唯⼀标识符。 
# NAME: 容器的名称。 
# CPU %: 容器使⽤的CPU百分⽐。 
# MEM USAGE / LIMIT: 容器当前的内存使⽤量和它所能使⽤的最⼤内存量。 
# MEM %: 容器使⽤的内存占总分配内存的百分⽐。 
# NET I/O: 容器的⽹络输⼊/输出量,分别显示了接收和发送的总数据量。 
# BLOCK I/O: 容器的磁盘输⼊/输出量,分别显示了读取和写⼊的总数据量。 
# PIDS: 容器内的进程数。
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

另外,Google开源的CAdvisor⼯具就是专⻔针对容器的性能进⾏监测和分析。它提供了⼀个直观的UI界⾯,⽤于展示容器的实时或历史资源使⽤情况。

最为重要的是,CAdvisor能够导出与Prometheus兼容的监控指标,这使得Prometheus可以抓取这些指标,从⽽对容器的资源使⽤进⾏监控和分析。 Cadvisor项⽬地址:(https://github.com/google/cadvisor/releases)

2 Cadvisor

2.1 运行docker容器

运行两个容器应用

docker run -d --memory=100m -p 8081:80 --name nginx1 hub.atomgit.com/amd64/nginx:latest

docker run -d --memory=50m -p 8082:80 --name nginx2 hub.atomgit.com/amd64/nginx:latest

2.2 运⾏Cadvisor

1、启动Cadvisor容器 
docker run -d --name=cadvisor \
-p 8083:8080 \
-v /:/rootfs:ro \
-v /var/run:/var/run:ro \
-v /sys:/sys:ro \
-v /dev/disk/:/dev/disk:ro \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
-v /data/docker/:/var/lib/docker:ro \
--privileged \
gcr.io/cadvisor/cadvisor:v0.47.2

2、Cadvisor提供的metrics地址为
http://192.168.137.128:8083/metrics

3、访问Cadvisor提供的webUI
http://192.168.137.128:8083/containers/
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

Prometheus监控之Docker_docker_02

2.3 配置Prometheus

1、修改Prometheus配置
  - job_name: "docker"
    metrics_path: "/metrics"
    static_configs:
    - targets: ["192.168.137.128:8083"]
 
2、重新加载Prometheus配置⽂件
curl -X POST http://192.168.137.131:9090/-/reload
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

2.4 Docker常⽤指标与示例

2.4.1 Docker CPU相关指标

指标名称

指标类型

指标含义

container_cpu_usage_seconds_total

counter

容器在所有CPU核⼼上累积使⽤的时间,以秒为单位。

container_cpu_user_seconds_total

counter

容器在所有CPU核⼼user模式下累积使⽤的时间,以秒为单位。

container_cpu_system_seconds_total

counter

容器在所有CPU核⼼system模式下累积使⽤的时间,以秒为单位。

案例:计算每个容器的CPU利⽤率。 
1、列出所有容器使⽤CPU的累积时间; 
2、使⽤rate将最近1分钟的使⽤时间专为平均速率; 
3、使⽤sum聚合,⽽后进⾏实例和容器名称的分组,最后乘以100将利⽤率专为百分⽐。
sum(rate(container_cpu_usage_seconds_total{name!=""}[1m])) by(instance,name) * 100
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
2.4.2 Docker 内存相关指标

指标名称

指标类型

指标含义

container_memory_usage_bytes

gauge

容器当前正在使⽤的内存。包括常驻内存,缓存、交换(swap)等类型的内存使⽤情况。

container_memory_working_set_bytes

gauge

容器当前实际使⽤的内存量。仅包括常驻内存,不包括缓存,以及可被回收的内存,因此更它准确。

container_spec_memory_limit_bytes

gauge

容器的内存使⽤上限。如果容器没有设置内存限制,则可能会显示0,或者宿主机的内存。

machine_memory_bytes

gauge

代表当前主机(宿主机)的总内存量(以字节为单位) 

案例1:获取每个容器的内存的实际使⽤量,以MB单位展示
sum(container_memory_working_set_bytes{name!=""}) by(instance,name) /1024 /1024

案例2:计算每个容器的实际内存使⽤,占其配置的内存最⼤限制⽐率。
计算公式:( 容器实际的使⽤内存 / ( 容器限制最⼤能使⽤的内存 > 0 ) * 100 )
sum(container_memory_working_set_bytes{name!=""}) by(instance,name) /
sum(container_spec_memory_limit_bytes{name!=""} > 0) by(instance,name) * 100

案例3:计算所有容器实际使⽤的内存的和,占物理内存的⽐率。
计算公式:( 所有容器内存使⽤的和 / 物理内存 * 100 )
sum(container_memory_working_set_bytes{name!=""}) / sum(machine_memory_bytes)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
2.4.3 Docker磁盘相关指标

指标名称

指标类型

指标含义

container_fs_writes_b ytes_total

counter

容器写⼊的总⼤⼩。

container_fs_reads_bytes_total

counter

容器读取的总⼤⼩。

container_fs_writes_t

otal

counter

容器⾃启动以来的⽂件系统IO写操作的总次数。(IOPS)

container_fs_reads_to

tal

counter

容器⾃启动以来的⽂件系统IO读操作的总次数。(IOPS)

案例1:计算每个容器每秒的磁盘写⼊吞吐量。以MB为单位
# 进⼊nginx1容器执⾏:dd if=/dev/zero of=/bigdata bs=1M count=5000
sum(rate(container_fs_writes_bytes_total{name!=""}[1m])) by(instance,job,name) /1024 /1024

案例2:计算每个容器每秒的磁盘读取吞吐量。以MB为单位
# 进⼊nginx1容器执⾏:dd if=/bigdata of=/dev/null
sum(rate(container_fs_reads_bytes_total{name!=""}[1m])) by(instance,job,name) /1024 /1024

案例3:计算每个容器的每秒的读次数、写次数,也就是每秒的IOPS 
sum(rate(container_fs_reads_total{name!=""}[1m])) by(instance,name)
sum(rate(container_fs_writes_total{name!=""}[1m])) by(instance,name)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
2.4.4 Docker inode相关指标

指标名称

指标类型

指标含义

container_fs_inodes_free

gauge

容器的空闲inode数量。

container_fs_inodes_total

gauge

容器的inode总数。

案例1:计算inode已使⽤率,
计算公式:( (总的inode - 空闲的Inode ) / 总的inode ) * 100 )
(container_fs_inodes_total{name!=""} - container_fs_inodes_free{name!=""})/container_fs_inodes_total{name!=""} * 100
  • 1.
  • 2.
  • 3.
2.4.5 Docker⽹络相关指标

指标名称

指标类型

指标含义

container_network_transmit_bytes_total

counter

容器⾃启动以来发送的⽹络流量的总量,以字节为单位

container_network_receive_bytes_total

counter

容器⾃启动以来接收的⽹络流量的总量,以字节为单位。

案例1:查询每个容器“接收”的总流量⼤⼩,以MB为单位。(如果值太⼩,可以考虑使⽤ab模拟流量) 
sum(container_network_receive_bytes_total{name!=""}) by(instance,name) /1024 /1024

案例2:查询每个容器⽹络“发送”的总流量⼤⼩,以MB为单位。(如果值太⼩,可以考虑使⽤ab模拟流量) 
sum(container_network_transmit_bytes_total{name!=""}) by(instance,name) /1024 /1024
# 环⽐10分钟前的接收流量总⼤⼩⽐率 (当前流量-10分钟前流量) / 10分钟前流量 * 100
(sum(container_network_receive_bytes_total{name!=""}) - sum(container_network_receive_bytes_total{name!=""} offset 10m))
/ sum(container_network_receive_bytes_total{name!=""} offset 10m) * 100

案例3:查询每个容器⽹络每秒“接收”的⼤⼩除以1024,单位为KB/s(如果需要专为带宽兆⽐特Mbps,则需要 *8 /1024/1024) 
sum(rate(container_network_receive_bytes_total{name!=""}[1m])) by (instance,job,name) / 1024

案例4:查询每个容器⽹络每秒“发送”的⼤⼩除以1024,单位为KB/s(如果需要专为带宽兆⽐特Mbps,则需要 *8 /1024/1024)
sum(rate(container_network_transmit_bytes_total{name!=""}[1m])) by (instance,job,name) / 1024
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
2.4.6 Docker其他相关指标

指标名称

指标类型

指标含义

container_tasks_state


gauge

跟踪不同状态下的容器状态的数量,例如:(running、sleeping、stopped)等

container_start_time_seconds

gauge

容器启动的时间戳,可以⽤来确定容器的运⾏时⻓。

container_last_seen

gauge

容器最后⼀次被探测到的时间戳。

案例1:查询正在运⾏的容器数量 
count(container_tasks_state{name!="",state="running"}) 

案例2:查询每个容器所运⾏的时⻓。
计算公式:( 当前时间减去 - 容器运⾏时⻓ / 3600 = 容器运⾏的⼩时 ) 
sum (time() - container_start_time_seconds{name!=""}) by (instance,name) / 3600

案例3:查询是否有容器被删除了、或停⽌运⾏了。
计算公式:(当前时间戳 - 容器上⼀次观测到的时间戳 > 60s 则表明容器可能被停⽌或删除)
sum (time() - container_last_seen{name!=""}) by (instance,name) > 60
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

2.5 Docker告警规则⽂件

2.5.1 告警规则⽂件
vim /app/module/prometheus/rules/docker_rules.yml
groups:
- name: Docker的告警规则
  rules:
  - alert: 容器CPU利用率高
    expr: sum(rate(container_cpu_usage_seconds_total{name!=""}[1m])) by (instance,name) * 100 > 80
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "实例{{ $labels.instance }}的容器{{ $labels.name }}CPU利用率高"
      description: "容器{{ $labels.name }}的CPU利用率当前为{{ $value }}%,超过了80%的阈值。"
  - alert: 容器内存利用率高
    expr: |
      sum(container_memory_working_set_bytes{name!=""}) by (instance,name) /
      sum(container_spec_memory_limit_bytes{name!=""} > 0) by (instance,name) * 100 > 80
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "实例{{ $labels.instance }}的容器{{ $labels.name }}内存利用率高"
      description: 容器{{ $labels.name }}的内存最大限制是{{ printf `sum(container_spec_memory_limit_bytes{instance="%s",name="%s"}) /1024 /1024` $labels.instance $labels.name | query | first | value }}MB , 目前利用率已达{{ $value }}%,超过限制的80%。
  - alert: 容器整体内存利用率高
    expr: sum(container_memory_working_set_bytes{name!=""}) / sum(machine_memory_bytes) * 100 > 80
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "所有容器的总内存利用率高"
      description: "当前所有容器占用物理内存的总量为{{ $value }}%,超过了物理内存的80%阈值。"
  - alert: 容器网络发送速率过高
    expr: sum(rate(container_network_transmit_bytes_total{name!=""}[1m])) by (instance,job,name) * 8 / 1024 / 1024 > 50
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "实例{{ $labels.instance }}的容器{{ $labels.name }}网络发送速率过高"
      description: "容器{{ $labels.name }}的网络发送速率达到{{ $value }}Mbps,超过了50Mbps的阈值。"
  - alert: 容器网络接收速率过高
    expr: sum(rate(container_network_receive_bytes_total{name!=""}[1m])) by (instance,job,name) * 8 / 1024 / 1024 > 50
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "实例{{ $labels.instance }}的容器{{ $labels.name }}网络接收速率过高"
      description: "容器{{ $labels.name }}的网络接收速率达到{{ $value }}Mbps,超过了50Mbps的阈值。"
  - alert: 容器停止时间过长
    expr: sum(time() - container_last_seen{name!=""}) by (instance,name) > 60
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "实例{{ $labels.instance }}的容器{{ $labels.name }}已停止"
      description: "容器{{ $labels.name }}已停止运行超过60秒。当前停止时长 {{$value }}s"
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
2.5.2 检查rules语法

/app/module/prometheus/promtool check rules /app/module/prometheus/rules/docker_rules.yml

2.5.3 重新加载Prometheus

curl -X POST http://192.168.137.131:9090/-/reload

2.5.4 验证告警规则

Prometheus监控之Docker_Docker_03

2.5.5 模拟告警测试
# 启动容器,模拟内存满、然后退出容器模拟容器停⽌时间过⻓
docker stop nginx2
docker exec -it nginx1 /bin/bash 
dd if=/dev/zero of=/dev/null bs=100M count=50000
  • 1.
  • 2.
  • 3.
  • 4.

2.6 导⼊Docker图形

导⼊⼀个Docker Container的Grafana模板。Dashboard ID为 11600