容器环境下使用glances监控系统资源

需求 当后端服务进入容器之后,有些读取系统资源状态的结果可能会因为容器命名空间的原因而产生错误
【容器环境下使用glances监控系统资源】最明显的就是读取IP信息的时候会直接读取后端容器的IP,在容器当中不管是采用ifconfig方式还是采用代码psutil方式读取,都是只能读取容器IP,所以就产生了一个需求,需要一个强大的系统资源监控
解决方案 使用一个开源完整的资源监控项目,目前github标星20k+

https://github.com/nicolargo/glances

项目可以使用pipdocker版本安装,本方案采用docker安装,也可以使用pip安装体验一下
$ pip install glances $ python -m glances

容器环境下使用glances监控系统资源
文章图片

监控的指标包括以下CPU,磁盘,内存,磁盘读写速度,进程信息,内网公网IP,网口网速,容器服务,电池CPU温度,内核版本,启动时间等等
docker实现
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it nicolargo/glances

docker compose实现 新建compose.yaml
services: glances: image: nicolargo/glances:latest-full container_name: demo-glances restart: always pid: host volumes: - /var/run/docker.sock:/var/run/docker.sock:ro command: /bin/sh -c "python3 -m glances -w --disable-webui --bind 172.17.0.1" network_mode: host healthcheck: test: curl http://172.17.0.1:61208/

参数
image
  • nicolargo/glances:latest-full采用最新版本镜像,如果追求更小的镜像可以选择标签alpine-latest
pid
  • host参数表示使用宿主机进程命名空间,这样可以准确读取到宿主机其他进程信息
volumes
  • /var/run/docker.sock:/var/run/docker.sock:ro只读方式把dockersocket挂载进入容器确保可以正常读取宿主机容器状态
command下的glances参数
  • -w表示使用web服务器模式
  • --disable-webui表示关闭web服务接口,只留下Restful服务
  • --bind 172.17.0.1表示服务地址绑定到这个IP地址,该IP地址是固定的,详细解释查看下文docker桥接网络模式部分
network_mode
  • host表示使用宿主机网络命名空间
healthcheck
  • 表示进行容器健康状态检查,glances默认使用61208端口
服务启动
$ docker compose up -d

测试访问 容器内访问和容器外访问url都是一样的
访问之后的返回响应的值会依据用户网络情况变化
glancesrestful服务
  • glancesRestful服务默认监听61208端口
  • 通过访问IP地址172.17.0.1进行访问
测试容器外部访问
$ curl http://172.17.0.1:61208/api/3/ip {"address": "10.30.6.24", "mask": "255.255.248.0", "mask_cidr": 21, "gateway": "10.30.0.1", "public_address": "115.205.148.68"}

测试其他容器的容器内部访问
$ docker run curlimages/curl /bin/sh -c "curl http://172.17.0.1:61208/api/3/ip" % Total% Received % XferdAverage SpeedTimeTimeTimeCurrent DloadUploadTotalSpentLeftSpeed 100127100127006480 --:--:-- --:--:-- --:--:--651 {"address": "10.30.6.24", "mask": "255.255.248.0", "mask_cidr": 21, "gateway": "10.30.0.1", "public_address": "115.205.148.68"}或者也可以先进入容器之后执行 $ docker run -it curlimages/curl /bin/sh / $ curl http://172.17.0.1:61208/api/3/ip {"address": "10.30.6.24", "mask": "255.255.248.0", "mask_cidr": 21, "gateway": "10.30.0.1", "public_address": "115.205.148.68"}

python代码方式使用 创建文件demo.py写入如下
import requestsif __name__ == '__main__': url = 'http://172.17.0.1:61208/api/3/ip' response = requests.get(url=url).json() print(response)

如果有现成的python环境可以直接执行python demo.py查看结果
可以使用python镜像测试一下,使用python:3-bullseye的镜像,该镜像是使用最新python版本,进入容器后先安装依赖
$ docker run -it python:3-bullseye /bin/bash root@e81c69632d86:/# pip install requests -i https://mirrors.aliyun.com/pypi/simple/

安装完成之后写入文件
root@e81c69632d86:/# cat > demo.py <

检查文件写入并且执行测试glances服务是否正常
root@e81c69632d86:/# cat demo.py root@e81c69632d86:/# python demo.py

glances拓展 更详细文档参考glancesRestful服务文档
该开源项目可以获取多种系统资源的信息,每个组件都被封装为一个模块插件
可以先获取服务所有的插件
$ curl http://172.17.0.1:61208/api/3/pluginslist ["folders", "percpu", "sensors", "system", "wifi", "alert", "docker", "uptime", "gpu", "load", "amps", "connections", "mem", "cpu", "fs", "memswap", "quicklook", "processlist", "help", "ip", "smart", "network", "irq", "diskio", "psutilversion", "ports", "now", "cloud", "processcount", "core", "raid"]

基本的urlhttp://172.17.0.1:61208/api/3/{插件名称}
如果要指定更详细字段,urlhttp://172.17.0.1:61208/api/3/{插件名称}/{字段的key值}
IP插件 获取IP信息
$ curl http://172.17.0.1:61208/api/3/ip {"address": "10.30.6.24", "mask": "255.255.248.0", "mask_cidr": 21, "gateway": "10.30.0.1", "public_address": "115.205.148.68"}

获取更详细具体的信息
$ curl http://172.17.0.1:61208/api/3/ip/address {"address": "10.30.6.24"}

diskio模块 获取所有硬盘信息
$ curl http://172.17.0.1:61208/api/3/diskio [{"time_since_update": 82.1883933544159, "disk_name": "loop0", "read_count": 0, "write_count": 0, "read_bytes": 0, "write_bytes": 0, "key": "disk_name"}, {"time_since_update": 82.1883933544159, "disk_name": "loop1", "read_count": 0, "write_count": 0, "read_bytes": 0, "write_bytes": 0, "key": "disk_name"}, {"time_since_update": 82.1883933544159, "disk_name": ..............................

只获取硬盘名称
$ curl http://172.17.0.1:61208/api/3/diskio/disk_name {"disk_name": ["sda", "sda1", "sda2", "sda3", "sda4""]}

docker桥接网络知识拓展 docker网络列表
$ docker network ls 90f665152266bridgebridgelocal 0812cab7929chosthostlocal 089112aab72bnonenulllocal

bridge网络 新建容器默认使用bridge模式,会在网桥docker0上为容器创建新的网络栈
查看bridge信息,bridge网络空间的默认网关是172.17.0.1
$ docker network inspect bridge [ { "Name": "bridge", "Id": "90f6651522663d95f1a7e451026ed4c7b996115f70edd3493394681bc89f5d00", "Created": "2022-07-02T10:14:08.205251857+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "e81c69632d860104a60de7e1173332cca85887bf012dd072c3f002cb68561617": { "Name": "charming_dijkstra", "EndpointID": "f4955572e6529a58acfe4076f8876f8ca022d997147254048fabb0779df1755e", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]

host网络 容器和宿主机共享网络命名空间
none网络 不配置网络,用户可以自行进入容器配置网络(不推荐使用)
docker0配置
  • 只要安装了docker,就会有一个网卡docker0
  • docker0相当于一个路由器的作用
  • 任何一个容器启动默认都是docker0网络,docker默认会给容器分配一个可用ip,并把它同docke0相连,使用到的就是veth pair技术
  • IP地址是固定的,目前安装docker的时候默认配置的IP就是172.17.0.1
$ ip addr show docker0 10: docker0: mtu 1500 qdisc noqueue state UP group default link/ether 02:42:5c:de:63:85 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:5cff:fede:6385/64 scope link valid_lft forever preferred_lft forever

目前关于docker网络技术比较复杂,从使用上最简单的描述就是当容器网络配置为host模式之后,可以在宿主机和其他容器内部通过访问172.17.0.1地址访问到这个容器
参考阅读 docker桥接网络模式
glancesRestful服务文档
深入理解docker网络原理

    推荐阅读