OpenShift Pod 重建后权限异常:一次 SCC 变更引发的问题

某个运行了两年多的 OpenShift 应用一直非常稳定。某次由于 Node OOM,Pod 被驱逐并重新调度到其他节点。原本以为只是一次普通的重启,结果 Pod 无法启动,日志中出现大量文件和目录权限错误。

由于应用镜像、PVC 和 OpenShift 版本均未发生变化,问题一开始比较难定位。

故障现象

应用启动时出现类似错误:

1
2
3
Permission denied
Cannot create file
Cannot write to directory

查看 Pod 信息发现:

老 Pod:

1
openshift.io/scc: anyuid

新创建的 Pod:

1
openshift.io/scc: restricted-v2

问题开始有了方向。

OpenShift SCC 机制

OpenShift 中的 SCC(Security Context Constraints)决定了 Pod 运行时的安全策略。

常见的 SCC 包括:

1
2
3
restricted-v2
anyuid
privileged

很多人会认为:

1
openshift.io/scc: anyuid

是 Deployment 或 StatefulSet 的固定配置。实际上并不是。

SCC 是在 Pod 创建时动态选择的:

1
2
3
4
5
ServiceAccount + Pod Spec

OpenShift Admission

选择符合条件的 SCC

因此:

1
删除 Pod → 重新创建 Pod → 重新计算 SCC

新 Pod 完全有可能获得与旧 Pod 不同的 SCC。

关键发现

检查一个两年前创建且从未重启过的 Pod:

1
2
serviceAccountName: default
openshift.io/scc: anyuid

说明系统安装时,default ServiceAccount 拥有 anyuid 权限,否则 Pod 不可能获得 AnyUID SCC。

进一步验证:

1
2
oc auth can-i use scc/anyuid \
--as system:serviceaccount:<namespace>:default

结果:

1
no

说明当前的 default ServiceAccount 已经失去了使用 AnyUID 的权限。

Root Cause

系统安装时,default ServiceAccount 允许使用 anyuid,因此创建出来的 Pod 使用 openshift.io/scc: anyuid

后来某个时间点,SCC 或 RBAC 配置发生变化,导致 default ServiceAccount 无法再使用 anyuid。但由于旧 Pod 一直没有重建,问题始终没有暴露。

直到 Node OOM → Pod 被驱逐 → Pod 重建,OpenShift 重新选择 SCC。由于 AnyUID 已不可用,restricted-v2 成为新的 SCC。

为什么 Restricted-v2 会导致启动失败

Restricted-v2 要求容器使用随机非 Root UID,例如:

1
2
uid=1000700000
gid=0

而很多历史镜像中的目录权限是按照固定 UID 或 Root 用户设计的,例如 /opt/app/app/var/log/data。当随机 UID 无法访问这些目录时,就会出现 Permission denied,应用启动失败。

解决方案

方案一:调整 SecurityContext(推荐)

1
2
securityContext:
fsGroup: 1000700000

或者根据应用实际情况调整 runAsUserrunAsGroupfsGroup,使应用兼容 Restricted-v2。

方案二:恢复 AnyUID 权限

1
2
3
oc adm policy add-scc-to-user anyuid \
-z default \
-n <namespace>

验证:

1
2
oc auth can-i use scc/anyuid \
--as system:serviceaccount:<namespace>:default

返回 yes 后,重新创建 Pod 即可重新获得 AnyUID SCC。

排查过程中学到的经验

1. 长时间运行的 Pod 会隐藏问题

一个运行了几年都没有重建过的 Pod,并不能证明当前配置仍然正确。很多问题只有在 Pod 重建、节点迁移、集群升级时才会暴露。

2. SCC 是动态计算的

不要认为 openshift.io/scc: anyuid 会永久存在。每次创建 Pod 时都会重新计算。

3. 尽量不要依赖 Default ServiceAccount

推荐为应用创建专用 ServiceAccount(serviceAccountName: my-app-sa),避免未来权限调整影响整个 Namespace。

4. 优先兼容 Restricted-v2

从 OpenShift 安全模型的发展趋势来看,restricted-v2 已成为默认推荐方案。新开发的应用应尽量避免依赖 anyuidprivileged 等高权限 SCC。

总结

这次问题表面上看是文件权限异常(Permission denied),实际上根因是:

1
2
3
4
5
6
7
8
9
10
11
历史 Pod 使用 AnyUID

ServiceAccount 权限发生变化

Pod 重建

获得 Restricted-v2

随机 UID 无法访问应用目录

启动失败

对于长期运行的 OpenShift 集群,定期检查 SCC、ServiceAccount 和 SecurityContext 配置,是避免此类问题的有效手段。

Notice: 正常情况下,这里会有一个基于utteranc.es的留言系统,如果看不到,可能要想想办法才能看到。

Powered by Hexo and Hexo-theme-hiker

Copyright © 2012 - 2026 tiaobug.com All Rights Reserved.

鲁ICP备2024124237号-1