在 Jenkins Pipeline 中访问本地运行的容器

Posted

技术标签:

【中文标题】在 Jenkins Pipeline 中访问本地运行的容器【英文标题】:Accessing locally running containers within Jenkins Pipeline 【发布时间】:2021-03-12 20:10:28 【问题描述】:

我正在尝试使用 Docker 来运行 Jenkins 和 Sonarqube。然后在 Jenkins 中,我想使用管道设置一个作业来构建和测试应用程序,然后使用 sonarscan 运行扫描。

我的问题似乎与网络有关,因为在 Jenkins 管道中,我无法通过 dns 名称访问 SonarQube 容器 IP。当我手动找到该容器的内部 IP 并将其放入 Jenkinsfile 时,我没有任何问题。

这是我用来启动所有容器的 docker 命令(由于 WSL 问题,我没有移至 docker-compose)。

docker network create jenkins

docker run --name jenkins-docker --rm --detach \
  --privileged --network jenkins --network-alias docker \
  --env DOCKER_TLS_CERTDIR=/certs \
  --volume jenkins-docker-certs:/certs/client \
  --volume jenkins-data:/var/jenkins_home \
  --publish 3000:3000 \
  --publish 2376:2376 docker:dind

docker build -t myjenkins-blueocean:1.1 .

docker run --name jenkins-blueocean --rm --detach \
  --network jenkins --env DOCKER_HOST=tcp://docker:2376 \
  --env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 \
  --publish 8080:8080 --publish 50000:50000 \
  --volume jenkins-data:/var/jenkins_home \
  --volume jenkins-docker-certs:/certs/client:ro \
  --volume "$HOME":/home \
  myjenkins-blueocean:1.1

docker run --name db --rm --detach \
  --network jenkins \
  --env POSTGRES_USER=sonar \
  --env POSTGRES_PASSWORD=sonar \
  --volume postgresql:/var/lib/postgresql \
  --volume postgresql_data:/var/lib/postgresql/data \
  postgres

docker run --name sonarqube --rm --detach \
  --network jenkins \
  --link jenkins-blueocean \
  --env sonar.jdbc.username=sonar \
  --env sonar.jdbc.password=sonar \
  --env sonar.jdbc.url=jdbc:postgresql://db:5432/sonar \
  --publish 9000:9000 \
  --volume sonarqube_conf:/opt/sonarqube/conf \
  --volume sonarqube_data:/opt/sonarqube/data \
  --volume sonarqube_extensions:/opt/sonarqube/extensions \
  --volume sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins \
  sonarqube:7.6-community

这是我在管道中使用的 Jenkinsfile。 管道 无代理

stages 
    stage('Build')  
        agent  
            docker     
                image 'maven:3-alpine'  
                args '-v /root/.m2:/root/.m2 -v /var/run/docker.sock:/var/run/docker.sock'  
               
        
        steps 
            sh 'mvn -B -DskipTests clean package' 
        
    
    
    stage('Test') 
        agent  
            docker     
                image 'maven:3-alpine'  
                args '-v /root/.m2:/root/.m2 -v /var/run/docker.sock:/var/run/docker.sock'  
               
        
        steps 
            sh 'mvn test'
        
    
    
    stage('Analyze') 
        agent 
            docker 
                image 'sonarsource/sonar-scanner-cli'
                args '-v /var/run/docker.sock:/var/run/docker.sock --entrypoint=""'
            
        
        steps 
            sh 'sonar-scanner -Dsonar.source=. -Dsonar.projectKey=com.mycompany.app:my-app -Dsonar.host.url=http://sonarqube:9000 -Dsonar.login=admin -Dsonar.password=admin'
        
    
 

Is there a way to force Jenkins to work with the bridge network I've created?

【问题讨论】:

你可以尝试不使用 --link 并让 --network 到 sonarqube 容器吗? 不走运,我仍然收到相同的错误响应“错误:SonarQube 服务器 [sonarqube:9000] 无法访问” 您的声纳可能没有启动。你能用 docker logs sonarqube 检查它吗?您应该看到: 2020.11.30 22:07:26 INFO app[][o.s.a.SchedulerImpl] Process[ce] 已启动 2020.11.30 22:07:26 INFO app[][o.s.a.SchedulerImpl] SonarQube 已启动 排除网络问题的另一项检查是使用 telnet 容器,例如: docker run -it --network jenkins mikesplain/telnet sonarqube 9000 如果它已连接,那么您的 sonarqube 已启动,您可以从你的詹金斯网访问它 sonarqube 容器日志看起来不错。我无法让 mikeplain/telnet 工作,我收到与过时的 shcema1 清单格式相关的错误。我能够成功运行“docker exec -it jenkins-blueocean ping sonarqube”并得到了很好的响应。我不确定这是否等效。 【参考方案1】:

为了后代,这就是我解决这个问题的方法。我的主要问题是将 docker 中的 docker 与让 Jenkins 容器访问 docker 混淆。这篇 https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/ 的文章详细介绍了为什么 docker 中的 docker 可能不是一个好主意。我遇到的具体问题是内部 docker 实例无权访问外部 docker 实例。

所以我采取的步骤:

    在 Jenkins Dockerfile 中下载 docker 与 Jenkins 容器的 docker 套接字共享主机 docker 套接字 在主机上创建一个 Jenkins 用户 将 jenkins 用户添加到 docker 组 在 Jenkins Dockerfile 中手动将容器的 Jenkins 用户设置为 相同的用户 ID 和组 ID 以及主机上的 Jenkins 用户。还要确保 将容器 jenkins 用户添加到 docker 组,并将 docker 组 id 更改为 匹配主机的 您现在应该可以运行容器了,请确保使用您可以使用的卷 授予主机上 jenkins 用户和 docker 组的访问权限

【讨论】:

以上是关于在 Jenkins Pipeline 中访问本地运行的容器的主要内容,如果未能解决你的问题,请参考以下文章

49-Jenkins-本地进行Pipeline语法检查

多模块本地 jar 依赖项 - Jenkins Pipeline

gitlab+jenkins+maven+docker持续集成——.Jenkins Pipeline持续集成

jenkins pipeline job实战

Jenkins集群下的pipeline实战

让Jenkins执行GitHub上的pipeline脚本