【问题标题】:Jenkins pipeline with docker: run docker as specific user (embedded postgresql带有 docker 的 Jenkins 管道:以特定用户身份运行 docker(嵌入式 postgresql
【发布时间】:2019-07-02 12:47:13
【问题描述】:

你好 Stack Overflow 社区!

我有一个需要使用 jenkins 管道构建的 maven - java 项目。 为此,我使用 docker 映像 maven:3.3.3 配置了作业。一切正常,除了我使用ru.yandex.qatools.embed:postgresql-embedded。这在本地有效,但在 jenkins 上它抱怨启动 Postgres:

2019-02-08 09:31:20.366  WARN 140 --- [ost-startStop-1] r.y.q.embed.postgresql.PostgresProcess: Possibly failed to run initdb: 

initdb: cannot be run as root

Please log in (using, e.g., "su") as the (unprivileged) user that will own the server process.

2019-02-08 09:31:40.999 ERROR 140 --- [ost-startStop-1] r.y.q.embed.postgresql.PostgresProcess: Failed to read PID file (File '/var/.../target/database/postmaster.pid' does not exist)

java.io.FileNotFoundException: File '/var/.../target/database/postmaster.pid' does not exist

显然,出于安全原因,Postgres 不允许以超级用户权限运行。

我尝试通过创建自己的 docker-image 版本并将以下内容添加到 DockerFile 中以用户身份运行:

RUN useradd myuser
USER myuser

当我从服务器的终端启动 docker 映像时,这会起作用。但是通过使用 jenkins 管道,whoami 仍然打印“root”,这表明 Jenkins 管道在方案后面使用了run -u,这会否决 DockerFile?

我的流水线工作目前就这么简单:

pipeline {
    agent {
        docker {
            image 'custom-maven:1'
        }
    }
    stages {
        stage('Checkout') {
             ...
        }
        stage('Build') {
            steps {
                sh 'whoami'
                sh 'mvn clean install'
            }
        }
    }
}

所以,我的问题是:如何以其他用户身份启动此 docker 映像?还是在运行mvn clean install之前切换用户?

更新:

通过在 jenkins 管道中添加 -u myuser 作为 args,我确实以正确的用户身份登录,但是该作业无法访问 jenkins-log 文件(希望这是唯一的问题)。用户 myuser 被添加到组 root 中,但这并没有什么不同:

agent {
    docker {
        image 'custom-maven:1'
        args '-u myuser'
    }
}

还有错误:

sh: 1: cannot create /var/.../jenkins-log.txt: Permission denied
sh: 1: cannot create /var/.../jenkins-result.txt.tmp: Permission denied
mv: cannot stat ‘/var/.../jenkins-result.txt.tmp’: No such file or directory
touch: cannot touch ‘/var/.../jenkins-log.txt’: Permission denied

【问题讨论】:

  • 为什么不尝试在 docker 中使用 root 用户而不是创建不同的用户?
  • 默认以root身份运行。但是如上所述,出于安全原因,Postgres 不允许以超级用户权限运行。嵌入式 postgres 在测试开始时自行安装,但如果在 root 下运行则无法安装。我需要一个没有 root 权限的用户
  • 同时是否有自动创建的poatgres用户?
  • 实际上我不确定,但我想有... postgresql-embedded 通过 java(在服务器启动时)(github.com/yandex-qatools/postgresql-embedded)和内部处理 postgres 服务的安装我自己的java代码,连接发生并且一切都设置好了
  • 但是你为什么要以 root 用户身份运行管道?理想情况下,它不应该以 jenkins 用户身份运行,然后您可以以 jenkins 用户身份运行 docker 映像,而不是创建其他用户,以便管道和容器具有相同的所有者:jenkins?

标签: postgresql docker jenkins jenkins-pipeline root


【解决方案1】:

我已经解决了我们案例中的问题。我所做的是sudomvn 命令之前。请记住,每个sh 步骤都有自己的shell,因此您需要在每个sh 步骤中执行sudo

sh 'sudo -u <youruser> mvn <clean or whatever> -f <path/to/pomfile.xml>'

用户必须在 Dockerfile 中创建。我创建它时没有密码,但我认为这并不重要,因为您是 root...

您必须使用sudo 而不是切换用户或其他东西,否则您需要提供密码。

这远非一种干净的方式......我建议不要乱用用户切换,除非你真的需要(比如运行嵌入式 postgres)

【讨论】:

    【解决方案2】:

    @Thomas Stubbe

    我遇到了与您上面提到的几乎相同的错误。我还有一张上面有 postgresql 的图片。在 Dockerfile 上,我创建了一个名为 tdv 的用户,并在容器上使用 id 命令检查 tdv 权限为 1000:1000。我可以通过 Jenkins 管道启动容器,但它无法执行 sh 命令,即使我为每个命令添加了 sudo -u tdv 。是否进行了其他配置?

    我的 Jenkins Pileline 脚本如下:

    pipeline{
        agent none
      stages{
        stage('did operation inside container'){
         agent {
            docker{
            image 'tdv/tdv-test:8.2'
            label 'docker_machine'
            customWorkspace "/opt/test"
            registryUrl 'https://xxxx.xxxx.com'
            registryCredentialsId '8269c5cd-321e-4fab-919e-9ddc12b557f3'
            args '-u tdv --name tdv-test -w /opt/test -v /opt/test:/opt/test:rw,z -v /opt/test@tmp:/opt/test@tmp:rw,z -p 9400:9400 -p 9401:9401 -p 9402:9402 -p 9403:9403 -p 9407:9407 -p 9303:9303 --cpus=2.000 -m=4g xxx.xxx.com/tdv/tdv-test:8.2 tdv.server'
          }
        }
           steps{
    
                   sh 'sudo tdv whoami'
                   sh 'sudo tdv pwd'
                   sh 'sudo tdv echo aaa'
    
           }
    
      }
        }
    }
    
    

    Job 运行后,我可以检查 Container 的实际启动情况。但它仍然会出现如下错误

    $ docker top f1140072d77c5bed3ce43a5ad2ab3c4be24e8c32cf095e83c3fd01a883e67c4e -eo pid,comm
    ERROR: The container started but didn't run the expected command. Please double check your ENTRYPOINT does execute the command passed as docker run argument, as required by official docker images (see https://github.com/docker-library/official-images#consistency for entrypoint consistency requirements).
    Alternatively you can force image entrypoint to be disabled by adding option `--entrypoint=''`.
    [Pipeline] {
    [Pipeline] sh
    sh: /opt/test@tmp/durable-081990da/jenkins-log.txt: Permission denied
    sh: /opt/test@tmp/durable-081990da/jenkins-result.txt.tmp: Permission denied
    touch: cannot touch ‘/opt/test@tmp/durable-081990da/jenkins-log.txt’: Permission denied
    mv: cannot stat ‘/opt/test@tmp/durable-081990da/jenkins-result.txt.tmp’: No such file or directory
    touch: cannot touch ‘/opt/test@tmp/durable-081990da/jenkins-log.txt’: Permission denied
    touch: cannot touch ‘/opt/test@tmp/durable-081990da/jenkins-log.txt’: Permission denied
    

    【讨论】:

      【解决方案3】:

      解决方案

      您目前拥有sh 'sudo tdv whoami'

      我认为您应该像这样在 sudo 之后添加 -u 标志: sh 'sudo -u tdv whoami'

      【讨论】:

        猜你喜欢
        • 2019-06-24
        • 1970-01-01
        • 2017-12-20
        • 2021-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        相关资源
        最近更新 更多