docker容器内执行宿主机的命令

270 阅读1分钟

环境介绍

  • java项目maven打包
  • docker-compose部署运行
  • 服务器系统:centos7

需求

  • 容器内采集到当前服务器上所有docker镜像的cpu、内存,使用率

思路

  • 容器内发命令到宿主机(nsenter)
  • 容器使用宿主机命名空间,方便容器获取到宿主机所有进程信息(pid=host)
  • 给容器赋予与宿主机相同的权限,以免执行命令时,权限不足(privileged=true)

docker-compose 改造

version: "3.9"

services
    my-project:
        image: xxx
        restart: always
        pid: host         # 设置同命令空间
        privileged: true  # 设置同权限

命令脚本

nsenter -n -t 1 /bin/sh -c docker stats --no-stream
# -n 进入网络命令空间,由于配置了与宿主机相同的命名空间,所以现在进入的是宿主机的命名空间
# -t <pid> 获取进程
# -n -t 1 进入pid=1的进程的命名空间(pid=1 就是systemd)

代码+脚本

String[] cmd={"nsenter","-n","-t 1","/bin/sh","-c","docker stats --no-stream"};
try{
    // 执行脚本
    ProcessBuilder builder = new ProcessBuilder(cmd);
    Process process = builder.start();
    boolean flag = process.waitFor(3, TimeUnit.SECONDS);
    
    // 读取脚本返回结果
    if(flag){
        try(BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()))){
            String line = in.readLine();
            // 解析脚本内容
            ...
        }
    }
    
}catch(Exception e){}