使用Docker+Jenkins实现Go语言项目的持续集成

这篇文章将介绍如何使用Docker+Jenkins实现Go语言项目的持续集成。git

首先讲一下大体的实现思路:golang

推送代码至Git服务器 => 触发Jenkins服务器配置的Git Web Hooks => 从Git服务器中pull或clone代码 => 将代码编译成二进制可执行文件 => 构建docker镜像 => 上传docker镜像至镜像仓库 => 从Jenkins服务器进入远程应用服务器 => 从docker镜像仓库中拉取镜像 => 中止并删除该项目正在运行的docker容器 => 使用该新镜像构建并启动docker容器 => 删除其余旧版本镜像 => 完成web

而后讲一下实践过程当中用到的一些技术点:docker

  • Dockershell

    使用Docker的主要缘由主要有,应用移植方便,而且可有效解决同一应用在不一样服务器上部署带来的环境问题影响。json

  • Docker Composevim

    docker-compose也是由Docker提供的一个命令行工具,这里主要用于简化Jenkins服务器上对容器的操做,仅此而已,可直接使用shell脚本代替。浏览器

  • Jenkinsbash

    Jenkins是一个自动化服务器,也能够做为简单的CI/CD服务器。服务器

  • Git

    Git想必你们都不会陌生,这里一样使用它做为项目的代码管理仓库,而且利用它的Web Hooks,做为Jenkins任务构建的触发器。

  • 镜像仓库

    这里选择阿里云提供的容器服务做为咱们的镜像仓库,可自行选择本身合适的镜像仓库。

在本文的最后,列出了实践过程当中可能会出现的问题,而且提供了实践使用的Go项目代码仓库。

安装 Jenkins

启动 Jenkins 容器

  1. 拉取 Jenkins 镜像

    docker pull jenkins/jenkins:latest
    复制代码
  2. 编写 docker-compose.yml 文件

    version: "2"
    services:
    	jks:
    		image: jenkins/jenkins:latest
    		ports:
    			- 8080:8080
    			- 50000:50000
    		volumes:
    			- /data/jenkins:/var/jenkins_home
    			- /var/run/docker.sock:/var/run/docker.sock
    			- /bin/docker:/bin/docker
    		container_name: jks
    		user: root
    复制代码
  3. 建立用于挂载的 /data/jenkins 文件夹, 并修改该文件夹的拥有者为 ID=1000 的用户

    mkdir -p /data/jenkins
    chown -R 1000:1000 /data/jenkins
    复制代码
  4. 经过 docker-compose 启动 jenkins 容器

    docker-compose -f /data/compose/docker-compose.yml up -d jks
    复制代码

安装 Jenkins 插件

  1. 在浏览器输入 http://IP:8080 进入 Jenkins 管理页面

  2. 经过命令 cat /data/jenkins/secrets/initialAdminPassword 获取初始密码,对 Jenkins 进行解锁,解锁后先跳过插件安装(无需担忧漏装推荐的插件,在后续安装插件过程当中,会自动安装解锁后推荐的全部插件)

  3. (可选)修改配置文件,并重启 Jenkins 容器,实现插件安装加速

    # 编辑jenkins配置文件
    vim /data/jenkins/updates/default.json
     # 执行ex命令, 替换全部插件下载URL
    :1,$s/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g
     # 执行ex命令, 替换链接测试URL
    :1,$s/http:\/\/www.google.com/https:\/\/www.baidu.com/g
     # 重启jenkins容器
    docker-compose -f /data/compose/docker-compose.yml restart jks
    复制代码
  4. 进入Jenkins -> Plugin Manager页面安装如下插件

    • Localization: Chinese (Simplified)
    • Publish Over SSH
    • Gitee
    • Go

配置 Jenkins

全局工具配置

进入Jenkins -> 系统管理 -> 全局工具配置页面,对GitGo进行相关配置

Gitee 配置

在已安装 Gitee 插件的前提下,进入Jenkins -> 系统管理 -> 系统配置,找到Gitee 配置,对其进行配置,配置后内容大体以下:

配置 Publish over SSH

在已安装Publish over SSH 插件的前提下,进入Jenkins -> 系统管理 -> 系统配置,找到Publish over SSH配置,以下图所示:

Passphrase:生成密钥时使用的加密口令,为空则表示无

Path to key:生成的私钥位置,与Key选项只需填其中一个

Key:生成的私钥内容,与Path to key选项只需填其中一个

Name:远程服务器备注名(自定义)

Hostname:远程服务器地址

Username:远程服务器用户名

Remote Directory:进入远程服务器后所在的位置

主要有两种配置方式,第一种是直接使用远程服务器的帐号和密码,另一种则是经过密钥的方式。

  • 帐号密码方式

    使用帐号密码方式无需配置公私钥相关的选项,直接对SSH Server内容进行配置,并点击高级按钮,勾选Use password authentication, or use a different key选项,并填写远程服务器用户对应的密码Passphrase / Password,完成后点击下方的Test Configuration按钮进行链接测试便可。

  • 密钥方式

    1. 进入 Jenkins 容器

      docker exec -it jks /bin/bash
      复制代码
    2. 生成密钥

      ssh-keygen -t rsa
      复制代码
    3. 将公钥复制到远程服务器

      ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.56.101
      复制代码
    4. 配置Path to key 选项值为/root/.ssh/id_rsa

    5. 配置SSH Server

    6. 链接测试

构建任务

  1. 点击Jenkins -> 新建任务,建立一个 Jenkins 任务

  2. General

    填写项目的Gitee 连接以及勾选丢弃旧的构建

  3. 源码管理

    选择Git选项,填写Repositories信息,并建立Gitee 帐号密码凭据

  4. 构建触发器

    勾选Gitee webhook 触发构建,根据需求选择容许触发构建的分支,并在下方的Gitee WebHook 密码选项右边,点击生成按钮,将该触发器的WebHook URLWebHook 密码填写至该项目的Gitee WebHooks管理中。

  5. 构建环境

    在已安装Go 插件的前提下,勾选Set up Go programming language tools选项框,并在其下方填写项目使用到的 Go 版本号便可,以下图:

  6. 构建

    构建过程大体能够分为以下步骤:

    • 判断是否存在项目本地仓库
      • 存在:进入该本地仓库文件夹,经过git pull命令从Git远程仓库拉取最新代码
      • 不存在:直接使用git clone命令从Git远程仓库克隆项目,并进入该项目文件夹
    • 使用go build命令编译成二进制可执行文件
    • 执行事先写好的docker-push脚本,编译docker镜像并上传至docker仓库

    if [ ! -d "/var/go-docker-demo" ];then
    	cd /var
        git clone https://hkail:xxxxxxxxx@gitee.com/hkail/go-docker-demo
        cd go-docker-demo
    else
    	cd /var/go-docker-demo
        git pull
    fi
    
    go build -o app
    
    chmod +x docker-push && ./docker-push
    复制代码

    Dockerfile文件内容以下:

    FROM golang:1.14.2
    
    COPY app . COPY conf/conf.toml ./conf/ 
    ENTRYPOINT ["./app"] 复制代码

    docker-push脚本内容以下:

    # 容器名
    name=`cat version | awk '{print $1}'`
    # 容器标签
    tag=`cat version | awk '{print $2}'`
    # 仓库域名
    domain=registry-vpc.cn-shenzhen.aliyuncs.com
    # 仓库URL
    url=colehuang/coletest
     # 构建Docker镜像
    docker build -t $name:$tag .
     # 获取镜像ID
    id=`docker images | grep $name | grep $tag | awk '{ print $3 }'`
     # 镜像上传至Docker镜像仓库
    docker login --username=xxx --password=xxx $domain
    docker tag $id $domain/$url:$tag
    docker push $domain/$url:$tag
    复制代码

    version文件内容以下:

    gdd 1.1.2
    复制代码
  7. 构建后操做

    构建后操做的过程大体能够分为以下步骤:

    • 将项目中的versiondocker-pull文件传送至远程服务器中
    • 进入在Publish over SSH中配置的远程服务器目录,并执行docker-pull脚本,从docker镜像仓库中拉取提交的新版本镜像,并使用该镜像构建docker容器

    docker-pull脚本内容以下:

    # 容器名
    name=`cat version | awk '{print $1}'`
    # 容器标签
    tag=`cat version | awk '{print $2}'`
    # 仓库域名
    domain=registry.cn-shenzhen.aliyuncs.com
    # 仓库URL
    url=colehuang/coletest
     # 从Docker镜像仓库中拉取镜像
    docker login --username=xxx --password=xxx $domain
    docker pull $domain/$url:$tag
     # 中止该镜像正在运行的Docker容器
    line=`docker ps | grep $name`
    if [ -n "$line" ]; then
    	echo "存在正在运行的$name容器, 正在使其中止运行..."
    	docker stop $name
    	echo "$name容器, 已中止运行"
    fi
     # 删除该镜像的Docker容器
    line=`docker ps -a | grep $name`
    if [ -n "$line" ]; then
    	echo "存在$name容器, 对其进行删除..."
    	docker rm $name
    	echo "$name容器, 已被删除"
    fi
     # 启动容器
    docker run --rm --name $name -p 8008:8006 -d $domain/$url:$tag
    
    IFS=$'\n'
     # 删除多余镜像
    images=`docker images | grep $domain/$url`
    for i in $images
    	do
    		echo $i
    		t=`echo "$i" | awk '{print $2}'`
    		if [ "$t" != "$tag" ]; then
    			id=`echo "$i" | awk '{print $3}'`
    			docker rmi $id
    		fi
    	done
    复制代码
  8. 基本完成

    完成以上全部配置后,当在本地将代码pushGit 远程仓库时,则会触发Git WebHooks,从而全自动的实现对服务器项目的自动更新和部署。

内容小结

这篇文章对如何使用Docker结合Jenkins实现Go语言项目的持续集成进行了简单讲解,在最后讲一下实践过程当中须要注意的地方。

首先是在Jenkins服务器上经过git pull命令拉取远程仓库的代码时,若是为私有仓库,可能会须要输入Git帐号和密码,这里使用的方式是经过设置Git全局变量的方式,记录Git帐号和密码。

git config --global credential.helper store
复制代码

而后是最后的构建后操做过程当中,笔者本人会出现一个现象,当远程服务器第一次从docker镜像仓库获取镜像时,会由于因为远程服务器本地不存在该镜像依赖的其余镜像,从而致使拉取的速度较慢,出现超时的状况。该问题的解决方案可修改超时时间或者进入远程服务器中手动拉取一遍。

最后附上与演示项目内容一致的代码仓库:gitee.com/hkail/go-do…

实践时需修改的内容可能有:

docker-push脚本文件中:domain仓库域名,url仓库URL,docker login命令后的用户名和密码

docker-pull脚本文件中:同docker-pull脚本文件,docker run命令后的映射端口号

最后,感谢你们的耐心阅读~

相关文章
相关标签/搜索