在容器内启动进程
docker exec -it 9c6b0b0509da /bin/bash
cd /home
./testapp
主机上的监控程序同样可以监控到
13022 /home/testapp
!!!!!发现异常进程:testapp, exePath:/home/testapp
GetExePath()函数返回的值是/home/testapp ,即:进程执行文件所在容器内的目录路径
func (p *Process) GetExePath() (string, error) {ret, err := os.Readlink("/proc/" + p.Pid + "/exe")//println("Readlink:Pid: %d, linkpath:%s \n", p.Pid, ret)if err != nil {return "", err}ret = strings.TrimSpace(ret)p.ExePath = retreturn ret, nil
}
通过访问宿主机进程下的虚拟目录系统发现可以访问到容器内的目录内容
cd /proc/13022/root/home //和容器内的/home目录一致
所以要获取容器进程的目录需要在返回的目录前加上/proc/" + p.Pid+ "/"
func (p *Process) GetExePath() (string, error) {ret, err := os.Readlink("/proc/" + p.Pid + "/exe")//println("Readlink:Pid: %d, linkpath:%s \n", p.Pid, ret)if err != nil {return "", err}ret = strings.TrimSpace(ret)//p.ExePath = retret = "/proc/" + p.Pid + "/root" + ret //容器中的进程只能获取到容器内的相对目录,在宿主机上前面必须加"/proc/" + p.Pid+ "/" 才能获取到return ret, nil
}
//这样返回的路径是: /proc/9374/root/home/testapp/
访问容器内的进程文件所在目录
现在就可以通过proc虚拟目录系统类似快链接方式访问容器内目录,不需要获取到容器的实际挂载全路径。
宿主机进程和容器进程Pid的关系?
ps -a 发现容器内看到的进程号也和宿主机不同不是13022
具体映射关系可以后续研究
如何判断进程是否是在容器中运行的?以及所在容器
/proc/<PID>/cgroup 有记录容器的ID,从而可以判定是某个容器内进程
方式1
查看进程的PID命名空间:每个进程都有一个PID命名空间,容器内的进程会有自己独立的PID命名空间,而宿主机上的进程则共享一个PID命名空间。
/proc/[PID]/ns/pid
文件记录了与该进程所在的 PID 命名空间的信息
可以通过查看进程的/proc/[PID]/ns/pid文件,如果该文件是一个符号链接,且指向的inode与宿主机上的/proc/1/ns/pid文件的inode相同,则说明该进程是宿主机启动的进程。
具体见:https://blog.csdn.net/lwyeluo/article/details/51803207
1、启动容器名字或id,通过docker **命令可以获取该容器的第一个进程的ID信息,通过该进程可以知道该容器的PID namespace标号;
2、同样容器内启动任意进程PID(主机上看到的)可以获取到所在namespace标号,这样就建立了容器和任意进程的关联。
方式2
查看进程的根文件系统:容器内的进程会有自己独立的根文件系统,而宿主机上的进程则使用宿主机的根文件系统。可以通过查看进程的/proc/[PID]/root目录,如果该目录是一个符号链接,且指向的路径与宿主机上的根文件系统路径不同,则说明该进程是容器内启动的进程。
方式3
查看进程的命令行参数:容器内的进程通常会有特定的命令行参数,用于标识其为容器内启动的进程。可以通过查看进程的/proc/[PID]/cmdline文件,查看其中的命令行参数是否包含容器相关的标识,如Docker、Kubernetes等
#查看容器ID列表
docker inspect -f "{{.Id}}" $(docker ps -q) |grep
#查看容器进程ID、容器ID、容器名称列表
docker inspect -f "{{.Id}} {{.State.Pid}} {{.Config.Hostname}}" $(docker ps -q) |grep
#查看容器内top占用进程信息
for i in `docker ps |grep Up|awk '{print $1}'`;do echo \ &&docker top $i &&echo ID=$i; done |grep -A