下篇:使用jenkins发布go项目到k8s,接上篇的手工体验改造为自动化发布
Posted ttropsstack
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了下篇:使用jenkins发布go项目到k8s,接上篇的手工体验改造为自动化发布相关的知识,希望对你有一定的参考价值。
写在开篇
关于上篇
本篇在 《上篇:带你手工体验从写代码、编译、打包镜像、部署到K8S的全过程》 的基础上,将手动的过程通过jenkins工具将其改造成自动化。
环境准备
我的环境说明:
组件 | 安装方式 | 访问IP | 访问端口 |
---|---|---|---|
jenkins | docker | 192.168.11.254 | 8086 |
gitlab | docker | 192.168.11.254 | 8088 |
harbor | docker | 192.168.11.254 | 8081 |
上面的3个组件均以docker的方式安装在同一台宿主机上,且是在k8s集群外部。即使Jenkins、GitLab、Harbor都部署在K8S集群外部,也是可以将Go web项目发布到K8S集群中的。那么,关于如何安装上面的组件,可参考我之前发布过的文章 《云原生下的CICD-3件套快速搭建合集:jenkins+harbor+gitlab》。
当然也可以将CICD的相关组件部署在K8S集群内部,这些内容后面有时间的时候再作分享。
制作jenkins镜像
因jenkinsci/blueocean镜像中没有安装go和kubectl,因此基于它来重新制作一个新的镜像,把go和kubectl安装好。
- 从jenkinsci/blueocean镜像启动jenkins容器
[root@workhost jenkins]# docker run -d -u root --name jenkins-ser01 --restart=always -p 8086:8080 -p 50000:50000 -v /data/jenkins/data:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean
- 将准备好的kubectl工具拷贝到容器里面
# 我的宿主机已经有kubectl二进制包
[root@workhost jenkins]# docker cp /usr/local/bin/kubectl jenkins-ser01:/bin/kubectl
# 拷贝后进入容器检查能否正常执行
bash-5.1# kubectl version
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. Use --output=yaml|json to get the full version.
Client Version: version.InfoMajor:"1", Minor:"25", GitVersion:"v1.25.4", GitCommit:"872a965c6c6526caa949f0c6ac028ef7aff3fb78", GitTreeState:"clean", BuildDate:"2022-11-09T13:36:36Z", GoVersion:"go1.19.3", Compiler:"gc", Platform:"linux/amd64"
Kustomize Version: v4.5.7
- 进入容器编译安装golang
由于jenkins镜像是基于Alpine Linux的,需要从源代码编译安装go,不然其它发行版的二进制包是不能直接使用的
# 进入容器
[root@workhost jenkins]# docker exec -it jenkins-ser01 bash
# 编译安装golang
bash-5.1# export GOARCH=amd64
bash-5.1# export GOOS=linux
bash-5.1# wget https://go.dev/dl/go1.20.4.src.tar.gz
bash-5.1# tar -zxf go1.20.4.src.tar.gz
bash-5.1# apk add --no-cache --virtual .build-deps bash gcc go musl-dev
bash-5.1# export GOROOT_BOOTSTRAP="$(go env GOROOT)" GOHOSTOS="$GOOS" GOHOSTARCH="$GOARCH"
bash-5.1# cd ./go/src
bash-5.1# ./make.bash
bash-5.1# go install std
# 查看版本
bash-5.1# which go
/usr/bin/go
bash-5.1#
bash-5.1# go version
go version go1.18.7 linux/amd64
# 清理现场和退出容器
bash-5.1# cd /
bash-5.1# rm -rf go go1.20.4.src.tar.gz
bash-5.1# exit
exit
- 从容器提交镜像并推送到harbor
[root@workhost jenkins]# docker commit jenkins-ser01 192.168.11.254:8081/jenkins/jenkins:20230505v1
sha256:34685da4c262a14229d4aee5de9a294a877f4974c68f2bcff5e57d3f1420f101
[root@workhost jenkins]# docker push 192.168.11.254:8081/jenkins/jenkins:20230505v1
The push refers to repository [192.168.11.254:8081/jenkins/jenkins]
334b6fe88500: Pushing [====> ] 78.86MB/838.3MB
18df88a5f0e3: Pushed
704921b7ee47: Pushing [====================> ] 94.57MB/235MB
...
...
- 最后就可以删掉这个容器
[root@workhost jenkins]# docker stop jenkins-ser01
jenkins-ser01
[root@workhost jenkins]# docker rm jenkins-ser01
jenkins-ser01
- 从制作好的镜像启动jenkins容器
[root@workhost jenkins]# docker run -d -u root --name jenkins-ser01 --restart=always -p 8086:8080 -p 50000:50000 -v /data/jenkins/data:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock 192.168.11.254:8081/jenkins/jenkins:20230505v1
a052d6f503d6ef9a90d8cc99bf606daa92b5c890a8bff885d2b189fa1174492a
[root@workhost jenkins]#
[root@workhost jenkins]# docker ps -a | grep jenk
a052d6f503d6 192.168.11.254:8081/jenkins/jenkins:20230505v1 "/sbin/tini -- /usr/…" 7 seconds ago Up 6 seconds 0.0.0.0:50000->50000/tcp, :::50000->50000/tcp, 0.0.0.0:8086->8080/tcp, :::8086->8080/tcp jenkins-ser01
[root@workhost jenkins]#
[root@workhost jenkins]# docker exec -it jenkins-ser01 bash
bash-5.1# go version
go version go1.18.7 linux/amd64
bash-5.1# kubectl version
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. Use --output=yaml|json to get the full version.
Client Version: version.InfoMajor:"1", Minor:"25", GitVersion:"v1.25.4", GitCommit:"872a965c6c6526caa949f0c6ac028ef7aff3fb78", GitTreeState:"clean", BuildDate:"2022-11-09T13:36:36Z", GoVersion:"go1.19.3", Compiler:"gc", Platform:"linux/amd64"
Kustomize Version: v4.5.7
构建方式的选择
在 Jenkins 中,Freestyle Project 和 Pipeline 都是常用的构建作业类型,它们都可以用来实现自动化构建和持续集成,但它们的应用场景略有不同,还是得提前了解一下:
- 如果项目比较简单,例如只需要执行一些 Shell 命令、构建 Maven 项目、执行 Ant 构建等简单操作,那么使用 Freestyle Project 就可以满足需求,因为 Freestyle Project 的配置界面非常简单,可以快速地完成配置和构建。
- 如果项目比较复杂,例如需要处理多个 Git 仓库、执行多个步骤、分支流程等,那么使用 Pipeline 可能更加适合,因为 Pipeline 具有灵活的流程控制能力,可以支持复杂的项目构建过程。同时,Pipeline 也支持以代码的形式进行定义,具有更好的可维护性和可重用性。
建议根据项目的具体需求,选择使用适合的构建方式。通过对这两种构建方式的了解,相信你已经知道了哪种合适自己了。当然,还有其它的构建方式,比如“多分支流水线”等等,这些以后用到了再去了解吧。
涉及到的插件
下面的插件是我以后要用到的,先提前安装好。本次打算先用“自由软件风格项目”来发布goweb应用,有些插件在本篇还未用到,比如Pipeline,不过装上也无妨。因篇幅有限,本篇不讲如何安装插件,请自行安装好即可。
- Kubernetes:提供了在 Jenkins 中管理和部署应用程序到 Kubernetes 集群的能力。
- Kubernetes CLI:提供了在 Jenkins 中使用 kubectl 命令行工具与 Kubernetes 集群交互的能力。
- Git:用于在 Jenkins 中集成 Git 版本控制系统。
- Docker:用于在 Jenkins 中构建和推送 Docker 镜像。
- Credentials:用于在 Jenkins 中配置和管理 GitLab 和 Harbor 的认证凭据。
- Config File Provider
- Pipeline:用于在 Jenkins 中创建和管理流水线(Pipeline)作业。
- Go:是一个官方支持的Jenkins插件,它提供了构建和部署Go应用程序的能力。
提示:如果只需要使用 kubectl 命令行工具与 Kubernetes 集群交互,那么只需要安装 Kubernetes CLI 插件即可。如果需要在 Jenkins 构建管道中使用 Kubernetes 插件提供的更丰富的功能和 Jenkins 语法来管理 Kubernetes 资源,那么需要安装 Kubernetes 插件。在这里,我先把两个都安装上。
goweb项目结构
[root@workhost goweb]# tree
.
├── Dockerfile
├── go.mod
├── main.go
├── README.md
└── static
└── login.html
[root@workhost goweb]#
Dockerfile代码:
FROM alpine:latest
WORKDIR /app
COPY static /app/static
COPY main /app
EXPOSE 80
CMD ["./main"]
将dockerfile和项目代码一并提交到gitlab:
git add .
git commit -m "add code"
git push
提交后:
在jenkins发布goweb
- 凭据准备
装备好k8s、gitlab、harbor的凭据
连接k8s的凭据,我直接上传了kubeconfig文件:
- 创建自由风格的软件项目
- 在参数化构建选项中准备好要用到的参数
- VERSION:这个变量我打算用来作为发布版本的用途,当构建镜像时,会作为镜像的标签
- HARORB_ADMIN_PASSWD:因为推送镜像时我用到是shell命令的方式,登录harbor的时候引用这个密码变量
- 源码管理,配置git
这里要注意指定分支,我的是 “/main”,在gitlab上进入代码仓库里可看到。
- 在构建环境中配置连接k8s
- 构建步骤中配置编译go代码
- 构建步骤中配置构建镜像和推送镜像
- 构建步骤中,配置创建deployment和service
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: goweb
name: goweb
spec:
replicas: 6
selector:
matchLabels:
app: goweb
template:
metadata:
labels:
app: goweb
spec:
containers:
- image: 192.168.11.254:8081/webdemo/goweb:$VERSION
imagePullPolicy: Always
name: goweb
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: goweb
name: goweb
spec:
ports:
- name: http-port
port: 5678
protocol: TCP
targetPort: 80
nodePort: 30080
selector:
app: goweb
type: NodePort
- 开始运行构建任务
- 到k8s上检查
[root@k8s-b-master ~]# kubectl get deployment,pod,svc
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/goweb 6/6 6 6 73m
NAME READY STATUS RESTARTS AGE
pod/goweb-d59b979bb-2xrxm 1/1 Running 0 58s
pod/goweb-d59b979bb-jllgt 1/1 Running 0 56s
pod/goweb-d59b979bb-nd8dl 1/1 Running 0 56s
pod/goweb-d59b979bb-prl7m 1/1 Running 0 55s
pod/goweb-d59b979bb-r5csh 1/1 Running 0 58s
pod/goweb-d59b979bb-t2v5n 1/1 Running 0 58s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/goweb NodePort 10.96.6.121 <none> 5678:30080/TCP 55m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
[root@k8s-b-master ~]#
- 访问
最后
本次采用的是Freestyle Project的构建方式,这是最常见,也是比较传统的方式。下次在k8s部署 jenkins 主从架构,并以 Pipeline 的方式来构建发布。
本文转载于WX公众号:不背锅运维(喜欢的盆友关注我们):https://mp.weixin.qq.com/s/yJ6rkYrwn8RAMLt5uCF9mw
使用 Docker 在 Jenkins 上使用“供应商”目录构建 Go 应用程序
【中文标题】使用 Docker 在 Jenkins 上使用“供应商”目录构建 Go 应用程序【英文标题】:Building Go app with "vendor" directory on Jenkins with Docker 【发布时间】:2016-12-24 01:41:06 【问题描述】:我正在尝试使用Jenkinsfile
和docker.image().inside
设置一个 Jenkins 流水线来构建和部署我的第一个 Go 项目。我不知道如何去获取vendor/
目录中的依赖项。
当我运行构建时,我得到了一堆错误:
+ goapp 测试 ./... src/dao/demo_dao.go:8:2:在以下任何一个中都找不到包“github.com/dgrijalva/jwt-go”: /usr/lib/go_appengine/goroot/src/github.com/dgrijalva/jwt-go(来自 $GOROOT) /usr/lib/go_appengine/gopath/src/github.com/dgrijalva/jwt-go(来自 $GOPATH) /workspace/src/github.com/dgrijalva/jwt-go...为什么不选择 Vendor 目录?
当我输入一些日志时,似乎在运行sh "cd /workspace/src/bitbucket.org/nalbion/go-demo"
之后,下一个sh
命令仍在原来的$WORKSPACE
目录中。我真的很喜欢 Jenkins 文件的想法,但我找不到任何合适的文档。
(编辑 - here 有不错的文档,但 dir("/workspace/src/bitbucket.org/nalbion/go-demo")
似乎不适用于 docker.image().inside)
我的 Docker 文件类似于:
来自 golang:1.6.2 # Google 的 App Engine Go SDK 运行 wget https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.40.zip -q -O go_appengine_sdk.zip && \ 解压 -q go_appengine_sdk.zip -d /usr/lib/ && \ rm go_appengine_sdk.zip 环境路径 /usr/lib/go_appengine:/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin: /bin ENV GOPATH /usr/lib/go_appengine/gopath # 添加詹金斯用户 运行 groupadd -g 132 jenkins && useradd -d "/var/jenkins_home" -u 122 -g 132 -m -s /bin/bash jenkins还有我的 Jenkinsfile:
节点(“码头工人”) currentBuild.result = "成功" 尝试 阶段“结帐” 结帐单片机 阶段“构建和测试” env.WORKSPACE = pwd() docker.image('nalbion/go-web-build:latest').inside( "-v $env.WORKSPACE:/workspace/src/bitbucket.org/nalbion/go-demo " + "-e GOPATH=/usr/lib/go_appengine/gopath:/workspace") // 调试 sh '回声 GOPATH: $GOPATH' sh "ls -al /workspace/src/bitbucket.org/nalbion/go-demo" sh "cd /workspace/src/bitbucket.org/nalbion/go-demo" sh "密码" sh "去检查 ./src/..." sh "goapp 测试 ./..." 阶段“部署到 DEV” docker.image('nalbion/go-web-build').inside sh "goapp deploy --application go-demo --version v$v app.yaml" 超时(时间:5,单位:'DAYS') 输入消息:'批准部署?',提交者:'qa' 阶段“部署到生产” docker.image('nalbion/go-web-build').inside sh "goapp deploy --application go-demo --version v$v app.yaml" 捕捉(错误) currentBuild.result = "失败" // 发送通知 抛出错误【问题讨论】:
【参考方案1】:我设法通过在同一 sh
语句中包含 cd
来使其工作:
【讨论】:
以上是关于下篇:使用jenkins发布go项目到k8s,接上篇的手工体验改造为自动化发布的主要内容,如果未能解决你的问题,请参考以下文章
使用Jenkins实现重构项目并部署项目到阿里k8s环境运行
CICD实现方法之二--Gitlab+Jenkins+K8S
CICD实现方法之二--Gitlab+Jenkins+K8S