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

2020/5/11 17:26:59

本文主要是介绍使用Docker+Jenkins实现Go语言项目的持续集成,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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

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

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

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

  • Docker

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

  • Docker Compose

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

  • Jenkins

    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命令后的映射端口号

最后,感谢大家的耐心阅读~



这篇关于使用Docker+Jenkins实现Go语言项目的持续集成的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程