shell jenkins with docker build pipeline fail - Permission denied

e0bqpujr  于 2023-10-23  发布在  Shell
关注(0)|答案(1)|浏览(130)

我用Docker运行Jenkins,当我开始构建管道时,我得到了这个错误:

sh: /var/jenkins_home/workspace/fake_message_main@2@tmp/durable-ac93e82e/jenkins-log.txt: Permission denied
sh: /var/jenkins_home/workspace/fake_message_main@2@tmp/durable-ac93e82e/jenkins-result.txt.tmp: Permission denied
touch: cannot touch '/var/jenkins_home/workspace/fake_message_main@2@tmp/durable-ac93e82e/jenkins-log.txt': Permission denied
mv: cannot stat '/var/jenkins_home/workspace/fake_message_main@2@tmp/durable-ac93e82e/jenkins-result.txt.tmp': No such file or directory
touch: cannot touch '/var/jenkins_home/workspace/fake_message_main@2@tmp/durable-ac93e82e/jenkins-log.txt': Permission denied
touch: cannot touch '/var/jenkins_home/workspace/fake_message_main@2@tmp/durable-ac93e82e/jenkins-log.txt': Permission denied
touch: cannot touch '/var/jenkins_home/workspace/fake_message_main@2@tmp/durable-ac93e82e/jenkins-log.txt': Permission denied
touch: cannot touch '/var/jenkins_home/workspace/fake_message_main@2@tmp/durable-ac93e82e/jenkins-log.txt': Permission denied

这是我的Jenkinsfile:

pipeline {
        agent any 
        
        stages {
            stage('Check Docker') {
                steps {
                    echo 'checking if docker exists...'
                    sh 'docker --version'
                }
            }
            stage ('Test'){
                parallel {
                    stage ('Test Rocky 8.1') {
                        agent {
                            docker {
                                image 'localhost:5000/centos7:latest'
                                args '-u jenkins:jenkins'
                            }
                        }
                        steps {
                            script {
                                echo env.WORKSPACE
                                echo 'Building Rpm...'
                                sh 'python3 --version'
                            }
                        }
                    }
                }
            }
            stage ('Build'){
                parallel {
                    stage ('Test Rocky 8.1') {
                        agent {
                            docker {
                                image 'localhost:5000/centos7:latest'
                                args '-u root:root'
                            }
                        }
                        steps {
                            echo 'Building Rpm...'
                            sh 'python3 --version'
                        }
                        post {
                            always {
                                cleanWs()
                            }
                        }
                    }
                }
            }
            stage("deploy") {
                steps {
                    echo 'Hello World'
                    echo "deploying the aplication... wooooow!!!"
                }
            }
        }
    }

这就是我如何使用Docker运行Jenkins:

docker run -u 0 \
  --privileged --rm \
  --name jenkins -d \
  -p 8080:8080 -p 50000:50000 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(which docker):/usr/bin/docker \
  -v jenkins_home:/var/jenkins_home \
  -e JAVA_OPTS="-Dorg.jenkinsci.plugins.durabletask.BourneShellScript.LAUNCH_DIAGNOSTICS=true" \
  jenkins/jenkins:latest

如果我用args -u root:root替换args -u jenkins:jenkins,或者如果我进入运行jenkins容器的shell并快速将所有权更改为jenkins,在构建开始之前给予/var/jenkins_home/workspace/fake_message_main@2@tmp/的完全权限,一切都可以正常工作。我尝试了这些解决方案,但没有工作,一些在Jenkins论坛。感谢您的帮助!
编辑后,这是我如何构建centos7容器:

FROM centos:centos7
ADD files/tmp /tmp
RUN rpm --import /tmp/*.pub
RUN yum clean all
RUN yum -y install openssh-clients
RUN yum -y install \
    epel-release
RUN yum makecache && yum -y install \
    python27 \
    python-pip \
    python-requests \
    python2-mock \
    python34-devel \
    python34-mock \
    rpmdevtools  \
    rpmlint \
    rpm-build \
    python-devel \
    python2-devel \
    python2-setuptools \
    python34-setuptools \
    python36-devel \
    python36-setuptools \
    which \
    perl-devel \
    perl-ExtUtils-MakeMaker
RUN yum -y install \
    gcc \
    zlib zlib-devel lzma xz-devel \
    openssl-devel ncurses-devel bzip2-devel \
    readline-devel libffi-devel sqlite-devel
RUN yum -y group install "Development Tools"

RUN groupadd -g 1000 jenkins && \
    useradd -m jenkins -u 1000 -g 1000

ADD files/etc/rpm-repo.conf /root/scripts/rpm-repo.conf
ADD files/scripts/scp-upload.sh /root/scripts/scp-upload.sh
ADD files/scripts/pyenv.sh /home/jenkins/
ADD files/etc/argo.repo /etc/yum.repos.d
RUN pip install httmock coverage=='4.5.4' unittest2 discover
RUN pip install -U "pip==20.*" "setuptools<45.0.0" && pip install pipenv
RUN pip3 install -U pip setuptools
RUN pip3 install mock httmock tox tox-pyenv requests pytest coverage unittest-xml-reporting aiofiles lxml unidecode
RUN yum install -y python3-aiohttp python3-bonsai python3-avro
COPY files/build-rpm.sh /home/jenkins/build-rpm.sh
USER jenkins
WORKDIR /home/jenkins
RUN curl https://pyenv.run | bash
RUN mv $HOME/.pyenv $HOME/pyenv
RUN source $HOME/pyenv.sh && pyenv install --list | grep ' 3.7' | tail -n1 | xargs pyenv install
RUN source $HOME/pyenv.sh && pyenv install --list | grep ' 3.8' | tail -n1 | xargs pyenv install
RUN source $HOME/pyenv.sh && pyenv install --list | grep ' 3.9' | tail -n1 | xargs pyenv install
RUN source $HOME/pyenv.sh && pyenv install --list | grep 'mambaforge' | tail -n1 | xargs pyenv install
RUN source $HOME/pyenv.sh && pyenv local $(pyenv versions | grep 'mambaforge' | head -n1)
RUN source $HOME/pyenv.sh && mamba create -y -n ams-py310 python=3.10
RUN source $HOME/pyenv.sh && pyenv local system
RUN rm $HOME/.python-version
USER root
WORKDIR /root
RUN su - jenkins rpmdev-setuptree
t40tm48m

t40tm48m1#

根本原因是您通过选项-v jenkins_home:/var/jenkins_home将主机目录jenkins_home挂载到容器。
当用户jenkins访问容器内的/var/jenkins_home时,实际上是访问主机上的jenkins_home
主机目录jenkins_home的所有者不是您通过Dockerfile为容器创建的用户jenkins。因此,访问被拒绝。

**重要提示:**即使您在主机和容器上有同名的用户或组,但如果两者的ID不相同,操作系统也不会认为两者相同。

有三种方法可以解决您的问题:
1.将主机用户和组装载到容器

  • 通过选项-v /etc/passwd:/etc/passwd-v /etc/group:/etc/group运行容器,它会导致主机目录jenkins_home的所有者可以在容器中找到,
  • 运行container的所有者是主机目录jenkins_home,你可以在这里使用用户名或用户名。-u <user name or id of host directory "jenkins_home">

1.将主机目录jenkins_home所有者更改为1000:1000(由容器的Dockerfile创建的用户jenkins的用户和组ID),然后您可以使用选项-u 1000:1000运行容器,但-u jenkins:jenkins(操作系统通过主机和容器之间的ID匹配用户和组,而不是通过名称)
1.使用主机目录jenkins_home的所有者的用户和组ID在Dockerfile中创建用户jenkins,然后使用主机目录jenkins_home的所有者运行容器。

ARG JENKINS_HOME_USER_ID
ARG JENKINS_HOME_GROUP_ID

RUN groupadd -g $JENKINS_HOME_GROUP_ID jenkins && \
    useradd -m jenkins -u $JENKINS_HOME_USER_ID -g $JENKINS_HOME_GROUP_ID

这3种方法的核心是使主机目录jenkins_home的所有者成为容器内现有的有效用户。

相关问题