有什么方法可以确定一个进程(脚本)是否在lxc容器中运行(~ Docker runtime)?我知道一些程序能够检测它们是否在虚拟机中运行,lxc/docker是否也有类似的功能?
当前回答
golang代码得到pid container_id,你可以得到map container_id get docker image
func GetContainerID(pid int32) string {
cgroupPath := fmt.Sprintf("/proc/%s/cgroup", strconv.Itoa(int(pid)))
return getContainerID(cgroupPath)
}
func GetImage(containerId string) string {
if containerId == "" {
return ""
}
image, ok := containerImage[containerId]
if ok {
return image
} else {
return ""
}
}
func getContainerID(cgroupPath string) string {
containerID := ""
content, err := ioutil.ReadFile(cgroupPath)
if err != nil {
return containerID
}
lines := strings.Split(string(content), "\n")
for _, line := range lines {
field := strings.Split(line, ":")
if len(field) < 3 {
continue
}
cgroup_path := field[2]
if len(cgroup_path) < 64 {
continue
}
// Non-systemd Docker
//5:net_prio,net_cls:/docker/de630f22746b9c06c412858f26ca286c6cdfed086d3b302998aa403d9dcedc42
//3:net_cls:/kubepods/burstable/pod5f399c1a-f9fc-11e8-bf65-246e9659ebfc/9170559b8aadd07d99978d9460cf8d1c71552f3c64fefc7e9906ab3fb7e18f69
pos := strings.LastIndex(cgroup_path, "/")
if pos > 0 {
id_len := len(cgroup_path) - pos - 1
if id_len == 64 {
//p.InDocker = true
// docker id
containerID = cgroup_path[pos+1 : pos+1+64]
// logs.Debug("pid:%v in docker id:%v", pid, id)
return containerID
}
}
// systemd Docker
//5:net_cls:/system.slice/docker-afd862d2ed48ef5dc0ce8f1863e4475894e331098c9a512789233ca9ca06fc62.scope
docker_str := "docker-"
pos = strings.Index(cgroup_path, docker_str)
if pos > 0 {
pos_scope := strings.Index(cgroup_path, ".scope")
id_len := pos_scope - pos - len(docker_str)
if pos_scope > 0 && id_len == 64 {
containerID = cgroup_path[pos+len(docker_str) : pos+len(docker_str)+64]
return containerID
}
}
}
return containerID
}
其他回答
Docker每天都在发展,所以我们不能肯定他们将来是否会保留.dockerenv .dockerinit。
在大多数Linux版本中,init是第一个启动的进程。但在容器的情况下,这不是真的。
#!/bin/bash
if ps -p1|grep -q init;then
echo "non-docker"
else
echo "docker"
fi
最简单的方法是检查环境。如果你有container=lxc变量,你就在一个容器中。
否则,如果您是根用户,您可以尝试执行mknod或mount操作,如果失败,则很可能处于已删除功能的容器中。
在Python中检查以上所有的解决方案:
import os
def in_container():
proc_1 = r'/proc/1/sched'
if os.path.exists(proc_1):
with open(proc_1, 'r') as fp:
out = fp.read()
else:
out = ''
checks = [
'docker' in out,
'/lxc/' in out,
out.split(' ')[0] not in ('systemd', 'init',),
os.path.exists('./dockerenv'),
os.path.exists('/.dockerinit'),
os.getenv('container') is not None
]
return any(checks)
if __name__ == '__main__':
print(in_container())
概念证明:
$ docker run --rm -it --mount type=bind,source=${PWD}/incontainer.py,target=/tmp/script.py python:3 python /tmp/script.py
True
这个SO问答:“找出操作系统是否在虚拟环境中运行”;虽然与OP的问题不一样,但它确实回答了找到你所在容器的常见情况(如果有的话)。
特别是,安装并阅读这个bash脚本的代码,它似乎工作得很好:
virt-what:
sudo apt install virt-what
有点跑题了,你可以用两种方法检查你是否在容器中:
Cat /proc/1/environ|tr "\0" "\n"|grep容器:如果你在容器中,你会看到容器变量。 Ps -ef | grep '\[':当你在容器中时,你将只看到grep进程,这意味着你看不到内核进程(例如[kthread])。注意:正常的macOS也不显示内核进程。
参考:这个Linux测试页面
推荐文章
- 如何获得一个变量值,如果变量名存储为字符串?
- 拉访问拒绝存储库不存在或可能需要docker登录
- 如何在ENTRYPOINT数组中使用Docker环境变量?
- Docker:容器不断地重新启动
- RVM不是一个函数,用' RVM use…’不会起作用
- 如何强制从另一个SSH会话分离屏幕?
- 如何打破一个循环在Bash?
- 如何从终端机发送电子邮件?
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- Mac/OS X上的/var/lib/docker在哪里
- 如何用docker-compose标记docker图像
- Linux Bash中双&和分号有什么区别?
- 在Bash中模拟do-while循环
- 在Bash中将输出赋给变量
- 在SSH会话中查找客户端的IP地址