node.js - ECS Fargate 上的 EFS 挂载 - 非 root 用户的读/写权限被拒绝
问题描述
我有一个 ECS Fargate 容器,它运行具有非 root 权限的 nodejs 应用程序,并且还安装到容器内 /.user_data 上的 EFS。
我遵循了这个AWS 教程。我的设置几乎相似。
这是 Docker 文件:
FROM node:12-buster-slim
RUN apt-get update && \
apt-get install -y build-essential \
wget \
python3 \
make \
gcc \
libc6-dev \
git
# delete old user
RUN userdel -r node
# Run as a non-root user
RUN addgroup "new_user_group" && \
useradd "new_user" --gid "new_user_group" \
--home-dir "/home/new_user"
RUN git clone https://github.com/test-app.git /home/new_user/app
RUN chown -R new_user:new_user_group /home/new_user
RUN mkdir -p /home/new_user/.user_data
RUN chown -R new_user:new_user_group /home/new_user/.user_data
RUN chmod -R 755 /home/new_user/
WORKDIR /home/new_user/app
RUN npm install
RUN npm run build
EXPOSE 1880
USER new_user
CMD [ "npm", "start" ]
当 Node 应用程序尝试在 /.user_data 内写入时,我收到读写权限被拒绝错误。
如果我以 root 身份运行容器,则应用程序能够读取/写入数据。
我尝试使用 UID 和权限向 EFS 添加访问点,但这也无济于事。
请注意:Dockerfile 在我的本地机器上运行良好。
解决方案
更新
阅读这篇博文 -将 Amazon EFS 与 Amazon ECS 和 AWS Fargate 结合使用的开发人员指南 - 第 2 部分 > POSIX 权限
可能与分配给 ECS 任务的 IAM 角色的 IAM 策略有关。
“...如果 AWS 策略不允许 ClientRootAccess 操作,您的用户将被压缩为预定义的 UID:GID,即 65534:65534。从此时起,标准 POSIX 权限适用:此用户可以做什么do 由 POSIX 文件系统权限决定。例如,由任何 UID:GID 拥有的 65534:65534 以外的文件夹拥有 666(rw 代表所有者,rw 代表所有人)将允许该保留用户创建文件。但是,由任何 UID:GID 拥有的文件夹(除 65534:65534 之外的 644(所有者为 rw,所有人为 r))将不允许此压缩用户创建文件。”
确保您的根目录权限设置为777
. 这样任何 UID 都可以读/写这个目录。
为了不那么宽松,将 root-dir 设置为755
,这是默认设置的,请参阅 docs。这提供read-write-execute
给 root 用户、read-execute
组和read-execute
所有其他用户。
如果对父目录(目录)没有读取权限,则用户 (UID) 无法访问(读取)子目录。
您可以使用Docker轻松测试它,这是一个简单的示例
创建一个Dockerfile -
FROM ubuntu:20.04
# Fetch values from ARGs that were declared at the top of this file
ARG APP_NAME
ARG APP_ARTIFACT_DIR
ARG APP_HOME_DIR="/app"
ARG APP_USER_NAME="appuser"
ARG APP_GROUP_ID="appgroup"
# Define workdir
ENV HOME="${APP_HOME_DIR}"
WORKDIR "${HOME}"
RUN apt-get update -y && apt-get install tree
# Define env vars
ENV PATH="${HOME}/.local/bin:${PATH}"
# Run as a non-root user
RUN addgroup "${APP_GROUP_ID}" && \
useradd "${APP_USER_NAME}" --gid "${APP_GROUP_ID}" --home-dir "${HOME}" && \
chown -R ${APP_USER_NAME} .
RUN mkdir -p rootdir && \
mkdir -p rootdir/subdir && \
touch rootdir/root.file rootdir/subdir/sub.file && \
chown -R root:root rootdir && \
chmod 600 rootdir rootdir/root.file && \
chmod -R 775 rootdir/subdir
您应该使用chmod 600
and chmod -R 775
,尝试不同的权限集,例如777
and 644
,看看它是否有意义。
构建镜像,运行容器,并测试权限 -
docker build boyfromnorth .
docker run --rm -it boyfromnorth bash
root@e0f043d9884c:~$ su appuser
$ ls -la
total 12
drwxr-xr-x 1 appuser root 4096 Jan 30 12:23 .
drwxr-xr-x 1 root root 4096 Jan 30 12:33 ..
drw------- 3 root root 4096 Jan 30 12:23 rootdir
$ ls rootdir
ls: cannot open directory 'rootdir': Permission denied
推荐阅读
- geoserver - 在地理服务器中找不到 imagepyramid 的 sample_image
- azure - Azure CI/CD - Azure 私有 Npm 注册表 - 无法进行身份验证,需要:Bearer authorization_uri=https://login.windows.net
- perl - 有没有办法设置 XML::LibXML->load_html(location => $url) 的连接超时
- jmeter - 我创建了一个由 10 个用户组成的步进线程组,但在运行计划后它没有显示用户数,也没有停止在 10 个用户
- popupwindow - 弹出窗口显示另一个程序正在使用此文件的错误
- html - 使第二行文本在第一行文本下对齐
- django - Django - 我正在尝试将用户对象添加到 ManyToManyField,但它不断添加所有用户对象
- amazon-web-services - Kinesis 视频流 - 多个生产者
- swift - Swift - AES base64 + md5 解密
- codenameone - 如何将多个容器绑定在一起?