Docker 容器内获取宿主机资源内存、执行docker命令及常用命令tcpdump无安装使用等(nsenter)

一、作用场景及知识点

  1. 使用场景(SSH方式除外):

    A. 运行在Docker容器里面的程序,怎么采集宿主机的CPU、内存、磁盘等信息;

    B. 容器内更改宿主机的网卡信息,怎么操作宿主机执行命令;

    C. 容器内命令不足,如telnet调试端口,怎么利用宿主机的工具命令。

  2. 知识点介绍

    A. Docker和宿主机共用一个内核,Namespace的隔离依然没有完全隔离Linux资源,如:/proc、/sys、/dev/sd*等目录;

    B. 使用Docker问题:在Docker容器中执行top、free命令,看到的资源情况是宿主机的资源消耗比例,而不是这个容器被限制了多少CPU、内存;

    C. 设置容器特权级运行:--privileged,比如容器内操作内核模块、挂载USB磁盘、修改MAC地址等,设置privileged=true即可;

    D. 设置容器特权白名单:--cap-add,privileged=true等同于cap-add=ALL,其权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加权限限制,只提供给容器必须的权限。

 

二、实际应用

  1. Docker容器操作宿主机命令

    A. 修改Docker Compose配置文件

      pid=host,使用宿主机命名空间,方便容器获取到宿主机所有进程信息,其中/proc/1作为nsenter的目标;

      privileged=true,使得docker容器有root权限执行宿主机命令,确保从容器执行命令时不会报权限不足提示;

    B. nsenter执行宿主机命令查看IP信息:nsenter -n -t 1 ip addr

      nsenter命令是一个可以在指定进程的命令空间下运行指定程序的命令,位于util-linux包中,格式:nsenter -a -t <pid> <command> 或者nsenter -m -u -i -n -p -t <pid> <command> ;

      -a表示进入宿主机的所有命名空间,linux旧版本可能不支持,需要替换为-m -u -i -n -p、-m表示进入mount命令空间、-u表示进入uts命令空间、-i表示进入ipc命令空间、-n表示进入net命令空间、-p表示进入pid命令空间、-U表示进入user命令空间、-t表示被进入命名空间的目标进程的pid;

       可以先输入nsenter -n -1进入1空间,然后输入ip addr命令,最后执行exit退出。

  2. Docker容器权限(nsenter -m -u -i -n -p -t 1)

    A. 配置SYS_ADMIN,否则报错:

    B. 配置SYS_PTRACE,否则报错: 

    C. 配置NET_ADMIN,否则报错:

   3. nsenter命令安装

FROM baseImage
RUN apk add util-linux --no-cache

   4. 问题集

    A. 在java代码docker容器里使用nsetner调用shell脚本,当shell脚本中需要进入另外一个容器执行某些命令,如mysql容器,会出现部分脚本不执行,但是手动执行又可以,此时解决方式为进入容器方式docker exec -it mysql -h127.0.0.1 -uroot -p123456 -e "show databases"换成 docker exec -d mysql -h127.0.0.1 -uroot -p123456 -e "show databases"

   5. 利用宿主机命令来调试Docker容器

    A. 查看容器的PID:docker inspect -f {{.State.Pid}} 容器ID或NAME;

    B. 进入容器命令空间:nsenter -n -t PID [<command>](不带command时,执行完后不会有任何提示);

    C. 抓取数据包:tcpdump -nn -i veth728d560 port 8081。

 

posted @ 2022-11-02 14:32  如幻行云  阅读(3160)  评论(0编辑  收藏  举报