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 i p 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 - t 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。