Golang 实现 CICD
所有有关harbor的操作 请确保harbor已经创建相关的项目
0、Go测试代码
package main
import (
"fmt"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/logger"
"github.com/kataras/iris/v12/middleware/recover"
)
func GoLoop() {
for {
fmt.Println("hello")
}
}
func main() {
app := iris.New()
app.Use(recover.New())
app.Use(logger.New())
go GoLoop()
//输出html
// 请求方式: GET
// 访问地址: http://localhost:8080/welcome
app.Handle("GET", "/welcome", func(ctx iris.Context) {
ctx.HTML("<h1>Welcome</h1>")
})
//输出字符串
// 类似于 app.Handle("GET", "/ping", [...])
// 请求方式: GET
// 请求地址: http://localhost:8080/ping
app.Get("/ping", func(ctx iris.Context) {
ctx.WriteString("pong")
})
//输出json
// 请求方式: GET
// 请求地址: http://localhost:8080/hello
app.Get("/hello", func(ctx iris.Context) {
ctx.JSON(iris.Map{"message": "Hello Iris!"})
})
app.Run(iris.Addr(":8081"))//8080 监听端口
}
1、Go服务构建
我们需要通过自定义镜像底包,能够让该底包拥有启动go程序的基本功能和日志重定向输出到指定目录下,方便日志收集,编辑完相关文件后,我们需要通过docker
命令去构建镜像,构建完毕后将其推送到harbor base仓库,该名为base的仓库需要手动去harbor上创建。
1.1、制作Go服务镜像底包
创建一个目录 在该目录下执行下面操作
1.1.1、编写Dockerfile以及相关的启动脚本
cp /etc/yum.repos.d/CentOS-Base.repo 到当前目录下
- Dcokerfile
FROM alpine
USER root
RUN apk add tzdata && /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\
echo 'Asia/Shanghai' >/etc/timezone &&\
mkdir /opt/logs
WORKDIR /opt/project_dir/
1.1.2、构建镜像并上传到harbor仓库
$ docker build ./ -t harbor地址/base/go-run:1.14.2-1
Sending build context to Docker daemon 3.072kB
Step 1/6 : FROM alpine
---> a187dde48cd2
Step 2/6 : USER root
---> Using cache
---> f0673624a0e0
Step 3/6 : RUN apk add tzdata && /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone && mkdir /opt/logs
---> Using cache
---> e91f2e8a4919
Step 4/6 : WORKDIR /opt/project_dir/
---> Using cache
---> 6afa8e9ddd43
Step 5/6 : ADD entrypoint.sh /entrypoint.sh
---> Using cache
---> 7a7efe533a5f
Step 6/6 : CMD ["/entrypoint.sh"]
---> Using cache
---> 17d85fd60af3
Successfully built 17d85fd60af3
Successfully tagged harbor.od.com/base/go-run:1.14.2-1
$ docker push harbor地址/base/go-run:1.14.2-1
The push refers to repository [harbor.od.com/base/go-run]
20c042b1ca31: Mounted from base/go-test
98e20bd596b3: Mounted from base/go-test
f4ee0579d5d8: Mounted from base/go-test
beee9f30bc1f: Mounted from base/go-test
1.14.2-1: digest: sha256:49dda47c11a3148fdfd60fe4850ada128e6550fb33c1a6284caadf0e6ea8016d size: 1153
1.2、制作slave基础镜像底包
我们是基于jenkins slave方式去构建项目,并且使用pipeline来实现流程化,我们都知道slave运行的是一个pod,那么pod里可以有多个容器,而这些一个一个的容器就是执行我们对应操作的环境,所以我们需要通过制作一些镜像来满足我们的需求。
创建一个目录 在该目录下执行下面操作
1.2.1、Golang镜像
该镜像主要用于构建golang应用,我们是在基于golang v1.14.2环境下开发的golang程序,所以这里镜像版本就选择:golang:v1.14.2
docker pull golang:v1.14.12-stretch
docker images 查看刚刚pull下来的 image id
docker tag imageid harbor地址/public/golang:v1.14.12-stretch
docker push harbor地址/public/golang:v1.14.12-stretch
1.2.2、Docker镜像
该镜像主要用于将编译好的golang项目打包成镜像并推送到harbor,但需要定制化一下镜像,需要将一台已经实现docker login 登录到harbor仓库所生成的配置文件,路径为:/root/.docker/config.json,与原始Docker镜像一起打包生成新的Docker镜像并推送到本地仓库。
1.docker登录私有镜像仓库
在 /etc/docker/daemon.json 里写入 私有仓库地址
{
"insecure-registries": ["harbor地址"]
}
登录 默认账号 admin 密码 Harbor12345
docker login -u admin -p Harbor12345 harbor地址
2.准备镜像文件
docker pull docker:19.03
docker tag e036013d6d10 harbor地址/public/docker:v19.03
docker push harbor地址/public/docker:v19.03
3.准备Dockerfile和config.json
- Dockerfile
FROM harbor地址/public/docker:v19.03
USER root
ADD config.json /root/.docker/config.json
4.将/root/.docker/config.json文件拷贝到Dockerfile目录下
{
"auths": {
"harbor.od.com": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/19.03.6 (linux)"
}
}
5.制作并推送镜像
$ docker build ./ -t harbor地址/public/docker:v19.03
$ docker push harbor地址/public/docker:v19.0
2、Jenkins流水线
2.1、创建流水线
1.添加参数化构建
- Choice Parameterr:app_project
Value:jenkins-test
Describe:项目名必须和git仓库名一致
- Choice Parameterr:image_name
Value:app/go-test
Describe:镜像名称:仓库名/镜像名
- String Parameterr:git_ver
Value:master
Describe:Git仓库分支或Commit ID
- String Parameterr:add_tag
Value:
Describe:打包镜像tag,一般为日期时间
- Choice Parameterr:git_repo
Value:https://gitee.com/zzxaaas/jenkins-test.git
Describe:代码仓库地址
- Choice Parameterr:base_image
Value:base/go-run:1.14.2-1
Describe:基础镜像底包
2.pipeline代码
podTemplate(cloud:'kubernetes',containers: [
containerTemplate(
name: 'go-build',
envVars: [
envVar(key: 'GO111MODULE', value: 'on'),
envVar(key: 'GOPROXY', value: 'https://goproxy.io'),
envVar(key: 'CGO_ENABLED', value: '0'),
envVar(key: 'GOOS', value: 'linux')
],
image: 'harbor.zzx/public/golang:v1.14.12-stretch',
ttyEnabled: true,
command: 'cat'),
containerTemplate(
name: 'docker',
ttyEnabled: true,
image: 'harbor.zzx/public/docker:v19.03'),
],
volumes: [
nfsVolume(mountPath: '/go/pkg/mod', readOnly: false, serverAddress: 'nfs.server', serverPath: '/data/k8s/go-pkg/'),
hostPathVolume(hostPath: '/run/docker.sock', mountPath: '/run/docker.sock')
]
){
node(POD_LABEL) {
stage('Get a Go project') {
// 从git仓库拉取代码
checkout([$class: 'GitSCM', branches: [[name: "${params.git_ver}"]], browser: [$class: 'GitLab', repoUrl: ''], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'git', name: 'git', refspec: 'refs/changes/*:refs/changes/*', url: "${params.git_repo}"]]])
container('go-build') {
stage('Build a go project') {
// 将go应用构建名为app的可执行二进制文件
sh "go build -o app"
}
}
}
stage('Docker build') {
container('docker') {
stage('create dir'){
sh "mkdir -p /tmp/${params.app_project}/project_dir && mv ./app /tmp/${params.app_project}/project_dir"
stage('build docker iamge'){
sh """
echo "FROM harbor.zzx/${params.base_image}" >/tmp/${params.app_project}/Dockerfile
echo "ADD ./project_dir /opt/project_dir" >>/tmp/${params.app_project}/Dockerfile
"""
sh "docker login -u admin -p Harbor12345 harbor.zzx"
sh "cd /tmp/${params.app_project}/ && pwd && docker build ./ -t harbor.zzx/${params.image_name}:${params.git_ver}_${params.add_tag} && docker push harbor.zzx/${params.image_name}:${params.git_ver}_${params.add_tag} "
}
}
}
}
}
}
3、golang资源配置清单
创建一个目录,在该目录下执行下面操作
3.1、准备资源配置清单
准备3个yaml文件 deployment.yaml
svc.yaml
ingress.yaml
1.deployment
kind: Deployment
apiVersion: apps/v1
metadata:
name: go-test
namespace: app
labels:
name: go-test
spec:
replicas: 1
selector:
matchLabels:
name: go-test
template:
metadata:
labels:
app: go-test
name: go-test
spec:
containers:
- name: go-test
command: [ "/bin/sh", "-c", "--" ]
args: [ "/opt/project_dir/app;while true; do sleep 30; done;" ]
image: harbor.zzx/app/go-test:master_20210106_1143
ports:
- containerPort: 80
protocol: TCP
imagePullPolicy: IfNotPresent
imagePullSecrets:
- name: harbor
restartPolicy: Always
terminationGracePeriodSeconds: 30
securityContext:
runAsUser: 0
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
revisionHistoryLimit: 7
progressDeadlineSeconds: 600
2.svc
kind: Service
apiVersion: v1
metadata:
name: go-test
namespace: app
spec:
type: NodePort
ports:
- protocol: TCP
port: 8081
targetPort: 8081
nodePort: 30088 #外部访问端口
selector:
name: go-test
3.ingress
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: go-test
namespace: app
spec:
rules:
- host: gotest.com
http:
paths:
- path: /
backend:
serviceName: go-test
servicePort: 80
3.2、应用资源配置清单
kubectl create namespace app
kubectl apply -f ./
修改某个yaml文件后 单独 kubectl apply -f yaml文件名
查看pod运行状态
$ kubectl get pods -n app
NAME READY STATUS RESTARTS AGE
go-test-55474c768d-x8qj5 1/1 Running 0 2m10s
3.3、浏览器访问golang业务
1.浏览器访问 k8s结点ip:30088/welcome
4、k8s 其他命令
查看pod信息
kubectl describe pod go-test-55474c768d-x8qj5 -n app
删除yaml
kubectl delete -f yaml文件名
创建yaml
kubectl create-f yaml文件名
查看pod日志
kubectl logs go-test-55474c768d-x8qj5 -n app
5、docker命令
查看镜像
docker images
查看 当前正在运行的容器
docker ps
-a : 全部
进入容器(先通过 docker ps 获取容器id)
docker exec -it 容器id sh
删除镜像
docker rmi 镜像id
-f : 强制删除
删除容器
docker rm 容器id