环境准备
软件版本
软件 | 版本 |
---|---|
gitlab | 14.3.0 |
Jenkins | 2.303.1 |
Harbor | 1.10.2 |
Sonar | 9.1 |
Nexus | 3.35.0-02 |
ArgoCD | 2.1.3 |
部署gitlab
1 | docker run --detach --hostname 10.8.242.28 --publish 443:443 --publish 80:80 --publish 1022:22 --name gitlab --restart always --volume /srv/gitlab/config:/etc/gitlab --volume /srv/gitlab/logs:/var/log/gitlab --volume /srv/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce:12.10.3-ce.0 |
替换hostname为实际节点外网IP
部署Harbor
Harbor部署与管理
部署前先修改docker
编辑docker
1 | vim /etc/docker/daemon.json |
重启docker
1 | systemctl restart docker |
安装docker-compose
1 | curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose |
下载harbor
1 | https://github.com/goharbor/harbor/releases/download/v1.10.2/harbor-online-installer-v1.10.2.tgz |
配置harbo.yaml
1 | hostname: 172.31.48.86 //修改为实际节点IP |
屏蔽https配置
安装harbor
1 | ./install.sh --with-clair |
1 | docker-compose ps |
admin/Harbor12345
创建测试项目
spring-petclinic官方示例项目地址:https://projects.spring.io/spring-petclinic/
本次实践针对Spring官方提供的spring-petclinic示例项目进行容器化部署,该项目采用Spring Boot + Thymeleaf开发,数据库可使用MySQL、H2等,本实践为操作方便直接使用内置的H2数据库。
注意:由于本实践采用的是H2内置数据库,所以每个应用实例的数据独立,也使得应用变成了有状态应用,而生产的最佳实践应该是数据采用外部存储,且应用采用无状态方式部署。
国内clone地址:https://gitee.com/wanshaoyuan/spring-petclinic.git
将此项目clone后上传到私有的gitlab中.
与Gitlab集成
安装gitlab插件
Gitlab中申请AccessToken
将申请成功的token保存好
配置Jenkins对接gitlab
添加凭证
测试连接
测试
读取gitlab中项目spring-petclinic项目中pom.xml文件
配置连接gitlab私有项目的密钥可以用ssh密钥也可以使用账号密码
分支处修改为main分支
构建
去cat这个文件输出内容
执行立即构建
输出结果为实际我们的pom.xml的文件内容
与Kubernetes集成构建分布式动态编译环境
安装Kubernetes插件
Jenkins与Kubernetes集成实现动态Slave Pod,需要安装Kubernetes插件:
- kubernetes
安装Kubernetes Continuous Deploy插件
Jenkins访问kubernetes需要依赖于kubeconfig,为支持kubeconfig类型的凭据配置,需要安装Kubernetes Continuous Deploy插件:
- Kubernetes Continuous Deploy
配置Kubernetes集群
配置 系统管理—>系统设置—>新增一个云
配置Jenkins URL,这里可以不配置api-server地址和证书key,连接kubernetes,所以默认会去读取放在JENKINS_HOME的.kube/目录的kubeconfig文件,用于连接集群。我这里是通过安装包的方式安装的Jenkins HOME在/var/lib/jenkins/目录,如果是通过容器方式启动,将kubeconfig文件直接放~/.kube/目录。
保存到Jenkins主机的config文件中
复制粘贴到Jenkins容器内的~/.kube/config文件中
1 | docker exec -it jenkins mkdir /root/.kube/ |
注意:
此方式Jenkins容器重启后,会将目录重新初始化覆盖掉,kubeconfig文件,生产环境可以直接挂载。
验证Pipeline流水线
以上Jenkins与Kubernetes的集成配置就基本完成了,下面在正式为Spring Petclinic应用创建Pipeline之前,先简单测试下Jenkins与Kubernetes集成Pipeline流水线是否正常。
- 新建一个流水线类型的任务test-hello-pipeline
- 准备流水线测试脚本
1 | pipeline { |
以上是一个简单的声明式pipeline,利用busybox镜像输出hello world
字符串。
- 添加流水线脚本
把测试脚本添加到任务的流水线脚本框中:
- 保存流水线,并执行构建
- 查看JOB运行结果
在Kubernetes中可以看到Jenkins自动创建了Pod来执行任务,任务执行完成以后,Pod自动删除。
Jenkins中查看下构建的控制台输出,正常输出了hello world
:
验证结果表明,Jenkins与Kubernetes配置成功,Pipeline运行正常。
Sonar-Qube对接实现代码质量扫描
安装sonarqube
初始化
1 | helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube |
helm安装sonarqube
1 | helm install sonarqube --namespace sonarqube sonarqube/sonarqube --set postgresql.persistence.enabled=false |
注意:这里为了快速部署没有设置postgresql的持久化存储,有数据丢失风险,生产环境postgresql建议设计HA或持久化存储。
设置为NodePort对外暴露
1 | kubectl patch svc sonarqube-sonarqube -p '{"spec": {"type": "NodePort"}}' -n sonarqube |
查看NodePort端口
1 | kubectl get svc -n sonarqube |
查看启动成功
1 | kubectl get pod -n sonarqube |
访问节点的30005端口
默认密码admin/admin
如果需要中文直接安装插件就好
administrator—->Marketplace
搜索Chinese—-安装
生成token
申请token
administrator—>security—>user—>token
保存生成token
Jenkins配置
安装插件
系统设置—>插件管理
安装SonarQube Scanner for Jenkins
配置插件
配置sonarQube-server
Server URL填写sonarqube的地址
Server authentication token填写刚刚创建的token,这里创建一个密钥
类型为Secret Text。Secret填写token详细信息,ID为此secret的名称
配置sonarQUbe-agent
系统管理->全局工具配置——>SonarQube Scanner
此处配置为自动安装
FreeStyle风格任务下配置SonarQube
以上面的test-gitlab项目的spring-petclinic为例
先执行maven构建出class文件,在进行扫描,因为sonarQube扫描的对象是.class而不是.java文件。
1 | docker run -i -v /var/jenkins_home/workspace/:/tmp maven:3.6-jdk-8 mvn -f /tmp/spring-petclinic/pom.xml clean package -DskipTests |
在构建阶段添加”Execute SonarQube Scanner”
输入以下内容
1 | sonar.projectKey=test |
注:
sonar.projectKey=Test #sonar那显示project-key
sonar.projectName=Test #sonar那显示project名字
sonar.projectVersion=1.0 ##sonar那显示project版本
sonar.sources=src #指定要扫描的源码目录。
sonar.java.binaries=target/classes #指定java文件编译后class文件目录。
sonar.language=java #只扫描的语言。
sonar.sourceEncoding=UTF-8 #指定源码的编码格式,一般都会去指定为UTF-8。
执行构建
Jenkins处查看
sonar处查看
Jenkins-Pipeline风格任务下配置SonarQube
使用Pipeline流水线,需要在添加以下步骤
1、在对应的代码库的根目录创建sonar-project.properties
1 | sonar.projectKey=test2 |
Pipeline中添加以下步骤
Pipeline中添加以下步骤
1 | stage('SonarQube analysis') { |
注:
1、SonarQubeScanner为全局工具配置中的SonarQube Scanner的配置名称。
2、withSonarQubeEnv配置的sonar变量为全局——>系统配置sonar-server的配置名称
清空workspace
1 | rm -rf /var/jenkins_home/workspace/spring-petclinic |
Sonattype-Nexus
Nexus是开源的制品库,可以用来存储一些代码构建后的制品如jar包,npm包和docker镜像等。也可以将存放制品后的仓库做为私服,供给给后面需要内网编译的软件使用。
部署安装
软件版本:3.35.0-02
本次部署为了更加方便和快捷,采用Docker方式部署
创建目录
1 | mkdir /var/nexus-data && chown -R 200 /var/nexus-data |
Docker运行
1 | docker run -d -p 8081:8081 --name nexus -v /var/nexus-data:/nexus-data sonatype/nexus3 |
初始账号和密码访问
账号:admin
密码:
1 | cat /var/nexus-data/admin.password |
创建仓库
仓库分为三种类型,proxy、group、hosted。
Proxy:Repository是代理仓库,可以配置上游仓库地址,如阿里云仓库地址。当本地仓库不到时,去向配置的上游仓库查找。
hosted:供本地使用的本地仓库。
group:仓库组,将多个仓库合成一个组,查找jar包时,会按照仓库组中的仓库顺序下载jar包。
这里创建两个名为spring-petclinic-releases、spring-petclinic-snapshots,类型为hotsted的Maven2仓库。
releases库主要用于存储正式版的制品,snapshots存储持续集成过程中产生的制品。
这里可以根据情况进行修改为release或snapshots
maven处配置
在spring-petclinic目录下创建conf/settings.xml文件用于存放连接Nexus3的凭证信息,正常可以在maven_home或~/.m2/目录有这文件。因为这里是使用Docker进行构建编译,所以这里直接与业务代码放置在一起。
settings.xml文件
1 | <?xml version="1.0" encoding="UTF-8"?> |
关闭https检测,因为Nexus3使用的是http方式对外暴露所以需要关闭maven构建时强行要求https链接
src/checkstyle/nohttp-checkstyle.xml
注释<module name="io.spring.nohttp.checkstyle.check.NoHttpCheck"/>
注释后:<!-- <module name="io.spring.nohttp.checkstyle.check.NoHttpCheck"/> -->
pom.xml文件添加以下内容
1 | <distributionManagement> |
执行编译
1 | docker run -i -v /root/spring-petclinic/:/tmp maven:3.6-jdk-8 mvn -f /tmp/pom.xml --settings /tmp/conf/settings.xml clean deploy |
编译完成上传成功后
在spring-petclinic-snapshots仓库内可见上传来的jar包,对应的jar包后面也接上了对应的时间戳,方便进行分类。
如果要上传到release仓库,将pom.xml中的<version>2.5.0-SNAPSHOT</version>
中的-SNAPSHOT
字段删除就表示为正式版。
ArgoCD集成实现CD端对接
编写并上传部署spring-petclinic的yaml文件和Dockerfile文件
1 | apiVersion: apps/v1 |
将yaml中的镜像地址改为实际的镜像仓库地址和项目名称。
Dockerfile
1 | FROM registry.cn-shenzhen.aliyuncs.com/yedward/openjdk:8-jre-slim |
上传到gitlab中的spring-petclinic项目中
部署ArgoCD
单节点部署
使用官网快速部署
1 | kubectl create namespace argocd |
部署完后产生以下服务
1 | NAME READY STATUS RESTARTS AGE |
使用NodePort方式为对外暴露
1 | kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}' |
访问dashboard
默认帐号为admin,密码通过secret获取
1 | kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d |
配置ArgoCD
配置对接gitlab
setting——>Repositories->Connect repo using HTTPS
如果对应的git是私有库,pull需要帐号密码则需要在argo设置中配置repo connect
填写对应的帐号密码,如果是自签名证书需要将CA附上
创建Project
setting——>Projects
项目是argocd中的管理对象,也与之对应的发布权限相关联。
创建项目,并配置DESTINATIONS,能够发布到哪些集群和命名空间
创建Application
创建完后
点击sync会自动将yaml文件部署到k8s集群中。
可以在Kubernetes集群中查看到
1 | kubectl get pod |
Harbor中创建对应项目
在harbor中创建spring-petclinic项目
gitlab Webhook配置
当前Jenkins进行CI构建还是基于手动点击运行,可以配置基于gitlab的触发事件进行调用,如push、merge、tag push等事件触发回调Jenkins自动执行CI
jenkins处打开项目触发器
生成连接Secret token保存下来
Gitlab配置:
root登录后,需要开放安全配置,允许本地local网络连接
在menu选择admin——>settings-——>Network——>Outbound requests
勾选
1 | Allow requests to the local network from web hooks and services |
将Jenkins的ip添加到白名单中,保存。
项目——>setting——>webhooks
填写Jenkins对应的回调地址和token
点击Test settings即可在Jenkins处看见已经开始的构建任务。
保存配置
test这里选择基于事件回调。查看Jenkins处是否开始自动执行任务。
Jenkins配置
Argo是检查到yaml文件变化会进行自动发布到k8s中,那么我们只需要在Jenkins中增加修改和上传yaml阶段即可。
完整的构建阶段shell
编译阶段shell
1 | docker run -i -v /var/jenkins_home/workspace/:/tmp maven:3.6-jdk-8 mvn -f /tmp/spring-petclinic/pom.xml clean package -DskipTests |
代码扫描阶段
1 | sonar.projectKey=test |
镜像构建阶段
1 | docker login -u useradmin -p password harbor_ip |
注:
1、这里使用Jenkins内置BUILD_NUMBER号为镜像tag,跟Jenkins的CI号是匹配的。
2、将上传镜像的账号密码修改为实际的账号密码。
发布更新部署yaml阶段
1 | git clone http://username:password@1.13.173.7/root/spring-petclinic.git |
在配置一个构建后删除操作,避免构建后缓存影响下次构建
执行构建,构建成功后查看对应的k8s中的部署的业务镜像版本号是否与实际应用部署的环境变量相同。
1 | kubectl describe pod/spring-petclinic-0-0-1-699954b589-h7n58 |
访问节点ip+spring-petclinic服务暴露出来的NodePort端口
这是一个宠物医院的管理系统,可以通过此页面进行宠物管理。
备注
Jenkins内置环境变量
直接访问${YOUR_JENKINS_HOST}/env-vars.html即可
1 | BUILD_NUMBER, 唯一标识一次build,例如23; |