Jenkins Kubernetes插件:如何从Dockerfile构建镜像并在镜像内运行步骤
解决Jenkins Kubernetes Plugin中构建镜像后运行步骤的问题
你遇到的Expected a symbol错误,是因为docker.image('jenkins/jnlp-slave').inside()是Docker Pipeline插件的专属语法——它设计用来让Jenkins主节点或已配置Docker的代理节点直接与Docker daemon交互,但在你当前的Kubernetes Pod场景下,这个语法无法正常工作:你已经处在一个docker容器环境中,直接用Docker命令行工具操作会更适配。
快速修复:用docker run替代inside()
把Pipeline里的docker.image().inside()部分替换成直接调用docker run执行命令,因为你已经在docker容器内,完全可以通过命令行操作Docker:
pipeline { agent { kubernetes { label 'mypod' yaml ''' apiVersion: v1 kind: Pod spec: containers: - name: docker image: docker:1.11 command: ['cat'] tty: true volumeMounts: - name: dockersock mountPath: /var/run/docker.sock volumes: - name: dockersock hostPath: path: /var/run/docker.sock ''' } } stages { stage('Build Docker image') { steps { git 'https://github.com/jenkinsci/docker-jnlp-slave.git' container('docker') { sh "docker build -t jenkins/jnlp-slave ." // 替换inside()为docker run命令,--rm确保命令执行后自动清理容器 sh "docker run --rm jenkins/jnlp-slave whoami" } } } } }
更优方案:使用Kaniko替代Docker-in-Docker
挂载主机的dockersock存在安全风险(容器内的Docker可直接操作主机的Docker daemon),在Kubernetes环境中,更推荐用Kaniko完成镜像构建——它不需要依赖主机Docker daemon,完全在容器内独立完成构建:
- 先在Kubernetes集群中创建Docker仓库凭证的Secret(以Docker Hub为例),再修改Pipeline的Pod模板:
pipeline { agent { kubernetes { label 'mypod' yaml ''' apiVersion: v1 kind: Pod spec: containers: - name: kaniko image: gcr.io/kaniko-project/executor:v1.9.0 command: ['sleep'] args: ['infinity'] volumeMounts: - name: docker-config mountPath: /kaniko/.docker volumes: - name: docker-config secret: secretName: dockerhub-credentials items: - key: config.json path: config.json ''' } } stages { stage('Build Docker image') { steps { git 'https://github.com/jenkinsci/docker-jnlp-slave.git' container('kaniko') { // 用Kaniko构建并推送镜像到仓库 sh ''' /kaniko/executor \ --context `pwd` \ --dockerfile `pwd`/Dockerfile \ --destination jenkins/jnlp-slave:latest ''' } // 若需在新镜像中运行多步骤,可后续阶段用kubernetes agent拉取该镜像创建新Pod } } } }
额外说明
- Docker Pipeline插件的
inside()方法本质是让Jenkins动态创建Docker容器作为代理节点,但在Kubernetes代理模式下,Jenkins已经通过Pod管理代理,嵌套使用会导致语法和环境冲突。 - 如果需要在构建后的镜像中运行多步骤而非单条命令,还可以:
- 构建镜像后推送到仓库,后续阶段用
kubernetesagent拉取新镜像创建独立Pod。 - 在当前Pod中用
docker run -d启动后台容器,再通过docker exec执行后续步骤。
- 构建镜像后推送到仓库,后续阶段用
内容的提问来源于stack exchange,提问作者Lars Bilke
相关产品推荐
相关产品推荐

