概述
DevOps 是一系列做法和工具,可以使 IT 和软件开发团队之间的流程实现自动化。其中,随着敏捷软件开发日趋流行,持续集成 (CI) 和持续交付 (CD) 已经成为该领域一个理想的解决方案。在 CI/CD 工作流中,每次集成都通过自动化构建来验证,包括编码、发布和测试,从而帮助开发者提前发现集成错误,团队也可以快速、安全、可靠地将内部软件交付到生产环境。
不过,传统的 Jenkins Master-Agent 架构(即多个 Agent 为一个 Master 工作)有以下不足。
如果 Master 宕机,整个 CI/CD 流水线会崩溃。 资源分配不均衡,一些 Agent 的流水线任务 (Job) 出现排队等待,而其他 Agent 处于空闲状态。 不同的 Agent 可能配置环境不同,并需要使用不同的编码语言。这种差异会给管理和维护带来不便。
了解 KubeSphere DevOps
KubeSphere DevOps 工程支持源代码管理工具,例如 GitHub、Git 和 SVN。用户可以通过图形编辑面板 (Jenkinsfile out of SCM) 构建 CI/CD 流水线,或者从代码仓库 (Jenkinsfile in SCM) 创建基于 Jenkinsfile 的流水线。
KubeSphere CI/CD 流水线工作流
KubeSphere CI/CD 流水线基于底层 Kubernetes Jenkins Agent 而运行。这些 Jenkins Agent 可以动态扩缩,即根据任务状态进行动态供应或释放。Jenkins Master 和 Agent 以 Pod 的形式运行在 KubeSphere 节点上。Master 运行在其中一个节点上,其配置数据存储在一个存储卷 (Volume) 中。Agent 运行在各个节点上,但可能不会一直处于运行状态,而是根据需求动态创建并自动删除。
当 Jenkins Master 收到构建请求,会根据标签动态创建运行在 Pod 中的 Jenkins Agent 并注册到 Master 上。当 Agent 运行完任务后,将会被释放,相关的 Pod 也会被删除。
动态供应 Jenkins Agent
动态供应 Jenkins Agent 有以下优势: 资源分配合理:KubeSphere 动态分配已创建的 Agent 至空闲节点,避免因单个节点资源利用率高而导致任务排队等待。 高可扩缩性:当 KubeSphere 集群因资源不足而导致任务长时间排队等待时,您可以向集群新增节点。 高可用性:当 Jenkins Master 故障时,KubeSphere 会自动创建一个新的 Jenkins Master 容器,并将存储卷挂载至新创建的容器,保证数据不会丢失,从而实现集群高可用。
DevOps 开发
启用 DevOps
- 以 admin 身份登录控制台,点击左上角的平台管理,选择集群管理。
2.点击自定义资源 CRD,在搜索栏中输入 clusterconfiguration,点击搜索结果查看其详细页面。
3.在资源列表中,点击 ks-installer 右侧的
,选择编辑配置文件。
4.在该 YAML 文件中,搜寻到 devops,将 enabled 的 false 改为 true。完成后,点击右下角的更新,保存配置
5.然后输入以下命令查看安装日志
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f
6.出现此界面即为安装成功
集成SonarQube
1.请先安装 Helm,以便后续使用该工具安装 SonarQube。例如,运行以下命令安装 Helm 3:
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
2.安装sonarqube服务器
helm upgrade --install sonarqube sonarqube --repo https://charts.kubesphere.io/main -n kubesphere-devops-system --create-namespace --set service.type=NodePort
3.执行以下命令获取sonarqube服务器地址
export NODE_PORT=$(kubectl get --namespace kubesphere-devops-system -o jsonpath="{.spec.ports[0].nodePort}" services sonarqube-sonarqube)
export NODE_IP=$(kubectl get nodes --namespace kubesphere-devops-system -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
4.查看SonarQube pod 状态,待全部安装完成功运行后访问服务器,然后使用admin/admin账户密码登录
5.依次点击 MyAccount->security->generate 生成token复制并保留
6.获取 Jenkins 的 SonarQube Webhook 地址
export NODE_PORT=$(kubectl get --namespace kubesphere-devops-system -o jsonpath="{.spec.ports[0].nodePort}" services ks-jenkins)
export NODE_IP=$(kubectl get nodes --namespace kubesphere-devops-system -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT/sonarqube-webhook/
7.依次点击 Administration、Configuration 和 Webhooks 创建一个 Webhook。
8.将 SonarQube 配置添加到 ks-installer (参考步骤四中截图的sonarqube配置)
9.登录Jenkins,账号密码同kubesphere (地址获取参考步骤6 去掉后缀)
10.点击 系统管理-> 系统配置-> 找到 SonarQube Servers 一栏
添加凭证,secret 输入步骤5生成号的token, 类型选择Secret text ,ID 自定义。随后填写sonarqube 服务信息
11.将 sonarqubeURL 添加到 KubeSphere 控制台,就可以直接通过控制台直接跳转到sonarqube
#执行命令 添加sonarqube 地址并保存
kubectl edit cm -n kubesphere-system ks-console-config
12.重启ks-apiserver和ks-console
kubectl -n kubesphere-system rollout restart deploy ks-apiserver
kubectl -n kubesphere-system rollout restart deploy ks-console
集成流水线
1.使用kubesphere 创建企业空间,创建企业空间管理员,项目管理员,项目开发员,参考kubesphere.com.cn/docs/quick-…
2.使用项目管理员创建一个devOps项目
3.点击项目创建流水线,在参数化构建地方加三个String参数。分别是 REGISTRY docker 镜像仓库地址,DOCKERHUB_NAMESPACE docker仓库名称空间,APP_NAME 项目名称
4.凭证的添加,在devops工程下面创建凭证
git账号和dockerhub账户都属于账户凭证一类,输入账号密码即可。sonarqube则需要选择秘密文本类型,将之前保存的token粘贴即可。
5.点击流水线进入其详情页面。要使用图形编辑面板,请点击流水线选项卡下的编辑流水线。在弹出对话框中,点击**自定义流水线,进行编辑。**或者编辑jenkinsfile。下面用jenkinsfile示例: jenkins流水线语法传送门
pipeline {
agent { # 指示 Jenkins 为整个流水线分配一个执行器(在 Jenkins 环境中的任何可用代理/节点上)和工作区
node {
label 'maven' # 整个流水线将会运行在标签为maven的节点上
}
}
stages {
stage('Checkout SCM') { # 拉取代码,需要携带id为gitee-id的凭证信息
agent none
steps {
git(url: 'https://gitee.com/xxx.git', credentialsId: 'gitee-id', branch: 'master', changelog: true, poll: false)
}
}
stage('Unit Test') { #执行单元测试
steps {
container('maven') { # 指定容器
sh 'mvn clean -o -gs `pwd`/configuration/settings.xml test' #在指定容器下执行shell脚本
}
}
}
stage('Code Analysis') { #执行代码分析
steps {
container('maven') {
withCredentials([string(credentialsId : 'sonar-token' ,variable : 'SONAR_TOKEN' ,)]) {
withSonarQubeEnv('sonar') { #携带凭证 使用sonar环境 执行脚本
sh 'mvn sonar:sonar -o -gs `pwd`/configuration/settings.xml -Dsonar.login=$SONAR_TOKEN'
}
}
timeout(unit: 'HOURS', activity: true, time: 1) { # 无日志输出后开始计算超时时间
waitForQualityGate 'true' #等待质量分析是否影响后续业务继续进行
#代码质量检查标准来源于SonarQube的 Quality Gate (质量阈),如果需要自定义检查标准请前往 SonarQube 设置
}
}
}
}
stage('Build and Push') { # 构建并发布
agent none
steps {
container('maven') { #根据dockerFile构建镜像并push到远端仓库
sh 'mvn -o -Dmaven.test.skip=true -gs `pwd`/configuration/settings.xml clean package'
sh 'docker build -f Dockerfile-online -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER .'
withCredentials([usernamePassword(credentialsId : 'dockerhub-id' ,passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME' ,)]) {
sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
}
sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'
}
}
}
stage('update-yml') { #更新deployment的部署文件中容器镜像为刚刚push的
agent none
steps {
container('maven') {
sh 'sed -i "s/\\$REGISTRY\\/\\$DOCKERHUB_NAMESPACE\\/\\$APP_NAME:\\$TAG_NAME/\\"$REGISTRY\\/$DOCKERHUB_NAMESPACE\\/$APP_NAME:SNAPSHOT-$BUILD_NUMBER\\"/g" `pwd`/deploy/prod-ol/devops-sample.yaml'
}
}
}
stage('Artifacts') { #保存构建的jar包到项目构建空间下
steps {
archiveArtifacts 'target/*.jar'
}
}
stage('Deploy to Dev') { #部署到dev
agent none
steps {
input '是否部署至dev环境' # 提示用户,如果同意stage会继续
container('maven') {
sh '''kubectl apply -f `pwd`/deploy/prod-ol/devops-sample.yaml
kubectl apply -f `pwd`/deploy/prod-ol/devops-sample-svc.yaml'''
}
}
}
}
}
6.运行流水线
查看日志
7.查看代码分析
8.查看工作负载
查看部署成功的应用
返回上层查看服务,查看暴露端口并进行访问
访问成功!
9.也可登录Jenkins查看构建