返回顶部
首页 > 资讯 > 前端开发 > html >为什么strace在Docker容器中无法工作
  • 799
分享到

为什么strace在Docker容器中无法工作

2024-04-02 19:04:59 799人浏览 八月长安
摘要

本篇内容主要讲解“ 为什么strace在Docker容器中无法工作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ 为什么strace在Docker容器中无法工作

本篇内容主要讲解“ 为什么strace在Docker容器中无法工作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ 为什么strace在Docker容器中无法工作”吧!

这里的问题是 —— 如果我在笔记本上的 Docker 容器中运行 strace,就会出现这种情况:

$ docker run  -it ubuntu:18.04 /bin/bash $ # ... install strace ... [email protected]:/# strace ls strace: ptrace(PTRACE_TRACEME, ...): Operation not permitted

strace 通过 ptrace 系统调用起作用,所以如果不允许使用 ptrace,它肯定是不能工作的! 这个问题很容易解决 ——  在我的机器上,是这样解决的:

docker run --cap-add=SYS_PTRACE -it ubuntu:18.04 /bin/bash

但我对如何修复它不感兴趣,我想知道为什么会出现这种情况。为什么 strace 不能工作,为什么--cap-add=SYS_PTRACE  可以解决这个问题?

假设 1:容器进程缺少 CAP_SYS_PTRACE 能力。

我一直以为原因是 Docker 容器进程默认不具备 CAP_SYS_PTRACE 能力。这和它可以被 --cap-add=SYS_PTRACE  修复是一回事,是吧?

但这实际上是不合理的,原因有两个。

原因 1:在实验中,作为一个普通用户,我可以对我的用户运行的任何进程进行 strace。但如果我检查我的当前进程是否有 CAP_SYS_PTRACE  能力,则没有:

$ getpcaps $$ Capabilities for `11589': =

原因 2:capabilities 的手册页对 CAP_SYS_PTRACE 的介绍是:

CAP_SYS_PTRACE        * Trace arbitrary processes using ptrace(2);

所以,CAP_SYS_PTRACE 的作用是让你像 root 一样,可以对任何用户拥有的任意进程进行  ptrace。你不需要用它来对一个只是由你的用户拥有的普通进程进行 ptrace 。

我用第三种方法测试了一下(LCTT 译注:此处可能原文有误) —— 我用 docker run --cap-add=SYS_PTRACE -it  ubuntu:18.04 /bin/bash 运行了一个 Docker 容器,去掉了 CAP_SYS_PTRACE  能力,但我仍然可以跟踪进程,虽然我已经没有这个能力了。什么?为什么?!

假设 2:关于用户命名空间的事情?

我的下一个(没有那么充分的依据的)假设是“嗯,也许这个过程是在不同的用户命名空间里,而 strace  不能工作,因为某种原因而行不通?”这个问题其实并不相关,但这是我观察时想到的。

容器进程是否在不同的用户命名空间中?嗯,在容器中:

root@e27f594da870:/# ls /proc/$$/ns/user -l ... /proc/1/ns/user -> 'user:[4026531837]'

在宿主机:

bork@kiwi:~$ ls /proc/$$/ns/user -l ... /proc/12177/ns/user -> 'user:[4026531837]'

因为用户命名空间 ID(4026531837)是相同的,所以容器中的 root 用户和主机上的 root  用户是完全相同的用户。所以,绝对没有理由不能够对它创建的进程进行 strace!

这个假设并没有什么意义,但我(之前)没有意识到 Docker 容器中的 root 用户和主机上的 root 用户同一个,所以我觉得这很有意思。

假设 3:ptrace 系统的调用被 seccomp-bpf 规则阻止了

我也知道 Docker 使用 seccomp-bpf 来阻止容器进程运行许多系统调用。而 ptrace 在被 Docker 默认的 seccomp  配置文件阻止的系统调用列表中!(实际上,允许的系统调用列表是一个白名单,所以只是ptrace 不在默认的白名单中。但得出的结果是一样的。)

这很容易解释为什么 strace 在 Docker 容器中不能工作 —— 如果 ptrace 系统调用完全被屏蔽了,那么你当然不能调用它,strace  就会失败。

让我们来验证一下这个假设 —— 如果我们禁用了所有的 seccomp 规则,strace 能在 Docker 容器中工作吗?

$ docker run --security-opt seccomp=unconfined -it ubuntu:18.04  /bin/bash $ strace ls execve("/bin/ls", ["ls"], 0x7ffc69a65580 ) = 0 ... it works fine ...

是的,很好用!很好。谜底解开了,除了…..

为什么 --cap-add=SYS_PTRACE 能解决问题?

我们还没有解释的是:为什么 --cap-add=SYS_PTRACE 可以解决这个问题?

docker run 的手册页是这样解释 --cap-add 参数的。

--cap-add=[]    Add linux capabilities

这跟 seccomp 规则没有任何关系! 怎么回事?

我们来看看 Docker 源码

当文档没有帮助的时候,唯一要做的就是去看源码。

Go 语言的好处是,因为依赖关系通常是在一个 Go 仓库里,你可以通过 grep 来找出做某件事的代码在哪里。所以我克隆了  GitHub.com/moby/moby,然后对一些东西进行 grep,比如 rg CAP_SYS_PTRACE。

我认为是这样的。在 containerd 的 seccomp 实现中,在  contrib/seccomp/seccomp/seccomp_default.go 中,有一堆代码来确保如果一个进程有一个能力,那么它也会(通过  seccomp 规则)获得访问权限,以使用与该能力相关的系统调用。

case "CAP_SYS_PTRACE":        s.Syscalls = append(s.Syscalls, specs.LinuxSyscall{            Names: []string{                "kcmp",                "process_vm_readv",                "process_vm_writev",                "ptrace",            },            Action: specs.ActAllow,            Args:   []specs.LinuxSeccompArg{},        })

在 moby 中的 profile/seccomp/seccomp.go 和 默认的 seccomp  配置文件中,也有一些其他的代码似乎做了一些非常类似的事情,所以有可能就是这个代码在做这个事情。

所以我想我们有答案了!

Docker 中的 --cap-add 做的事情比它说的要多

结果似乎是,--cap-add 并不像手册页里说的那样,它更像是  --cap-add-and-also-whiteelist-some-extra-system-calls-if-required。这很有意义!  如果你具有一个像 --CAP_SYS_PTRACE 这样的能力,可以让你使用 process_vm_readv 系统调用,但是该系统调用被 seccomp  配置文件阻止了,那对你没有什么帮助!

所以当你给容器 CAP_SYS_PTRACE 能力时,允许使用 process_vm_readv 和 ptrace 系统调用似乎是一个合理的选择。

到此,相信大家对“ 为什么strace在Docker容器中无法工作”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: 为什么strace在Docker容器中无法工作

本文链接: https://lsjlt.com/news/84958.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 为什么strace在Docker容器中无法工作
    本篇内容主要讲解“ 为什么strace在Docker容器中无法工作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ 为什么strace在Docker容器中无法工作...
    99+
    2024-04-02
  • 无法在go中为docker容器写入有效的挂载路径
    php小编子墨发现,有一些开发者在使用Go语言编写docker容器时遇到了一个问题,即无法为容器写入有效的挂载路径。这个问题可能导致在容器中进行文件读写操作时出现错误或失败。对于开发者...
    99+
    2024-02-11
    go语言
  • Docker镜像与容器的工作原理是什么
    本篇内容介绍了“Docker镜像与容器的工作原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一. bootfs和rootfs通常而言...
    99+
    2023-06-30
  • Wireshark运算符!=为什么无法正常工作
    本篇文章给大家分享的是有关Wireshark运算符!=为什么无法正常工作,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Wireshark运算符!=无法正常工作在Wireshar...
    99+
    2023-06-05
  • Docker中Mysql容器无法停止无法删除问题
    目录Mysql容器无法停止无法删除问题问题原因Docker中Mysql的使用总结Mysql容器无法停止无法删除问题 问题 mysql容器如法停止,无法删除,也无法连接。docker ...
    99+
    2023-03-07
    Docker Mysql容器 Mysql容器无法停止 Mysql容器无法删除
  • Docker容器数据卷操作方法是什么
    本篇内容介绍了“Docker容器数据卷操作方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!容器数据卷介绍什么是数据卷将运用与运行的环...
    99+
    2023-06-30
  • 为什么go无法访问docker中的8080端口
    php小编西瓜在这里为大家解答一个常见问题:为什么Go语言无法访问Docker容器中的8080端口?在使用Docker容器时,我们常常会遇到无法访问容器内部端口的问题。这往往是因为Do...
    99+
    2024-02-11
    go语言
  • 在DOCKER容器中运行MySQL服务的操作方法
    下面讲讲关于在DOCKER容器中运行MySQL服务的操作方法,文字的奥妙在于贴近主题相关。所以,闲话就不谈了,我们直接看下文吧,相信看完在DOCKER容器中运行MySQL服务的操作方法这篇文章你一定会有所受...
    99+
    2024-04-02
  • Docker中Mysql容器无法停止无法删除如何解决
    这篇文章主要介绍“Docker中Mysql容器无法停止无法删除如何解决”,在日常操作中,相信很多人在Docker中Mysql容器无法停止无法删除如何解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Docke...
    99+
    2023-07-05
  • Docker中列出容器的方法是什么
    在Docker中,要列出正在运行的容器可以使用docker ps命令。这个命令会列出当前正在运行的容器的一些基本信息,如容器ID、名...
    99+
    2024-03-14
    Docker
  • 在 Docker 容器中为您的项目使用 MySQL
    我坚信保持主机系统清洁。 docker 容器是解决这个问题的完美解决方案。假设您正在开发一个带有 node / express 后端和 mysql 服务器的 react 应用程序来满足...
    99+
    2024-08-07
    mysql linux git docker macos
  • docker容器中无法获取宿主机hostname怎么办
    小编给大家分享一下docker容器中无法获取宿主机hostname怎么办,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在nodejs环境中测试通过,其它语言同理,...
    99+
    2023-06-14
  • Docker容器使用方法是什么
    这篇文章主要介绍了Docker容器使用方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Docker容器使用方法是什么文章都会有所收获,下面我们一起来看看吧。新建并启动所需要的命令主要为 dockerru...
    99+
    2023-07-02
  • 怎么在linux中删除Docker容器
    在linux中删除Docker容器的方法:1.启动Docker;2.进入Docker;3.使用docker ps命令Docker容器;4.使用docker stop命令容器;5.执行docker rm命令删除容器;具体步骤如下:首先,在li...
    99+
    2024-04-02
  • 在Docker容器中怎么使用Arthas
    这篇文章主要介绍“在Docker容器中怎么使用Arthas”,在日常操作中,相信很多人在在Docker容器中怎么使用Arthas问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”在Docker容器中怎么使用Art...
    99+
    2023-06-21
  • 在Docker容器中怎么部署MSSQL
    今天小编给大家分享一下在Docker容器中怎么部署MSSQL的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。部署MSSQL需要...
    99+
    2023-06-29
  • Redis快速部署为Docker容器的实现方法是什么
    Redis快速部署为Docker容器的实现方法是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Redis是一种内存键值存储,可以保存高性能的抽象数据结构。开源软件通常用...
    99+
    2023-06-22
  • 为什么要在 Unix 容器中使用 Python 编程算法?
    随着技术的不断发展,容器化技术在软件开发领域越来越受到关注。而 Python 作为一种高级编程语言,也在众多开发者中广受欢迎。在 Unix 容器中使用 Python 编程算法,可以带来很多好处。本文将从以下几个方面详细介绍。 环境隔离 ...
    99+
    2023-06-15
    编程算法 unix 容器
  • 为什么无法在IDEA中使用Spring-boot-devTools
    本篇文章为大家展示了为什么无法在IDEA中使用Spring-boot-devTools,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。相信大部分使用Intellij的同学都会遇到这个问题,即使项目使用...
    99+
    2023-05-31
    idea spring-boot-devtools
  • docker容器管理的方法是什么
    Docker容器可以通过以下几种方法进行管理: Docker CLI:使用Docker命令行工具来管理和操作容器,如创建、启动、...
    99+
    2024-04-02
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作