回顾上文
由于本篇跳过了前两篇进行撰写,本期旨在探讨如何借助 Jenkins + k8s 实现快速持续交付。此前,虽对 k8s 有过简单学习,但尚未进行实际操作。近期恰逢华为云服务器优惠力度大,便购入 3 台,由此萌生了撰写此文的想法。在本文中,我将详细介绍如何通过 Jenkins 和 k8s 实现快速持续交付,同时分享在此过程中遇到的一些坑及解决方法。
能学到什么
-
Jenkins快速安装
-
k8s部署
涉及技术
-
Docker
-
k8s
-
Jenkins
架构设计
暂时无法在飞书文档外展示此内容
前提准备
机器选购
为了这期文,我大出血在华为云选购了三台云服务非常的便宜(28元),有兴趣的友友可以选购选购,话不多说开干。
配置
- master(2c4g)
- node1(2c2g)
- node2(2c2g)
注意:
这里由于node1处于华北区域机器,master和node2处于华南区域,无法通过内网互相访问(华为提供云链接等方案可以解决)。
k8s集群部署
-
K8s 1.28.0
-
Docker 26.1.4
k8s搭建可以参考:实战Kubernetes之快速部署 K8s 集群 v1.28.0-云社区-华为云
master作为控制节点及主节点,node2作为从节点。由于node1无法通过内网与master通信,至此node1节点就作为服务依赖节点(mysql,redis,mq,consul)。
在网上找过许多方案通过修改iptable表来访问,但是加入节点始终加入不进去。
当访问192.168.14.109时通过路由表访问120.46.15.126 。 iptables -t nat -A OUTPUT -d 192.168.14.109 -j DNAT --to-destination 120.46.15.126
服务依赖节点 node1
Jenkisn
部署
这里jenkins部署通过运行jar包的形式使用。
需要jenkins.war的请留言。
- Java 11
java -jar jenkins.war
配置
-
创建任务
- 新建任务
- 选择自由风格
-
配置
-
源码管理
-
-
如果遇到如上错误可能就是没有安装git,
yum install git
-
构建触发器
- 选择Generic Webhook Trigger形式
- 找到仓库的webhooks功能
-
保持测试
-
-
-
sudo docker push swr.cn-north-4.myhuaweicloud.com/bbz/select:1.1
资源编写
这里只有简单的两个服务
user服务
- 10000
user比较简单这里只进行分配到一台机器即可。
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
namespace: select-course
labels:
app: user-service
spec:
replicas: 1
selector:
matchLabels:
app: user-service
template:
metadata:
name: user-service
labels:
app: user-service
version: "BUILD_HASH"
spec:
containers:
- name: user-service
image: swr.cn-north-4.myhuaweicloud.com/bbz/select-course:latest
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "export BASE_HOST=`hostname -i` && ./services/user/UserService" ]
ports:
- name: grpc-10000
containerPort: 10000
protocol: TCP
volumeMounts:
- name: config-env
mountPath: /project/.env
subPath: .env
- name: project-logs-volume
mountPath: /project/logs
imagePullSecrets:
- name: harborsecret
volumes:
- name: config-env
configMap:
name: config-env
items:
- key: .env
path: .env
- name: project-logs-volume
hostPath:
path: /data/logs
type: DirectoryOrCreate
restartPolicy: Always
terminationGracePeriodSeconds: 30
course服务
course服务分配到两台机器包括master(由于资源有限不得不使用master也作为服务节点)。
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: course-service
namespace: select-course
labels:
app: course-service
spec:
replicas: 2
selector:
matchLabels:
app: course-service
template:
metadata:
name: course-service
labels:
app: course-service
version: "BUILD_HASH"
spec:
containers:
- name: course-service
image: swr.cn-north-4.myhuaweicloud.com/bbz/select-course:latest
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "export BASE_HOST=`hostname -i` && ./services/course/CourseService" ]
ports:
- name: grpc-10001
containerPort: 10001
protocol: TCP
volumeMounts:
- name: config-env
mountPath: /project/.env
subPath: .env
- name: project-logs-volume
mountPath: /project/logs
imagePullSecrets:
- name: harborsecret
volumes:
- name: config-env
configMap:
name: config-env
items:
- key: .env
path: .env
- name: project-logs-volume
hostPath:
path: /data/logs
type: DirectoryOrCreate
restartPolicy: Always
terminationGracePeriodSeconds: 30
Ingress
这里通过使用DaemonSet模式让ingress代理主机80端口。
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx
namespace: select-course
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: nginx.kubernetes-devops.cn
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: gateway-svc
port:
number: 8888
打包进行上传到hub
这里由于国内访问docker hub被墙,所有这里使用华为云免费的私有hub仓库进行管理。
你也可以通过如下操作进行拉取,当前镜像属于公开的
docker pull swr.cn-north-4.myhuaweicloud.com/bbz/select-course:latest
通过k8s运行此项目
你可以通过项目根目录下的/k8s
文件夹直接启动项目,在启动项目前你需要部署项目的依赖文件,同级目录下的docker-compose.yaml
- 部署依赖服务
docker-compose up -d
2. 启动项目
cd k8s
# 如果没有部署ingress-nginx
# kubectl apply -f ingress-nginx
kubectl apply -f .
模拟
模拟推送事件
通过请求推送来进行触发构建操作
注意:
在实际开发场景下,并不是每次请求推送事件进行构建操作,这种常用于test分支,针对于主分支变更是非常少的。
推送
这里进行手动方式触发构建
构建步揍
#!/bin/bash
if [ ! "$(basename "$PWD")" ] = "select-course"; then
echo "please run this script in select-course"
exit 1
fi
# start
echo "starting..."
# 获取Jenkins构建号(如果在Jenkins环境中)
BUILD_NUMBER=${BUILD_NUMBER:-"unknown"}
BUILD_HASH=${BUILD_NUMBER}-${GIT_COMMIT}
IMAGE_NAME=select-course:${BUILD_HASH}
PUSH_IMAGE_NAME=swr.cn-north-4.myhuaweicloud.com/bbz/select-course:${BUILD_HASH}
# 构建镜像并使用唯一的标签
docker build -t "${IMAGE_NAME}" .
echo "build success"
# 推送带有唯一标签的镜像
docker tag "${IMAGE_NAME}" "${PUSH_IMAGE_NAME}" # 提交带有唯一标签的镜像
docker tag "${IMAGE_NAME}" select-course:latest # 提交最新的镜像
docker push "${PUSH_IMAGE_NAME}"
docker push select-course:latest
echo "push with unique tag success"
# 清理本地镜像
docker rmi -f "${IMAGE_NAME}"
docker rmi -f select-course:latest
docker rmi -f "${PUSH_IMAGE_NAME}"
echo "clear success"
# k8 replace
# 遍历目录中的所有 YAML 文件
find "./k8s" -name "*.yaml" | while read FILE; do
sed -i "s|BUILD_HASH|${BUILD_HASH}|" "$FILE"
done
# load configmap
# kubectl create configmap config-env -n select-course --from-file=./.env
kubectl apply -f k8s
echo "deploy success"
以下是流程图
一杯咖啡的时间。。。
暂时无法在飞书文档外展示此内容
坑集合
Jenkins
-
jenkins初始化时插件安装失败问题
-
问题原因:下载被墙。
-
解决:
-
作者在网上找到了jenkins的打包文件,可以快速运行无需安装,需要的可以留言。无坑
K8s
-
同网段问题
-
问题原因:我在购置三台云服务器时这三台云服务器并非在同一个地区(网段),只有两台节点在同一个地区,我尝试过许多方式将非同一个网段的地区加入到master节点,但还是未见效。
-
解决:
- blog.csdn.net/qq_33996921…
- 云厂商提供的解决方案
-
Ingress
ingress的问题也是卡我最长时间的问题,主要是对ingress操作不熟练。
-
拉取镜像问题
-
问题原因:被墙
-
解决:
-
在我项目里面也有ingress-nginx的已经修改的资源文件。
- 与k8s版本问题
总结
在篇文章中,我们通过搭建 k8s 集群,并部署 Jenkins,来实现选课系统的快速持续交付。其中,master 作为控制节点及主节点,node2 作为从节点,node1 由于无法与 master 通过内网通信,作为服务依赖节点(mysql,redis,mq,consul)。通过运行 jar 包的形式部署 Jenkins。通过仓库的webhook机制进行预订事件进行自动化构建。
注意:
该文章只是一个简单的持续交付流程,在实际的场景内比这复杂得多。不限于:版本控制、滚动更新、自动化测试等等。
请见下期文章。
本期代码请见:github.com/bbz1024/sel…
若阁下感兴趣可以clone下来玩一玩。
bash
代码解读
复制代码
git clone --branch demo6 https://github.com/bbz1024/select-course.git