问题描述
正在使用官方的jenkins:lts
镜像来托管Jenkins实例,并将Docker控制套接字转发到容器内部,以允许Jenkins启动新的容器。现在,他正在尝试运行一个以docker
代理开始的流水线。
运行此作业会尝试在Jenkins容器内部执行docker
命令,但由于未安装该软件包,因此无法正常工作。常规的Docker插件可以正常工作,因为它直接使用控制套接字而不是尝试运行外部程序。
用户怀疑自己不是第一个遇到这个问题的人,他想知道如何在容器内部设置一个可以执行带有“docker”代理的流水线的Jenkins实例。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
要在Jenkins容器内部执行带有docker
代理的流水线,需要扩展jenkins/jenkins:lts
镜像以安装Docker客户端。
以下是一个Dockerfile示例,可以在jenkins/jenkins:lts
镜像的基础上安装Docker客户端:
FROM jenkins/jenkins:lts
# 切换到root用户
USER root
# 定义Docker版本和Docker组ID
ENV DOCKER_VERSION docker-18.06.3-ce
ARG DOCKER_GID=993
# 下载并安装Docker客户端
RUN wget --quiet -O- \
https://download.docker.com/linux/static/stable/x86_64/${DOCKER_VERSION}.tgz | \
tar zx --strip-components=1 -C /usr/local/bin docker/docker \
&& groupadd -g ${DOCKER_GID} docker \
&& usermod -aG docker jenkins
# 切换回jenkins用户
USER jenkins
通过使用上述Dockerfile构建一个新的镜像,你可以在Jenkins容器内部安装Docker客户端。然后,你就可以声明带有docker
代理的流水线了。
方案2
使用
sh
步骤运行docker
命令可能会失败,因为jenkins/jenkins:lts
和jenkins/jenkins:latest
镜像没有docker
命令行应用程序。
另一种方法是使用脚本来控制容器的运行。你可以在sh
步骤中使用docker build
和docker run
命令来手动构建和运行容器。
以下是一个示例脚本,可以在Jenkins容器内部构建和运行一个简单的Flask应用程序容器:
stage('Deploy') {
steps {
sh 'docker build -t flask-sample:latest .'
sh 'docker run -d --rm --name hello_app_flask -p 4010:4000 flask-sample:latest'
}
}
在上面的示例中,我们使用docker build
命令构建一个名为flask-sample
的镜像,并将其标记为latest
版本。然后,使用docker run
命令在容器内部运行该镜像,并将容器命名为hello_app_flask
,并将容器的端口4000
映射到主机的端口4010
。
方案3
你可以使用
docker-compose
和Dockerfile
来设置Jenkins容器,并将Docker命令运行起来。
以下是一个使用docker-compose
和Dockerfile
的示例配置:
version: "3.7"
services:
jenkins:
build:
context: .
dockerfile: Dockerfile
image: jenkins
container_name: jenkins
restart: always
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "/etc/sysconfig/docker:/etc/sysconfig/docker"
- "/home/ubuntu/jenkins/volume:/var/jenkins_home"
ports:
- "8443:8080"
privileged: true
在上面的示例中,我们定义了一个名为jenkins
的服务,使用Dockerfile
构建镜像,并将其命名为jenkins
。我们将容器的端口8080
映射到主机的端口8443
,并将/var/run/docker.sock
、/etc/sysconfig/docker
和/home/ubuntu/jenkins/volume
目录挂载到容器内部。
请注意,为了在容器内部运行Docker命令,我们将privileged
属性设置为true
,这将允许容器拥有特权访问。
以上是几种在Jenkins容器内部使用Docker代理的解决方案。你可以根据自己的需求选择适合的方法。