AppArmor对Docker容器的影响

2025-07-07 19:13:00
丁国栋
原创 349
摘要:AppArmor对Docker容器的影响。

今天有个测试同学在其自己的 Ubuntu 24 LTS 系统中意外的执行了错误命令 find / -name "mysql*" -delete。结果发现之前可以通过 docker compose 正常拉起的 MySQL 容器无法启动了,虽然容器启动了但因为提示找不到 MySQL 数据目录而退出。


  1. 测试其他容器发现可以正常启动并没有问题
  2. 使用 docker system prunedocker volume prune 发现不起作用
  3. 卸载和清理 Docker 服务,发现不起作用
  4. 一开始是用普通用户启动 Docker 容器,发现启动后报错,尝试使用 root 用户启动,发现启动成功,因此确定这是个权限问题
  5. 检查了数据库持久化目录的权限发现没有问题,移除数据库持久化目录数据和目录发现问题依然存在
  6. 怀疑是 AppArmor 拦截,于是检查 Docker 服务日志 和 系统日志,没有发现明显提示异常
  7. 去另一台正常的 Ubuntu 24 LTS 查找 /etc/ 下与 mysql 和 apparmor 相关的文件,发现有个/etc/apparmor.d/abstractions/mysql,将其复制到问题服务器,重新启动 MySQL 容器发现问题解决
  8. 由此可确定是 AppArmor 拦截的问题

参考:

AppArmor security profiles for Docker https://docs.docker.com/engine/security/apparmor/

--

另一个案例是我们将一个含有 mysql 服务容器的服务从节点A迁移到节点B,也出现了容器内MySQL进程无法读写配置文件和错误日志的问题,MySQL 并不报错且日志文件没有新的写入,后来通过 dmesg 命令发现也是 AppArmor 拦截了。


[174314.300157] audit: type=1400 audit(1774590209.475:3511): apparmor="DENIED" operation="open" profile="/usr/sbin/mysqld" name="/opt/ydisks/log/mysql/error.log" pid=745299 comm="mysqld" requested_mask="ac" denied_mask="ac" fsuid=1000 ouid=1000

处理办法参照《AppArmor 常见问题和快速指南》,修改 /etc/apparmor.d/usr.sbin.mysqld 文件添加目录和权限并执行 apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld 应用变更。

由此可见的是,AppArmor 不仅限制主机中的进程,容器中的进程同样也是限制(当然我们也知道容器的进程也是主机的进程)。尽管可以使用 docker run --security-opt apparmor=unconfined ... 来避开AppArmor对容器的限制,但不建议这样做。

另外,我们可以得出的经验是,在设计应用目录结构时尽可能考虑与包管理提供的一致,例如MySQL的配置文件、数据目录和日志目录与默认官方保持一致。

为什么之前没有这个问题呢?我也查过之前节点A的AppArmor的配置,它也是启用的,但不同的是 节点A 并没有安装 MySQL。而节点B安装了 MySQL 就附带了来自官方的AppAppArmor配置 /etc/apparmor.d/usr.sbin.mysqld ,因此也就受到了限制。

--

发表评论
博客分类