前置条件
五台云服务器/五台虚拟机(当然也可以只用一台,所有环境都部署在一台服务器上,或者所有环境都使用docker搭建)
环境:jdk-8
我这里使用的是五台虚拟机,分别为:192.168.31.3、192.168.31.4、192.168.31.5、192.168.31.6、192.168.31.7
配置均为4H8G
ip地址 | 功能 |
---|---|
192.168.31.3 | docker容器 |
192.168.31.4 | gitlab |
192.168.31.5 | jenkins |
192.168.31.6 | harbor |
192.168.31.7 | k8s |
Centos7安装Docker
在192.168.31.3、192.168.31.4、192.168.31.5运行以下命令
#安装一些必要的系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
#添加Docker软件源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#更新yum软件包索引
sudo yum makecache fast
#安装Docker-ce
sudo yum -y install docker-ce
#启动Docker服务
sudo service docker start
#查看docker版本
docker version
# docker 服务开机自启
systemctl enable docker.service
配置阿里加速镜像:https://cr.console.aliyun.com/cn-shanghai/instances/mirrors
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
安装并初始化gitlab
在192.168.31.4这台服务器上安装gitlab
创建保存gitlab配置的文件夹
mkdir -p /etc/gitlab
mkdir -p /var/log/gitlab
mkdir -p /var/opt/gitlab
chmod -R 755 /etc/gitlab
chmod -R 755 /var/log/gitlab
chmod -R 755 /var/opt/gitlab
拉取gitlab镜像,并创建容器
docker run --name gitlab \
--hostname gitlab.oolo.cc \
--restart=always \
-p 80:80 \
-v /etc/gitlab:/etc/gitlab \
-v /var/log/gitlab:/var/log/gitlab \
-v /var/opt/gitlab:/var/opt/gitlab \
-d gitlab/gitlab-ce
等待下载完成过后,就可以通过http://192.168.31.4/访问gitlab了
然后运行以下命令拿到密码,用户名为root
[root@localhost ~]# sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
Password: PoiF4n5OCdH1azEEAfNKrSmOu9sVYXHiUy821eq0Tro=
[root@localhost ~]#
英文看着别扭可以设置中文
安装并初始化jenkins
在192.168.31.5上安装jenkins
jdk8:https://cdn.oolo.cc/source/jdk-8u341-linux-x64.tar.gz
maven:https://cdn.oolo.cc/source/apache-maven-3.8.6-bin.tar.gz
maven配置文件:https://cdn.oolo.cc/source/setting.xml
cd /usr/local
wget --no-check-certificate https://cdn.oolo.cc/source/jdk-8u341-linux-x64.tar.gz
wget --no-check-certificate https://cdn.oolo.cc/source/apache-maven-3.8.6-bin.tar.gz
tar zxvf jdk-8u341-linux-x64.tar.gz
tar zxvf apache-maven-3.8.6-bin.tar.gz
mv jdk1.8.0_341 jdk
mv apache-maven-3.8.6 maven
rm -f jdk-8u341-linux-x64.tar.gz
rm -f apache-maven-3.8.6-bin.tar.gz
cd /usr/local/maven/conf
rm -f settings.xml
wget --no-check-certificate https://cdn.oolo.cc/source/setting.xml
创建jenkins配置文件夹,创建jenkins镜像并启动容器,版本最好从官网查看最新版本,使用latest并不是最新版本,很多插件不支持低版本,插件下载会出现红叉等情况。
https://www.jenkins.io/download/
rm -rf /var/jenkins/
mkdir -p /var/jenkins/
chmod -R 777 /var/jenkins/
docker rm -f jenkins
docker run --name jenkins \
--restart=always \
-p 80:8080 \
-p 50000:50000 \
-v /var/jenkins/:/var/jenkins_home/ \
-v /usr/local/jdk:/usr/local/jdk \
-v /usr/local/maven:/usr/local/maven \
-e JENKINS_UC=https://mirrors.tuna.tsinghua.edu.cn/jenkins/ \
-e JENKINS_UC_DOWNLOAD=https://mirrors.tuna.tsinghua.edu.cn/jenkins/ \
-d jenkins/jenkins:2.396
docker logs -f jenkins
执行完上面的命令后,在最后会有一个初始密钥,在第一次进入jenkins的时候需要使用初始密钥进入,然后就是选择插件。
此时有两个选项 1.安装推荐的插件 2.选择插件来安装。
点击第二个,不需要任何修改,直接点继续
进入jenkins后,需要安装两个插件
1.Git Parameter:用于拉取git上的源代码
2.Publish Over SSH:将编译好的jar包通过ssh发送到目标服务器
安装过程:
配置jdk和maven:
容器中的jdk和maven是来自于宿主机挂载的目录,分别位于容器中/usr/local/jdk,/usr/local/maven
至此,gitlab和jenkins的创建和初始化就已经完成了。
Jenkins自动拉取构建(非Docker部署)
新建gitlab仓库
首先需要在gitlab中创建一个新项目,权限设置为公共(测试使用公共)
使用:git remote add origin http://gitlab.oolo.cc/root/webchat.git 添加远端仓库
然后add、commit后push将代码推送到gitlab,推送的时候报错
这是由于我们在创建gitlab容器的时候指定了gitlab的hostname为gitlab.oolo.cc,所以克隆地址都是gitlab.oolo.cc
解决方法:
1.可以在指定远程版本库的时候将gitlab.oolo.cc修改为gitlab的ip
比如:git remote add origin http://192.168.31.4/root/webchat.git
2.在本地hosts配置新增:192.168.31.4 gitlab.oolo.cc
Jenkins新建任务拉取代码
简单测试一下jenkins拉代码,打包是否正常
新建任务->选择构建一个自由风格的软件项目
需要修改的配置
1.源码管理->勾选git->填入git仓库地址(如果是私有仓库,需要添加用户名密码)
测试jenkins拉取代码是否成功
可以看到,在对应的目录下,代码已经拉取到本地了
Jenkins使用maven打包项目
接下来就需要使用maven进行打包
Build Steps -> 增加构建步骤 -> 执行shell
sh /usr/local/maven/bin/mvn package
查看对应目录下,已经构建出了jar包
添加目标服务器SSH
但是这个jar包只是保存在jenkins上,我们需要把他发送给其他服务器进行部署,这里就需要配置ssh了
首先进入首页点击 系统管理 -> 系统配置 -> 拉到最下方找到Publish over SSH -> 新增SSH Servers,填入接收jar包的服务器用户名、密码、jar包存放的路径,
发布jar包到目标服务器并运行
然后就是配置在构建完成后的操作了,其具体的流程为:将target和target文件夹下所有jar包发送到目标服务器上(之前配置了SSH的服务器)-> kill掉旧进程 -> 运行新进程
# kill进程名称为webChat-0.1的进程
ps -ef | grep webChat-0.1 | grep -v grep | awk '{print $2}' | xargs kill
# 后台运行webChat-0.1.jar(必须在末尾添加sleep 1)
nohup java -jar /usr/local/target/webChat-0.1.jar & sleep 1
可以看到192.168.31.3多了一个target文件夹,webChat-0.1.jar也已经从jenkins发送过来了,此时也正在运行
Jenkins自动拉取构建(Docker部署)
以上部署是直接将jar包部署到目标服务器,如果要在目标服务器上使用Docker进行部署,那么只需要修改构建后的配置即可。
新建Dockerfile
创建一个docker文件夹,创建一个Dockerfile文件
修改jenkins中构建后配置
1.如果我们使用Docker,就必须保证COPY的文件和Dockerfile是在同一级目录下,否则就会报错。
2.Docker存储库名称也必须小写,否则也会报错:
例如:docker build -t oolo/webChat:1.0 /usr/local/webchat
需要修改为 docker build -t oolo/webchat:1.0 /usr/local/webchat
系统管理 -> 系统配置 -> SSH Servers 将/usr/local修改为/usr/local/webchat
进入工程设置,图中的修改对应以下几个操作
1.Remove prefix为忽略target前缀,直接将target下的jar包发送到SSH设置指定目录,也就是/usr/local/webchat
2.删除之前直接部署在服务器上的命令,否则会导致端口冲突
3.点击Add Transfer Set,Remove prefix为忽略docker前缀,将docker目录下的所有文件发送到/usr/local/webchat
4.执行docker命令
docker build -t oolo/webchat:1.0 /usr/local/webchat
docker rm -f webchat
docker run -d -p 3333:3333 --name=webchat oolo/webchat:1.0
在部署完成后就可以看见目标服务器上新建的镜像和运行的容器了
安装部署Harbor镜像仓库
在之前的项目部署中,使用jenkins将构建好的代码通过 publish over ssh 插件推送到远程服务器进行部署,然后在远程服务器上进行镜像的构建以及容器的启动。那么如果是多台服务器就会比较耗时,这时采用在jenkins服务器上直接构建好镜像推送到镜像仓库,然后jenkins通知远程服务器直接去镜像仓库拉取镜像即可。
基于这种场景下,就可以使用harbor来统一管理镜像,主要流程为
jenkins推送jar包和Dockerfile到harbor服务器 -> harbor服务器构建过后push到harbor仓库 -> 目标服务器从harbor仓库拉取镜像
安装脚本:
# 卸载旧版本
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
# 安装新版本
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce-20.10.9 docker-ce-cli-20.10.9 containerd.io
# 启动Docker
sudo systemctl start docker
# 下载Docker Cmpose二进制文件
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 授予 Docker Compose 二进制文件执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证 Docker Compose 安装是否成功:
docker-compose --version
cd /usr/local
# 下载harbor
wget --no-check-certificate https://github.com/goharbor/harbor/releases/download/v1.10.14/harbor-offline-installer-v1.10.14.tgz
tar xzvf harbor-offline-installer-v1.10.14.tgz
修改Harbor核心配置文件harbor.yml
- hostname:192.168.31.6
- 注释掉 https.*
用户名:admin,默认密码:Harbor12345
安装Harbor
./install.sh
进入后创建一个新项目
在Harbor服务器(192.168.31.6)和目标服务器(192.168.31.3)新增镜像源
cat > /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://fskvstob.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.31.232:80"]
}
EOF
systemctl daemon-reload
systemctl restart docker
Jenkins实现CI持续集成
第一步,jenkins将jar包和Dockerfile推送到Harbor服务器,所以需要在jenkins配置Harbor服务器的SSH
进入 系统管理->系统配置 -> 新增SSH服务器
构建后操作 -> Add Server
添加harbor服务器构建后配置
流程:将target文件夹中的jar包和docker文件夹中的所有文件都发送到harbor服务器下的/usr/local/webchat文件夹下,然后执行以下脚本
# 构建镜像
docker build -t 192.168.31.6:80/public/webchat:1.0 /usr/local/webchat
# 登录到harbor
docker login -u admin -p Harbor12345 192.168.31.6:80
# 将镜像推送到harbor
docker push 192.168.31.6:80/public/webchat:1.0
修改工程配置中构建后顺序,因为jenkins需要先把Dockerfile和jar包发送给Harbor,harbor构建镜像过后再由目标服务器拉取镜像,所以需要Harbor执行顺序在目标服务器之前
拖拽该按钮至目标服务器配置之前
修改目标服务器构建后配置
流程:目标服务器只需要从harbor服务器拉取镜像,启动容器,不需要传输文件,只需要执行以下命令即可
docker rm -f webchat
docker run -d -p 3333:3333 --name=webchat 192.168.31.6:80/public/webchat:1.0
配置完成后点击立即构建,发现harbor和目标服务器上都出现了对应的镜像
Jenkins参数化构建实现多版本发布
可以看到,以上构建镜像的时候,版本号都是写死的,如果需要修改版本号,还得去jenkins对应的配置中修改版本号。我们希望的是版本号可以从git的tag标签动态的获取
在jenkins配置中配置tag环境变量,后续版本号通过$tag来获取
修改打包步骤,首先git checkout $tag切换到指定的标签,然后对该标签版本进行打包
注:切换标签操作必须在打包之前,否则将直接对当前master分支进行打包
将原先所有写死的版本号修改为$tag
修改pom.xml和Dockerfile
使用${version}代表版本号
使用sed命令,将Dockerfile中的${version}替换为tag版本号
sed -i 's/${version}/$tag/' /usr/local/webchat/Dockerfile
至此Jenkins参数化构建实现多版本发布就已经完成了。
在gitlab中新建一个标签,假如当前最新的版本为1.0.0,此时我新增了一些功能,那么版本就在原来的基础上+1,为1.0.1,首先修改pom.xml中的版本为1.0.1,然后推送到gitlab上,(注:我这里是直接推送到master分支,如果在公司里面需要等待自己的分支合并到master分支选择master分支创建tag或者将master分支合并到自己的分支以后再选择自己的分支创建tag),然后在gitlab中创建一个新的标签,版本也为1.0.1,然后保存,然后在jenkins中点击Build with Parameters(原立即构建),选择对应的版本号,就可以构建所对应的tag版本的jar包。通过选择不同的tag进行构建,在代码出现问题的时候,我们可以很方便的进行回滚。
同时,harbor中也出现了对应版本的镜像
Jenkins Pipeline流水线作业
以上我们创建任务都是通过自由风格创建的,所有的配置都是通过界面来进行配置,这种方式有两个缺点:1.配置麻烦。2.不易于管理
而Jenkins Pipeline流水线作业可以直接通过脚本来部署
新建一个任务名称->选择pipeline流水线创建
然后配置tag环境变量,后续版本号通过$tag来获取,这个步骤跟之前的步骤是相同的
然后就是编写流水线脚本了,流水线脚本可以根据图形界面动态生成
脚本生成器:http://192.168.31.5/job/webchat-pipeline/pipeline-syntax/
比如我需要配置git,那么我就选择:checkout:Check out from version control
下图为生成的脚本,stage为自己定义的当前步骤的名称,steps中的内容由脚本生成器生成
本质上跟我们之前的操作是一样的,只不过pipeline流水线是使用的脚本命令
pipeline {
agent any
stages {
stage('Pull SourceCode'){
steps{
checkout scmGit(branches: [[name: '$tag']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.31.4/root/webchat']])
}
}
stage('Maven Build'){
steps{
sh '/usr/local/maven/bin/mvn package'
}
}
stage('Publish Harbor Image'){
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'harbor', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo 0', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'target', sourceFiles: 'target/*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: '''sed -i \'s/${version}/$tag/\' /usr/local/webchat/Dockerfile
docker build -t 192.168.31.6:80/public/webchat:$tag /usr/local/webchat
docker login -u admin -p Harbor12345 192.168.31.6:80
docker push 192.168.31.6:80/public/webchat:$tag''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'docker', sourceFiles: 'docker/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('Run Container'){
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'target', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''docker rm -f webchat
docker run -d -p 3333:3333 --name=webchat 192.168.31.6:80/public/webchat:$tag''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
然后我们通过Build with Parameters,就可以进行发布了
发布的步骤与我们编写的脚本顺序是一致的
Gitlab托管Jenkinsfile
有时候我们希望能将脚本写在项目里面,而不是保存在Jenkins中,这时候就可以在项目中根目录创建一个Jenkinsfile文件,将我们之前的流水线脚本复制进去。
修改流水线配置,将Pipeline script
修改为Pipeline script from SCM
,然后配置git,最后指定流水线脚本文件,也就是Jenkinsfile,在配置完成后,Jenkins就会从git中获取Jenkinsfile配置
引入容器编排Kubernetes
利⽤Kubeode快速部署单节点K8S
Kudeode官网:https://gitee.com/q7104475/kubeode
Kudeode下载地址:
k8s-2022-04-15.tar
链接:https://cloud.189.cn/t/JRZrmiBFbeUj
(访问码:6cae)
下载完成后将压缩包上传至/usr/local目录,解压缩,并执⾏安装
tar xf k8s-2022-04-24.tar
cd k8s-2022-04-24
bash install.sh
选择第一个单机部署
然后等待安装完成即可
http://192.168.31.7:30080
⽤户名:admin
密码:Kuboard123
进入首页后点击添加集群,输入名称和描述后,其他操作无需修改,直接点击确定即可
然后复制该指令执行,安装Agent,等待导入,时间可能会比较长,待到纳管状态变为已就绪就代表导入完成
http://192.168.31.7:30000 为监控平台
为docker-daemon.json增加insecure-registries私有仓库
vim /etc/docker/daemon.json
添加insecure-registries私有仓库
{
"registry-mirrors": ["https://dockerhub.azk8s.cn","https://hub-mirror.c.163.com"],
"insecure-registries": ["192.168.31.6:80"],
"exec-opts": ["native.cgroupdriver=cgroupfs"],
"log-driver": "json-file",
"log-opts": {"max-size": "10m","max-file": "10"}
}
重载配置
sudo systemctl daemon-reload
sudo systemctl restart docker
若可以从harbor仓库拉取镜像则说明配置成功
创建K8S部署(Deployment)脚本
Deployment 介绍
为了更好地解决服务编排的问题,k8s在V1.2版本开始,引入了deployment控制器,值得一提的是,这种控制器并不直接管理pod,而是通过replicaset来间接管理pod,即:deployment管理replicaset,replicaset管理pod。所以deployment比replicaset的功能更强大
使用Harbor创建Deployment脚本
在Kuboard中default命名空间利用YAML创建部署
apiVersion: apps/v1 # 这是API版本
kind: Deployment # 这是资源类型
metadata:
name: webchat-deployment # 这是资源名称
spec:
# 这是副本数量
replicas: 2
selector:
matchLabels:
app: webchat-pod # 这是标签选择器
template:
metadata:
labels:
app: webchat-pod # 这是标签
spec:
containers:
- name: webchat # 这是容器名称
image: 192.168.31.6:80/public/webchat:1.1.0 # 这是容器镜像地址
ports:
- containerPort: 80 # 这是容器端口号
Kuboard还支持容器的动态伸缩,也就是可以控制容器的数量,也可以直接修改yaml中的replicas
通过命令的方式新增和运行Deployment脚本
在k8s主服务器上创建webchat-deployment.yml文件
mkdir /etc/k8s
cd /etc/k8s/
# 创建webchat-deployment.yml并写入脚本
cat > webchat-deployment.yml <<- 'EOF'
apiVersion: apps/v1 # 这是API版本
kind: Deployment # 这是资源类型
metadata:
name: webchat-deployment # 这是资源名称
spec:
# 这是副本数量
replicas: 2
selector:
matchLabels:
app: webchat-pod # 这是标签选择器
template:
metadata:
labels:
app: webchat-pod # 这是标签
spec:
containers:
- name: webchat # 这是容器名称
image: 192.168.31.6:80/public/webchat:1.1.0 # 这是容器镜像地址
ports:
- containerPort: 80 # 这是容器端口号
EOF
创建yml完成后通过kubectl apply -f /etc/k8s/webchat-deployment.yml启动脚本
# 选择webchat-deployment.yml配置启动脚本
kubectl apply -f /etc/k8s/webchat-deployment.yml
查看当前部署的pod
kubectl get pod
删除部署,执行后,所有pod都会进入Terminating状态,一段时间后被删除
kubectl delete deployment webchat-deployment
使用Harbor创建k8s服务(Service)脚本
很多Pod ⽹络插件的实现⽅式是将PodIP 作为私有IP地址,Pod 与Pod之间的通信是在⼀个私有⽹络中,因此要将Pod 中运⾏的服务发布出去,必然需要⼀个服务发布机制。
apiVersion: v1 # API版本
kind: Service # 资源类型
metadata: # 元数据
name: webchat-service # 名称
spec: # 规范
type: NodePort # Service类型
ports: # 暴露的端口和名称
- port: 3333 # 容器暴露的端口号
name: service-port # 端口名称
nodePort: 31005 # 外界访问的端口号,只能选取30000-32767范围的端口号
selector: # 所选择的Pod标签
app: webchat-pod # 标签名称
通过192.168.31.7:31005就可以访问容器中的3333端口了(多个容器由k8s自动进行负载均衡)
通过命令的方式新增和运行Service脚本
创建webchat-service.yml
cd /etc/k8s/
cat > webchat-service.yml <<- 'EOF'
apiVersion: v1 # API版本
kind: Service # 资源类型
metadata: # 元数据
name: webchat-service # 名称
spec: # 规范
type: NodePort # Service类型
ports: # 暴露的端口和名称
- port: 3333 # 容器暴露的端口号
name: service-port # 端口名称
nodePort: 31005 # 外界访问的端口号,只能选取30000-32767范围的端口号
selector: # 所选择的Pod标签
app: webchat-pod # 标签名称
EOF
通过命令创建Service
kubectl apply -f webchat-service.yml
运行提示当前这个service已经被创建了,这是因为我们刚才在Kuboard已经创建并运行了,所以我们可以删除当前service,重新创建即可
kubectl delete service webchat-service
Jenkins流水线驱动k8s持续部署、
使用k8s部署和使用docker的区别就是修改最后一个步骤,将docker启动容器的命令修改为k8s启动容器即可
在工程根路径下创建deployment.yml
apiVersion: apps/v1 # 这是API版本
kind: Deployment # 这是资源类型
metadata:
name: webchat-deployment # 这是资源名称
spec:
# 这是副本数量
replicas: 2
selector:
matchLabels:
app: webchat-pod # 这是标签选择器
template:
metadata:
labels:
app: webchat-pod # 这是标签
spec:
containers:
- name: webchat # 这是容器名称
image: 192.168.31.6:80/public/webchat:<TAG> # 这是容器镜像地址,TAG后续用于版本号切换
ports:
- containerPort: 80 # 这是容器端口号
---
apiVersion: v1 # API版本
kind: Service # 资源类型
metadata: # 元数据
name: webchat-service # 名称
spec: # 规范
type: NodePort # Service类型
ports: # 暴露的端口和名称
- port: 3333 # 容器暴露的端口号
name: service-port # 端口名称
nodePort: 31005 # 外界访问的端口号,只能选取30000-32767范围的端口号
selector: # 所选择的Pod标签
app: webchat-pod # 标签名称
Jenkins新增k8s Master服务器SSH
使用脚本生成器生成脚本语法
修改Jenkinsfile脚本中的最后一步
至此,Jenkins每次构建都会将deployment.yml发送给k8s服务器,然后再通过kubectl运行k8s容器
Gitlab Webhook自动版本发布
以上操作都需要我们手动在gitlab中创建tag后再通过Build with Parameters进行构建,
有没有办法当我们创建tag版本后Jenkins就自动进行构建?
可以通过gitlab的webhook机制实现,具体过程为,Jenkins提供一个地址,当访问这个地址的时候,Jenkins就会进行构建。当gitlab检测到有新的tag产生后,就自动调用Jenkins的接口
Jenkins新增Generic Webhook Trigger插件
安装完成后重启Jenkins,进入流水线配置,找到构建触发器,勾选Generic Webhook Trigger 保存
访问http://192.168.31.5/generic-webhook-trigger/invoke,就可以触发Jenkins构建任务,但是此时构建肯定是会失败的,因为我们通过访问url构建,并没有选择tag,也就是说,deployment.yml中的、\<TAG>并不会被替换。后面的内容再解决这个问题
设置gitlab允许Webhook和服务对本地网络的请求
进入我们自己的代码仓库,点击设置->Webhooks,写入Jenkins构建url,Secret令牌为验证,同时需要在Jenkins中配置一致的Token令牌
新建一个标签,测试是否可以触发构建,查看gitlab发送的参数,可以看到,gitlab发送的参数中包含我们需要的版本号,可以在Jenkins中解析获取版本号
该设置为解析json中的ref字段,并且去除refs/tags/,如果过滤后的结果为空,默认为1.0.0
我新创建一个版本号为1.1.9,对应Jenkins也可以通过解析获得1.1.9版本号
Helm:Kubernetes包管理工具
随着容器技术和微服务架构逐渐被企业接受,在Kubernetes上已经能便捷地部署简单的应⽤了。但对于复杂的应⽤或者中间件系统,在Kubernetes上进⾏容器化部署并⾮易事,通常需要研究Docker镜像的运⾏需求、环境变量等内容,为容器配置依赖的存储、⽹络等资源,并设计和编写Deployment、ConfigMap、Service、Volume、Ingress等YAML⽂件,再将其依次提交给Kubernetes部署。总之,微服务架构和容器化给复杂应⽤的部署和管理都带来了很⼤的挑战。Helm由Deis公司(已被微软收购)发起,⽤于对需要在Kubernetes上部署的复杂应⽤进⾏定义、安装和更新,是CNCF基⾦会的毕业项⽬,由Helm社区维护。Helm将Kubernetes的资源如Deployment、Service、ConfigMap、Ingress等,打包到⼀个Chart(图表)中,⽽Chart被保存到Chart仓库,由Chart仓库存储、分发和共享。Helm⽀持应⽤Chart的版本管理,简化了Kubernetes应⽤部署的应⽤定义、打包、部署、更新、删除和回滚等操作。简单来说,Helm通过将各种Kubernetes资源打包,类似于Linux的apt-get或yum⼯具,来完成复杂软件的安装和部署,并且⽀持部署实例的版本管理等,大大简化了在Kubernetes上部署和管理应用的复杂度。
安装helm
安装脚本
yum install -y wget
mkdir -p /usr/local/helm
cd /usr/local/helm
wget --no-check-certificate https://cdn.oolo.cc//source/helm-v3.10.0-linux-amd64.tar.gz
tar zxvf helm-v3.10.0-linux-amd64.tar.gz
mv -f linux-amd64/helm /usr/bin
helm镜像仓库站:https://artifacthub.io/
比如我现在需要安装nginx,那么就在helm镜像仓库站搜索nginx,点击install
# 添加一个名为bitnami的Helm仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
# 更新仓库中的 Charts 列表和元数据信息
helm repo update
# 移除my-nginx
helm uninstall my-nginx
#从远程 Helm 仓库中下载 Bitnami 的 Nginx chart,并将其安装到 Kubernetes 集群中
helm install my-nginx bitnami/nginx --version 13.2.32
helm list
# 查看my-nginx状态
helm status my-nginx
# 查看部署情况
kubectl get deploy
# 在部署后,可以使用set修改变量,比如这里是将my-nginx副本修改为3
helm upgrade my-nginx bitnami/nginx --version 13.2.10 --set replicaCount=3
k8s自动将41526端口转发到nginx容器的80端口
构建Helm私有仓库发布自定义Charts
私有仓库使用chartmuseum,一般来说需要单独的服务器,但是这里电脑内存有点不够了,我直接在192.168.31.3使用docker进行部署
进入服务器(192.168.31.3)
docker run --name chatmuseum \
-p 8080:8080 \
--restart=always \
-d bitnami/chartmuseum:0.15.0
在k8s服务器(192.168.31.7)创建/usr/local/charts目录
mkdir -p /usr/local/charts
cd /usr/local/charts
helm create webchat-charts
charts/
: 包含了 Chart 依赖的其他 Charts。这些 Charts 可以在安装 Chart 时自动下载和安装。Chart.yaml
: 包含 Chart 的元数据信息(例如名称、版本、作者、依赖关系等)。templates/
: 包含了 Kubernetes 对象的模板文件。这些模板文件使用 Go 的文本模板语言(Template)编写,并允许在部署期间动态地生成 Kubernetes 对象的 YAML 描述文件。values.yaml
: 包含了默认的 Helm 值,用于覆盖 Kubernetes 对象的默认值。这些值可以在安装 Chart 时通过--set
参数或通过外部值文件进行覆盖。
进入templates,删除所有文件,创建deployment.yaml和service.yaml
cat > deployment.yaml <<-'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: webchat-deployment
spec:
replicas: 2
selector:
matchLabels:
app: webchat-pod
template:
metadata:
labels:
app: webchat-pod
spec:
containers:
- name: webchat
image: 192.168.31.6:80/public/webchat:<TAG>
ports:
- containerPort: 80
EOF
cat > service.yaml <<-'EOF'
apiVersion: v1
kind: Service
metadata:
name: webchat-service
spec:
type: NodePort
ports:
- port: 3333
name: service-port
nodePort: 31005
selector:
app: webchat-pod
EOF
回到根目录,对当前目录构建压缩包
cd /usr/local/charts/webchat-charts
helm package .
向chatmuseums服务器上传Helm Chart
curl --data-binary "@webchat-charts-0.1.0.tgz" http://192.168.31.3:8080/api/charts
如果需要删除,可以执行以下命令
curl -X DELETE http://192.168.31.3:8080/api/charts/webchat-charts/0.1.0
安装我们自己的helm脚本
首先删除我们之前部署的webchat-deployment和webchat-service,保证后续操作不会出现冲突
helm uninstall webchat
kubectl delete deployment webchat-deployment
kubectl delete service webchat-service
增加一个仓库
# 删除原有的my-repo
helm repo remove my-repo
# 新增 my-repo
helm repo add my-repo http://192.168.31.3:8080/
# 查看当前仓库
helm repo list
# 对仓库缓存进行更新,保证每次获取到的仓库信息都是最新的,每次对仓库进行修改都应该先执行更新
helm repo update
# 查看我们上传的helm
helm search repo my-repo
使用helm脚本部署
helm install webchat my-repo/webchat-charts
基于Charts模板实现版本动态发布
重写Chart.yaml,修改生成的tgz的名称和版本号
cat -> /usr/local/charts/webchat-charts/Chart.yaml <<-'EOF'
apiVersion: v2
name: webchat-charts
description: A Helm chart for Kubernetes
type: application
version: 1.0.0
appVersion: stable
重写values.yaml,设置默认3个pod节点,版本号为1.0.0,对外暴露的节点为31005,这个为默认值,如果我们没有使用--set修改,那么默认deployment中的这些字段就使用的values.yaml中的值
cat > /usr/local/charts/webchat-charts/values.yaml <<-'EOF'
replicas: 3
tag: 1.0.0
nodePort: 31005
EOF
重写deployment.yaml
cat > /usr/local/charts/webchat-charts/templates/deployment.yaml <<-'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: webchat-deployment
spec:
replicas: {{.Values.replicas}}
selector:
matchLabels:
app: webchat-pod
template:
metadata:
labels:
app: webchat-pod
spec:
containers:
- name: webchat
image: 192.168.31.6:80/public/webchat:{{.Values.tag}}
ports:
- containerPort: 80
EOF
重写service.yaml
cat > /usr/local/charts/webchat-charts/templates/service.yaml <<-'EOF'
apiVersion: v1
kind: Service
metadata:
name: webchat-service
spec:
type: NodePort
ports:
- port: 80
name: service-port
nodePort: {{.Values.nodePort}}
selector:
app: webchat-pod
EOF
发布charts
curl -X DELETE http://192.168.31.3:8080/api/charts/webchat-charts/1.0.0
helm package .
curl --data-binary "@webchat-charts-0.1.0.tgz" http://192.168.31.3:8080/api/charts
运行
helm install webchat my-repo/webchat-charts --set replicas=2 --set tag=1.2.1
更新
helm upgrade webchat my-repo/webchat-charts --set replicas=1 --set tag=1.2.1
基于Helm实施Jenkins动态发布
前面我们的charts打包,发布都是在k8s服务器中进行的,规范的做法应该是在jenkins里面进行打包发布,然后在k8s服务器中进行install
将charts文件放到我们的项目根目录中
复制我们之前创建的流水线任务,命名为webchat-pipeline-k8s
然后进行配置,新增replicas和tag环境变量、tag之前已经创建了的话可以忽略
添加参数,选择字符参数,replicas,该配置可以让我们在手动部署的时候选择replicas
添加webhook参数配置,该配置可以在我们新增标签过后,生成一个replicas环境变量,默认值为2
流水线中新增Helm Build&Upload步骤
stage('Helm Build&Upload'){
steps {
sh 'curl -X DELETE http://192.168.31.3:8080/api/charts/webchat-charts/1.0.0'
sh 'helm package ./charts/webchat-charts'
sh 'curl --data-binary "@webchat-charts-1.0.0.tgz" http://192.168.31.3:8080/api/charts'
}
}
修改流水线配置
helm uninstall webchat
helm repo add my-repo http://192.168.31.3:8080/
helm repo update
helm install webchat my-repo/webchat-charts --set replicas=$replicas --set tag=$tag
将生成的流水线脚本覆盖Jenkinsfile中最后一步
到这里,基于Helm实施Jenkins动态发布就已经完成了
但是部署的时候出现了一个问题
这是因为Jenkins容器中没有安装Helm
yum install -y wget
mkdir -p /usr/local/helm
cd /usr/local/helm
wget --no-check-certificate https://cdn.oolo.cc//source/helm-v3.10.0-linux-amd64.tar.gz
tar zxvf helm-v3.10.0-linux-amd64.tar.gz
mv -f linux-amd64/helm /usr/bin
docker cp /usr/bin/helm jenkins:/usr/bin/helm
总结
总体思路如下
执行流程:
- IDEA推送代码的IDEA仓库,内含代码、Dockerfile、HelmCharts
- Gitlab接受到代码后,研发⼈员定义Tag,如配置WebHook,则⾃动触发Jenkins流⽔线
- 配置管理员、运维⼈员在Jenkins选择Tag,开始Jekins流⽔线。
a. Jenkins 从Gitlab checkout指定Tag的代码
b. Jenkins本地执⾏mvn package⽣成Jar包
c. Jenkins本地执⾏helm package⽣成helm-charts.tgz⽂件
d. Jenkins将Jar与Dockerfile发送到Harbor镜像服务器,先执⾏docker build构建镜像,再执⾏
docker push将镜像推送是Habor仓库
e. Jenkins将本地⽣成的helm-chart.tgz通过curl --data-binary 上传⾄Helm Museum私服
f. Jenkins远程连接到K8S Master执⾏helm install,K8S Master先拉取Helm Charts,再执⾏脚
本⾃动从Habor拉取Tag镜像,完整⾃动化发布流程
1 条评论
大佬好帅!!!