我正在docker镜像中运行initdb(官方 Postgres 镜像) 在 Openshift 环境中,设置了严格的安全策略,运行容器的用户将具有随机 UID,但 GID 将为 0,因此我可以断言该进程拥有所有必要的权限。
我已经使用 GID 更改为 0 的 postgres 用户测试了我的容器,一切正常。使用 ANYUID 策略的最终测试导致映像失败:
initdb:无法更改目录的权限
这很清楚:用户对目录具有完全的写入权限,但既不是所有者也不是 root。但是,我不明白为什么 initdb 需要更改目录的所有权,写入权限应该足够了。
必须initdb
在启动容器后调用,因为 pgdata 可能位于卷上,并且 anyuid 策略断言常规集群安全性,所以我不想禁用它。我知道通常可以使用该策略运行 Postgres docker 镜像,因为 RedHat 为此提供了修改后的镜像,但它们只能在 OpenShift Enterprise 中使用。
如何允许initdb
进程以任何具有必要写入权限但既不是所有者也不是 root 的用户身份运行?是否需要使用特殊标志重新编译源代码?我发现 RedHat 使用的是 Postgres 的自定义打包版本,但我不知道他们是否修改了源代码...
答案1
这个问题似乎没有直接的解决方案。查看替代的 PostgreSQL 镜像(即来自软件合集和Crunchydata),最有希望的解决方案不是预先创建 pgdata 目录,而是在运行时创建,当随机 UID 已知时。
Crunchydata 的 Docker 镜像pgdata
确保父目录存在且具有足够的权限,以便随机用户可以在其中创建具有随机名称的子目录在运行时。然后该子目录将被用作,pgdata
并且由于随机用户刚刚创建了它,它将以他作为其所有者,这将令人高兴pginit
。
结论:官方 Docker 镜像似乎与 OpenShift 不兼容。使用 Crunchydata 的镜像(例如crunchydata/crunchy-postgres
)代替官方镜像,并将卷安装为pgdata
的父目录,如其所述例子对我有用。
apiVersion: apps/v1
kind: Deployment
...
spec:
...
template:
...
spec:
...
volumes:
- name: pgdata
emptyDir: {}
- name: backup
emptyDir: {}
containers:
- name: postgres
image: "crunchydata/crunchy-postgres-gis:centos7-12.5-3.0-4.4.2"
volumeMounts:
- mountPath: "/pgdata"
name: pgdata
readOnly: false
- mountPath: "/backup"
name: backup
readOnly: true
...
/pgdata/pg-test-postgres-d9ff78d5-fb6hk
在运行时提供目录pgdata
:
INFO: Running initdb command: initdb -D /pgdata/pg-test-postgres-d9ff78d5-fb6hk --data-checksums > /tmp/initdb.stdout 2> /tmp/initdb.stderr
希望这可以帮助。