go程序基于阿里云CodePipeline的一次devops实践

背景

最近朋友有个项目代码托管用的码云,测试服务器(阿里云ECS)只有一台,三四个人开发,于是想基于阿里云的CodePipeline快速打造一套自动化cicd的流程,使用docker来进行多套环境部署。

CodePipeline 介绍

阿里云CodePipeline是兼容Jenkins标准的、提供快速可靠的持续集成与持续交付服务。基于容器技术和阿里云基础服务架构,提供稳定和安全的代码/Docker编译构建,测试,扫描和部署的工具服务,并提供Pipeline As Code的编码级配置模式,满足应用程序和基础设施快速可靠的交付和更新。

在这里插入图片描述

上面是阿里云的官方介绍,兼容jekins的标准,一次无意的点击出现了下图的图标,感觉就是jenkins的基础上做了一次二次开发。


在这里插入图片描述

新建构建项目

在这里插入图片描述

构建项目基本配置

基本信息配置

在这里插入图片描述

由于项目使用到了一些国外的lib,当然选择国内的节点也是可以的,不过在写Dockerfile的时候记得加上代理。

源码管理配置

在这里插入图片描述

选择合适的代码仓库,也可以是私仓,不过需要配上自己的账号和ssh key相关信息。

构建配置

在这里插入图片描述

我这里使用的是阿里云的私有的镜像仓库基于Dockerfile来构建镜像,注意配置凭证。


在这里插入图片描述
项目目录
gin_demo
├── app
│   └── app.go
├── conf
│   └── app.ini
├── Dockerfile
├── docs
│   └── sql
│       └── mjs.sql
├── go.mod
├── go.sum
├── main.go
├── middleware
│   ├── jwt
│   │   └── jwt.go
│   └── logging
│       └── logger.go
├── mjs.exe
├── models
│   ├── mongo
│   │   └── db.go
│   └── mysql
│       ├── db.go
│       ├── teacher.go
│       └── user.go
├── pkg
│   ├── app
│   │   ├── form.go
│   │   ├── request.go
│   │   └── response.go
│   ├── def
│   │   └── def.go
│   ├── e
│   │   ├── code.go
│   │   ├── def.go
│   │   └── msg.go
│   ├── file
│   │   └── file.go
│   ├── gredis
│   │   └── redis.go
│   ├── logging
│   │   ├── file.go
│   │   └── log.go
│   ├── setting
│   │   └── setting.go
│   ├── upload
│   │   └── image.go
│   └── util
│       ├── jwt.go
│       ├── md5.go
│       ├── pagination.go
│       └── util.go
├── README.en.md
├── README.md
├── routers
│   ├── api
│   │   └── v1
│   └── router.go
├── runtime
│   └── logs
│       ├── log20190528.log
│       └── log20190529.log
└── service
    ├── teacher_service
    │   └── teacher.go
    └── user_service
        └── user.go

Dockerfile
FROM golang:1.12.4 as build

#ENV GOPROXY https://goproxy.io 

WORKDIR /go/cache

ADD go.mod .
ADD go.sum .
RUN go mod download

WORKDIR /go/release

ADD . .

RUN GOOS=linux CGO_ENABLED=0 go build -ldflags="-s -w" -installsuffix cgo -o gin_demo main.go

FROM scratch as prod

COPY --from=build /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build /go/release/gin_demo /
COPY --from=build /go/release/conf ./conf
CMD ["/gin_demo"]

注:如果选择国内节点构建必须配上代理 ENV GOPROXY https://goproxy.io

配置触发器

在这里插入图片描述

这里选择一个构建的代码分支,然后点击生成,将生成后的url可以在对应的代码仓库配上webhook之类的配置。选择合适的触发方式。


在这里插入图片描述

配置部署

在这里插入图片描述

阿里云构建步骤里面部署到ECS上(不方便)和部署到k8s(收费)都不能满足项目场景需求,不过上面支持shell脚本,于是自己想在朋友的那台阿里云ECS上跑个ci的web server,这里构建完之后就去通知下这个接口,然后去执行一些docker指令的脚本,拉取构建完之后的镜像并且重新启动,启动完之后邮件通知。于是写了这样一个很简单的web server。
main

package main

import (
    "fmt"
    "log"
    "net/http"
    "os/exec"
    "path"
)

/*
* @Author:hanyajun
* @Date:2019/5/28 16:44
* @Name:ci_tools
* @Function: ci 工具
 */

//
func HandleCi(w http.ResponseWriter, req *http.Request) {
    user := path.Base(req.URL.Path)
    //针对不同开发人员的push拉取不同的镜像和映射不同的端口
    var port string
    switch user {
    case "zhangsan":
        port = "8088"
    case "lisi":
        port = "8087"
    case "wangmazi":
        port = "8086"
    case "dev":
        port = "8085"
    case "master":
        port = "8084"

    }
    println(user)
    result := Run(user,port)
    client:=NewMailClient("smtp.qq.com",465,"******@qq.com","*********")//注意使用465 ssl发送,25端口阿里云ecs禁止了。
    s:=&SendObject{
        ToMails:[]string{"******@qq.com","******@qq.com","******@qq.com"},
        CcMails:[]string{"******@qq.com"},
        Object:"cicd流程结果通知",
        ContentType:"text/html",
        Content:user+" has push something to the branch: "+user+"\n"+"result: "+string(result),
    }
    err:=client.SendMail(s)
    if err!=nil{
        println("send mail fail",err)
    }
    _, _ = w.Write(result)
}
func main() {
    http.HandleFunc("/ci/", HandleCi)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

func Run(user string,port string) []byte {

    shellPath := "/root/ci/ci.sh"
    command := exec.Command(shellPath, user,port) 
    err := command.Start()                   
    if nil != err {
        fmt.Println(err)
        return []byte(err.Error())
    }
    fmt.Println("Process PID:", command.Process.Pid)
    err = command.Wait() //等待执行完成
    if nil != err {
        fmt.Println(err)
        return []byte(err.Error())
    }
    fmt.Println("ProcessState PID:", command.ProcessState.Pid())
    return []byte("success")
}

mail.go

package main

import (
    "fmt"
    "gopkg.in/gomail.v2"
)

/*
* @Author:15815
* @Date:2019/5/8 17:47
* @Name:mail
* @Function:邮件发送
 */

type Client struct {
    Host     string
    Port     int
    Mail     string
    Password string
}

type SendObject struct {
    ToMails     []string
    CcMails     []string
    Object      string
    ContentType string
    Content     string
}

func NewMailClient(host string, port int, sendMail, password string) *Client {
    return &Client{
        Host:     host,
        Port:     port,
        Mail:     sendMail,
        Password: password,
    }
}
func (m *Client) SendMail(s *SendObject) error {
    mgs := gomail.NewMessage()
    mgs.SetHeader("From", m.Mail)
    mgs.SetHeader("To", s.ToMails...)
    mgs.SetHeader("Cc", s.CcMails...)
    mgs.SetHeader("Subject", s.Object)
    mgs.SetBody(s.ContentType, s.Content)
    d := gomail.NewDialer(m.Host, m.Port, m.Mail, m.Password)
    if err := d.DialAndSend(mgs); err != nil {
        fmt.Printf("send mail err:%v", err)
        return err
    }
    return nil
}

ci.sh

#!/bin/bash
funCiTools()
{
    docker pull registry.cn-shanghai.aliyuncs.com/***/***:$1
    docker rm -f $1
    docker run -d -p $2:8000 --name $1 registry.cn-shanghai.aliyuncs.com/***/***:$1
}
funCiTools $1 $2

第一个参数是对应开发人员启动容器的名字以及构建镜像的tag和上面构建的配置一致,第二个参数是映射的端口。
构建ci_web_server

自己的电脑是windows的,朋友的阿里云ecs上又没有go环境,想构建基于linux的二进制程序,于是直接利用docker image 来构建了镜像,一个指令解决问题。
build.sh

docker run --rm -i -v `pwd`:/go/src/ci -w /go/src/ci  golang:1.11.5   go build -o ci  ci

使用nohup直接将ci server放置后台运行。

nohup ./ci  >output 2>&1 &

效果测试

直接修改点东西提交代码后就等邮件通知了,是不是感觉很爽。


在这里插入图片描述

提交完代码后就开始触发构建了。


在这里插入图片描述

最后构建完完成后触发ci server 进行deploy,完成邮件通知。
在这里插入图片描述

登录到阿里云Ecs上我们发现我们的容器已经启动成功了。


在这里插入图片描述
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,928评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,748评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,282评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,065评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,101评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,855评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,521评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,414评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,931评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,053评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,191评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,873评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,529评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,074评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,188评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,491评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,173评论 2 357

推荐阅读更多精彩内容

  • 识别二维码报名活动 8月19日,来自微软、数人云、京东、当当网的四位IT老兵,《一起吹响Container+集结号...
    优云数智阅读 715评论 0 12
  • 敏捷开发少不了一个方便的持续交付环境。这些天在阿里云简单搭了一套开发环境,这里简单记录一下搭建过程。 先盗张图 J...
    元家昕阅读 3,799评论 0 2
  • 周小安被那人的声音吓了一跳。他心想:这种独特的嗓音实在太像刘富贵了!……可那胖子不是已经死了吗。他的脑海中浮现出一...
    张三疯漫画阅读 1,140评论 0 1
  • 2016-03-12 周六 晴 今天当了一回小白鼠。 上学期参加了一次学校的“爱上实验室”活动,参观了五道口金融学...
    韩日记阅读 298评论 0 3
  • 题记:除夕夜随笔第二篇 2018年资本市场寒冬,大家都缩在自己的蜗牛壳里迤逦前行。而我的2018,工作不顺利,生活...
    JuicyOnTheWay阅读 269评论 0 2