乐趣区

关于docker:容器环境下使用glances监控系统资源

需要

当后端服务进入容器之后,有些读取系统资源状态的后果可能会因为容器命名空间的起因而产生谬误

最显著的就是读取 IP 信息的时候会间接读取后端容器的 IP,在容器当中不论是采纳ifconfig 形式还是采纳代码 psutil 形式读取,都是只能读取容器IP, 所以就产生了一个需要,须要一个弱小的系统资源监控

解决方案

应用一个开源残缺的资源监控我的项目,目前 github 标星20k+

https://github.com/nicolargo/glances

我的项目能够应用 pipdocker版本装置,本计划采纳 docker 装置,也能够应用 pip 装置体验一下

$ pip install glances
$ python -m 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 % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   127  100   127    0     0    648      0 --:--:-- --:--:-- --:--:--   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 requests


if __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 <<EOF
import requests


if __name__ == '__main__':
    url = 'http://172.17.0.1:61208/api/3/ip'
    response = requests.get(url=url).json()
    print(response)
EOF

查看文件写入并且执行测试 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
90f665152266   bridge                  bridge    local
0812cab7929c   host                    host      local
089112aab72b   none                    null      local

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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 网络原理

退出移动版