1. 故障现象
环境在跑自动化测试时打印 error: [ ERROR ] Opening output file '/output.xml' failed: Read-only file system。
2 测试流程
通过 helm chart 部署 pod,在 pod 的指定 container 内运行 robot case。其中,运行的 robot case 需要读写文件。
3. 故障分析
- [ ] 用户权限问题
打印 Read-only file system,排查是不是运行 container 的 id 不是 root,导致无法访问指定目录。
检查 helm chart 及 container id ,发现用户和用户组均是 root。
kubernetes 平台上 container 和 host 未做用户隔离,container 运行的用户即是 host 上的 root。排除了这点还有什么限制呢?
- [x] scc
除了 container 配置自身的限制还有 kubernetes 集群级别的 scc 限制 container 对 host 上文件系统的访问。
之所以说是 host 上文件系统是因为,这里用到了联合文件系统,container 访问的文件是映射到 host 上的。
查看 scc 发现 container 的 serviceaccount 绑定的 scc 设置了 ReadOnlyFileSystem=true。那么,应该是这里限制了文件系统只能是只读的。
修改 scc 的 ReadOnlyFileSystem 为 false:
kubectl edit scc <scc_name> -n <project>
注意绑定到该 scc 的 pod 并未生效,由于 pod 受 deployment controller 控制,这里直接 delete pod 触发重启,重启之后手动模拟自动化测试,创建文件 output.xml 成功。
一波未平,一波又起。以为搞定了,重新运行 jenkins 自动化测试发现 pull image 报错:
rpc error: code = Unknown desc = reading manifest latest in image-registry.openshift-image-registry.svc:5000...
unauthorized: authentication required
提示很明显更改了 ReadOnlyFileSystem 参数,scc 下的 serviceaccount 均有在文件系统的可读可写权限,这样的权限对于新 pull 的 image 也是适用的,那么在对 pull 的 image 进行更改时也是需要认证的,认证之后才能对 image 进行更改,这是合理的。
同时,这也解释了为什么 ReadOnlyFileSystem false 时,测试 case 可以 pull image,而不用认证。因为没有权限对 image 进行改动啊。
既然知道了原因解决起来也不难了,给 serviceaccount 添加相应的 pull image 的 role 使得 serviceaccount 可以 pull image:
oc policy add-role-to-user system:image-puller system:serviceaccount:<project>:<serviceaccount_name> -n <project>
重新运行 jenkins 测试,运行成功。