AppArmor对Docker容器的影响
- 2025-07-07 19:13:00
- 丁国栋
- 原创 348
今天有个测试同学在其自己的 Ubuntu 24 LTS 系统中意外的执行了错误命令 find / -name "mysql*" -delete。结果发现之前可以通过 docker compose 正常拉起的 MySQL 容器无法启动了,虽然容器启动了但因为提示找不到 MySQL 数据目录而退出。
- 测试其他容器发现可以正常启动并没有问题
- 使用
docker system prune和docker volume prune发现不起作用 - 卸载和清理 Docker 服务,发现不起作用
- 一开始是用普通用户启动 Docker 容器,发现启动后报错,尝试使用 root 用户启动,发现启动成功,因此确定这是个权限问题
- 检查了数据库持久化目录的权限发现没有问题,移除数据库持久化目录数据和目录发现问题依然存在
- 怀疑是 AppArmor 拦截,于是检查 Docker 服务日志 和 系统日志,没有发现明显提示异常
- 去另一台正常的 Ubuntu 24 LTS 查找 /etc/ 下与 mysql 和 apparmor 相关的文件,发现有个
/etc/apparmor.d/abstractions/mysql,将其复制到问题服务器,重新启动 MySQL 容器发现问题解决 - 由此可确定是 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 ,因此也就受到了限制。
--