【devOps】jenkins+gitee+docker 教程(linux) 解决docker .: /bin/docker: cannot execute binary file

前置声明 我的是4G服务器 部了个rocketmq集群 一个mariadb 一个jenkins 一个docker, jenkins就时不时要崩一下。即使服务器只用来部署jenkins+docker ,估计 2G服务器也够呛 所以注意自己服务器配置,如果低内存仍要尝试的话,在部署不起来的时候,排查问题时务必注意是因为操作失误还是硬件配置问题

jenkins安装

jenkins安装教程

安装好后 会提示创建第一个用户

docker安装

同样的 因为内容比较多 单独一篇文章
docker安装教程

jenkins 配置gitee

注意:除了jenkins和docker , linux上面还需要安装git、maven
以 centos为例 : yum install git ,yum install maven

  1. jenkins安装gitee插件

在这里插入图片描述
在这里插入图片描述
顺便把 SSH Pipeline Steps插件安装一下
在这里插入图片描述

  1. 配置gitee账号密码
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 新建一个流水线项目
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
Jenkinsfile_dev是jenkinsfile的文件名 默认取当前路径 (就是项目的根目录)

  1. 接下来就是编写jenkinsfile了 这也是最核心的部分,这里贴出一份比较简单的脚步
def getHost(){
    
    
    def remote = [:]
    remote.name = 'aliyun'
    remote.host = 'xx.xxx.xxx你的主机地址'
    remote.user = '你用来登陆linux的账号'
    remote.port = 22  
    remote.password = '密码'
    remote.allowAnyHosts = true
    return remote
}
pipeline {
    
    
    agent any
    environment {
    
    
        server=""
        ACTIVE_PROFILE="dev"     // 当前环境
        BRANCH_NAME="master"    // 代码分支名称
        HOST_EXPOSE_PORT=8586        // docker对外端口
        CONTAINER_EXPOSE_PORT=8585   // 项目端口

        JAR_NAME="springboot-core-1.0.0.jar"   //jar包名
        JAR_OTHER_NAME="springboot.jar" // jar包别名
        GIT_USERNAME="gitee账号"
        GIT_PASSWORD="gitee密码"
        GIT_ADDR="https://${GIT_USERNAME}:${GIT_PASSWORD}@gitee.com:xxx/xxx.git"  //项目地址
        JOB_NAME="springboot"
        JENKINS_WORKSPACE="/root/.jenkins/workspace"    // jenkins存放文件的地址
        PROJECT_NAME="springboot-core"   // 项目名称
        CONTAINER_NAME="${JOB_NAME}"                // 容器名称
        IMAGE_NAME="${JOB_NAME}"                    // 镜像名
        IMAGE_TAG="v1.0.0"                          // 镜像版本号
        APP_SERVER_JOB_PATH="/var/lib/jenkins/workspace/${JOB_NAME}" // 应用服务器工程项目根目录
        APP_SERVER_PROJECT_PATH="${APP_SERVER_JOB_PATH}/${PROJECT_NAME}/target" // 项目目录绝对路径

    }
    stages {
    
    
        stage('InitContainerServer'){
    
    
            steps {
    
    
                script {
    
    
                    server = getHost()
                }
            }
        }
        stage("Checkout") {
    
    
            steps {
    
    
                echo "从Git下载项目源码"
                script {
    
    
                    ssh remote: server, command: """
                    if test -e ${APP_SERVER_JOB_PATH};then
                        rm -rf ${APP_SERVER_JOB_PATH}
                        whoami
                        git clone -b ${BRANCH_NAME} ${GIT_ADDR} ${APP_SERVER_JOB_PATH}
                    else
                        git clone -b ${BRANCH_NAME} ${GIT_ADDR} ${APP_SERVER_JOB_PATH}
                    fi
                    """
                }
            }
        }
                stage("Build") {
    
    
            steps {
    
    
                echo "开始maven编译构建"
                sh 'whoami'
                sh 'pwd'
                sh "mvn  clean package -P ${ACTIVE_PROFILE} -U -Dmaven.test.skip=true"
                sh "mv -f ${APP_SERVER_PROJECT_PATH}/${JAR_NAME}  ${APP_SERVER_JOB_PATH}"
                echo "maven构建成功..."

            }
        }


        // 注意点1: jenkins需要安装SSH Pipeline Steps 插件 用于sshCommand 命令 并可以在控制台看到脚本内容做了什么
        // 不安装的话 sshCommand替换成ssh 也是可以执行的 但是很多时候看不到脚本里面做了什么
        // 注意点2 $()和``是一个含义  ``是shell通用  $()有的不支持 但可读性更强
        // 注意点3 """ 见到$ 就会当成一个变量 但是下面有$()/``  所以需要替换成'''
        // 注意点4 awk因为里面有$1存在 所以同样的需要单引号 ''

        stage("CleanContainer") {
            steps {
                echo "清理旧容器中..."
                sh '''docker stop `docker container ls -a|grep -w ${JAR_NAME}|awk '{print $1}'` ||true'''
                sh '''docker stop `docker container ls -a|grep -w ${HOST_EXPOSE_PORT}|awk '{print $1}'` ||true'''
                sh 'sleep 3s'
                sh '''docker rm -f `docker container ls -a|grep -w  ${JAR_NAME}|awk '{print $1}'` ||true'''
                sh '''docker rm -f `docker container ls -a|grep -w  ${HOST_EXPOSE_PORT}|awk '{print $1}'` ||true'''

                sh 'docker rmi -f ${JAR_NAME}||true'

                echo "清理旧容器成功 开始构建docker"

            }
        }

        stage("Deploy") {
            steps {

                sh  """
                        pwd
                        whoami
                        docker build -t  ${
    
    JAR_NAME} .
                        echo "构建docker成功..."
                    """

                echo "开始部署"
                sh 'docker run -d -p ${HOST_EXPOSE_PORT}:${CONTAINER_EXPOSE_PORT} -t ${JAR_NAME} >output 2>&1'

                echo "部署完毕"
            }
        }
        stage("Clean") {
            steps {
                echo "清理工作"
            }
        }
    }
    post {
        always {
            echo "工作流执行完毕"
        }
        failure {
            echo "工作流执行失败! :("
        }
        success {
            echo "工作流执行成功! ^o^"
        }
    }
}

语法就是上面这样了 也可以再自定义一些其它的。 全文的难点就是移除docker的语法了 ,不明白到底是linux版本问题还是jenkins问题 导致shell各种出错 试过很多其它人的写法 无一成功的 (我的linux是alibaba cloud linux 理论是等同于centos的), 最后自己想了两天 用这种写法完成了 。

  1. dockerFile的编写
# Docker image for springboot file run
# VERSION 0.0.1
# Author: qkj
# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER qkj <1005738053@qq.com>
# 路径
WORKDIR /var/lib/jenkins/workspace/springboot
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为springboot.jar
ADD springboot-core-1.0.0.jar /springboot.jar
# 运行jar包
RUN bash -c 'touch /springboot.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/springboot.jar"]

  1. 回到jenkins控制台构建

报错排查.: /bin/docker: cannot execute binary file

在写两个file部署过程中(上面两个file是正确的,这里以回忆的角度叙述), jenkins控制台遇到了.: /bin/docker: cannot execute binary file 排查过程是这样的:

  1. 首先jenkins_user已经设置为root了(在安装jenkins博客有提及),那就不应该是权限问题,可以看到jenkinsfile中也有whoami 命令(whoami是输出 当前登录账号),也确实是root
  2. 于是不通过jenkins控制台 直接在linux机器部署docker 先是部署成功, 后面又失败了(对 就是莫名其妙失败的),找到了stackoverflow的一个回答
    在这里插入图片描述

https://stackoverflow.com/questions/57892651/error-invalid-or-corrupt-jarfile-app-jar/58170124
本来是不相信的 因为加不加斜杠 之前测试都是可以的, 但是别人这么说了 可能是真的遇到过这种情况 抱着试试看的态度加上去了
在这里插入图片描述
加上去之后 本地是可以了 没再出现失败的情况,但是jenkins控制台还是报错。

  1. 索性将jenkins文件夹 chmod 777 (读写执行全开放命令 在我置顶博客也有提及用法) 依然报错
  2. 仔细观察发现jenkins控制台命令输出 在 docker run xxxxx 前面 自动加了一个 . ,
    变成了 . docker run xxxxx ,一开始我的写法是这样的 ,把docker run放在sh “”" “”"代码块里面 不知道为什么会自动加上 .
      stage("Deploy") {
    
    
            steps {
    
    
                echo "开始部署"
                sh  """
                        pwd
                        whoami
                        docker build -t  ${JAR_NAME} .
                        echo "build成功 开始运行"
                        docker run  -p ${HOST_EXPOSE_PORT}:${CONTAINER_EXPOSE_PORT} -t ${JAR_NAME}
                    """
               

                echo "部署完毕"
            }
        }

把它单独提出来之后 就解决了这个问题

      stage("Deploy") {
    
    
            steps {
    
    
                echo "开始部署"
                sh  """
                        pwd
                        whoami
                        docker build -t  ${JAR_NAME} .
                        echo "build成功 开始运行"
                    """
                 sh 'docker run  -p ${HOST_EXPOSE_PORT}:${CONTAINER_EXPOSE_PORT} -t ${JAR_NAME}'

                echo "部署完毕"
            }
        }

出现docker .: /bin/docker: cannot execute binary file问题总结:

1.权限问题(可能是账户权限 也可能是文件夹读写执行权限)
2.ADD aaa.jar  /bbb.jar 或 COPY aaa.jar  /bbb.jar重命名时 还是加上斜杠好 某些未知情况下 可能会有bug 
3.命令前面多了一个 . 

猜你喜欢

转载自blog.csdn.net/qq_36268103/article/details/122083018