Docker中无法以gitlab-runner用户运行supervisorctl命令求助
解决以gitlab-runner用户运行supervisorctl的权限问题
问题背景
我有如下Dockerfile:
FROM 2.dkr.ecr.us-east-1.amazonaws.com/pa-amazonlinux:latest # FROM amazonlinux:2 # install core packages RUN yum update -y && \ amazon-linux-extras install -y python3.8 postgresql14 nginx1 epel && \ yum install -y gcc git openldap-devel openssl-devel crontabs python38-devel mariadb-devel supervisor which tar python2-requests # install extra packages RUN yum install -y libpq-devel libaio ENV PATH "$PATH:~/.local/bin" #RUN useradd -ms /bin/bash gitlab-runner #RUN usermod -aG wheel gitlab-runner WORKDIR /app/pa # copy over our source code COPY . /app/pa/ # copy over configuration COPY nginx.conf /etc/nginx/ # create directories used by the app RUN mkdir /var/log/pa && \ mkdir /var/www && \ mkdir /var/www/pa RUN mkdir /virtualenvs RUN chown -R gitlab-runner:gitlab-runner /var/log/pa RUN chown -R gitlab-runner:gitlab-runner /var/www RUN chown -R gitlab-runner:gitlab-runner /var/www/pa RUN chown -R gitlab-runner:gitlab-runner /virtualenvs # setup virtual environment for the app RUN python3.8 -m venv /virtualenvs/pa && \ source /virtualenvs/pa/bin/activate && \ pip install -r requirements/base.txt RUN ldconfig RUN chmod u+x docker_entrypoint.sh RUN echo "NETWORKING=yes" > /etc/sysconfig/network
对应的docker_entrypoint.sh:
NAME="maestro_ecs" echo "$ENVIRONMENT" DJANGODIR=/app/platform_analytics service=ecs echo "Starting $NAME as `whoami`" tag_filter="ma-ecs-"$ENVIRONMENT # Get the list of runners with the specified tag page=1 per_page=100 printenv | grep -v "no_proxy" >> /etc/environment cd $DJANGODIR # awslogs installation echo -e "log_group_name = /ecs/ma-$ENVIRONMENT" >> awslogs.conf echo "Setting up awslogs" echo -e "Amazon Linux AMI\n$(cat /etc/issue)" > /etc/issue curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -O curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/AgentDependencies.tar.gz -O tar xvf AgentDependencies.tar.gz -C /tmp/ python ./awslogs-agent-setup.py --region us-east-1 --dependency-path /tmp/AgentDependencies -c awslogs.conf -n echo "Setting up virtual environment" source /virtualenvs/platform_analytics/bin/activate python manage.py collectstatic --noinput echo "starting gitlab-runner installation" yum install wget -y yum install jq -y echo "starting wget installation" wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64 chmod +x /usr/local/bin/gitlab-runner echo "unregister all active runners" gitlab-runner unregister --all-runners # below line of code will remove any previous zombie runners registered by dead containers offline_runners=$(curl -s --header "PRIVATE-TOKEN:${gitlab_runner_api_access_token}" "${GitlabRunnerUrl}api/v4/runners?tag_list=${tag_filter}&page=${page}&per_page=${per_page}" | jq -r '.[] | .id') # Iterate over each offline runner and remove it for runner_id in $offline_runners; do echo "Removing runner ID: ${runner_id}" curl -s --header "PRIVATE-TOKEN:${gitlab_runner_api_access_token}" --request DELETE "${GitlabRunnerUrl}api/v4/runners/${runner_id}" done chown -R gitlab-runner:gitlab-runner /etc useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash usermod -aG root gitlab-runner mkdir /opt/gitlab /usr/local/bin/gitlab-runner install --user gitlab-runner --working-directory=/opt/gitlab /usr/local/bin/gitlab-runner start /usr/local/bin/gitlab-runner register \ --non-interactive \ --url ${GitlabRunnerUrl} \ --registration-token ${GitlabRunnerTokenForService} \ --executor shell \ --name ${GitlabRunnerName} \ --docker-pull-policy always \ --locked=false \ --run-untagged=false \ --docker-privileged=true \ --limit 1 \ --tag-list ${GitlabRunnerName} /usr/local/bin/gitlab-runner restart chown gitlab-runner /opt/gitlab chmod -R 777 /opt/gitlab chmod -R 777 /app/ echo "Starting supervisord" # this is running as background process supervisord & echo "Starting nginx as foreground" nginx # echo "Forever nginx"
希望以gitlab-runner用户运行supervisorctl等命令时遭遇权限拒绝,尝试以该用户安装supervisor需要root权限,但部署阶段无法获取root权限,需要解决办法。
解决方案
1. 镜像构建阶段完成用户创建与权限配置
Docker构建阶段默认以root身份运行,可在此完成supervisor安装和权限配置,无需部署阶段处理:
修改Dockerfile,恢复gitlab-runner用户创建代码,并添加supervisor相关目录的权限调整:
ENV PATH "$PATH:~/.local/bin" # 创建gitlab-runner用户并加入wheel组 RUN useradd -ms /bin/bash gitlab-runner RUN usermod -aG wheel gitlab-runner WORKDIR /app/pa COPY . /app/pa/ COPY nginx.conf /etc/nginx/ # 创建并配置supervisor所需目录权限 RUN mkdir -p /var/log/supervisor /etc/supervisor.d /opt/gitlab/supervisor RUN chown -R gitlab-runner:gitlab-runner /var/log/supervisor /etc/supervisor.d /opt/gitlab/supervisor # 创建应用目录并调整权限 RUN mkdir /var/log/pa /var/www /var/www/pa /virtualenvs RUN chown -R gitlab-runner:gitlab-runner /var/log/pa /var/www /virtualenvs
2. 修改supervisor核心配置
编辑/etc/supervisord.conf(可在Dockerfile中替换或修改),确保所有路径和权限适配gitlab-runner用户:
[unix_http_server] file=/opt/gitlab/supervisor/supervisord.sock # 放在gitlab-runner有权限的目录 chmod=0760 chown=gitlab-runner:gitlab-runner [supervisord] logfile=/var/log/supervisor/supervisord.log pidfile=/opt/gitlab/supervisor/supervisord.pid user=gitlab-runner # 指定运行用户 nodaemon=false [supervisorctl] serverurl=unix:///opt/gitlab/supervisor/supervisord.sock # 匹配socket路径
3. 调整entrypoint脚本,以gitlab-runner启动supervisord
删除entrypoint中重复创建gitlab-runner用户的代码(已在构建阶段完成),修改supervisord启动命令,切换到gitlab-runner用户:
# 替换原supervisord启动代码 echo "Starting supervisord as gitlab-runner" su gitlab-runner -c "supervisord &"
若需更安全的用户切换,可在Dockerfile中安装gosu,然后用gosu启动:
# Dockerfile中添加 RUN yum install -y gosu
# entrypoint中替换为 echo "Starting supervisord as gitlab-runner" gosu gitlab-runner supervisord &
4. 配置supervisorctl访问权限
gitlab-runner用户可直接运行supervisorctl,若需指定socket路径,使用:
supervisorctl -s unix:///opt/gitlab/supervisor/supervisord.sock status
5. 清理entrypoint冗余代码
删除entrypoint中以下冗余代码(已在构建阶段完成):
chown -R gitlab-runner:gitlab-runner /etc useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash usermod -aG root gitlab-runner
内容的提问来源于stack exchange,提问作者Mahak Malik
相关产品推荐
相关产品推荐

