什么是CICD
为什么需要CICD
一、部署Harbor仓库
(1)基础准备
解压软件包:
[root@master ~]# tar -zxf BlueOcean.tar.gz
(2)部署Harbor
安装Docker Compose:
[root@master ~]# cp BlueOcean/tools/docker-compose-Linux-x86_64 /usr/bin/docker-compose
[root@master ~]# docker-compose version
docker-compose version 1.25.0, build 0a186604
docker-py version: 4.1.0
CPython version: 3.7.4
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
安装Harbor仓库:
[root@master ~]# tar -zxf BlueOcean/harbor-offline-installer.tar.gz -C /opt/
[root@master ~]# sh /opt/harbor/install.sh
部署完成后Harbor镜像仓库默认用户为admin,密码为Harbor12345。
(3)访问Harbor
在Web端使用火狐浏览器登录Harbor(http://master),登录成功后如图所示:
新建springcloud项目,访问级别设置为公开,如图所示:
创建完成后如图4所示:
上传镜像到Harbor(IP为master节点地址):
[root@master ~]# docker login -uadmin -pHarbor12345 10.26.15.244
[root@master ~]# docker load -i BlueOcean/images/maven_latest.tar
[root@master ~]# docker tag maven 10.26.15.244/library/maven
[root@master ~]# docker push 10.26.15.244/library/maven
[root@master ~]# docker load -i BlueOcean/images/java_8-jre.tar
[root@master ~]# docker load -i BlueOcean/images/jenkins_jenkins_latest.tar
[root@master ~]# docker load -i BlueOcean/images/gitlab_gitlab-ce_latest.tar
二、部署Jenkins
(1)安装Jenkins
新建命名空间:
[root@master ~]# kubectl create ns devops
部署Jenkins需要使用到一个拥有相关权限的serviceAccount,名称为jenkins-admin,可以给jenkins-admin赋予一些必要的权限,也可以直接绑定一个cluster-admin的集群角色权限,此处选择给予集群角色权限。编写Jenkins资源清单文件:
[root@master ~]# vi jenkins-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: jenkins
labels:
app: jenkins
spec:
type: NodePort
ports:
- name: http
port: 8080
targetPort: 8080
nodePort: 30880
- name: agent
port: 50000
targetPort: agent
nodePort: 30850
selector:
app: jenkins
┅ # 此三横请手动输入,不要复制
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
labels:
app: jenkins
spec:
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccountName: jenkins-admin
containers:
- name: jenkins
image: jenkins/jenkins:latest
imagePullPolicy: IfNotPresent
securityContext:
runAsUser: 0
privileged: true
ports:
- name: http
containerPort: 8080
volumeMounts:
- mountPath: /var/jenkins_home
name: jenkinshome
- mountPath: /usr/bin/docker
name: docker
- mountPath: /var/run/docker.sock
name: dockersock
- mountPath: /usr/bin/kubectl
name: kubectl
- mountPath: /root/.kube
name: kubeconfig
volumes:
- name: jenkinshome
hostPath:
path: /home/jenkins_home
- name: docker
hostPath:
path: /usr/bin/docker
- name: dockersock
hostPath:
path: /var/run/docker.sock
- name: kubectl
hostPath:
path: /usr/bin/kubectl
- name: kubeconfig
hostPath:
path: /root/.kube
┅ # 此三横请手动输入,不要复制
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: jenkinshome
annotations:
volume.beta.kubernetes.io/storage-class: local-path
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1024Mi
┅ # 此三横请手动输入,不要复制
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-admin
labels:
name: jenkins
┅ # 此三横请手动输入,不要复制
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins-admin
labels:
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins-admin
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
这里通过NodePort的形式来暴露了Jenkins的8080端口,另外还需要暴露一个agent的端口,这个端口主要用于Jenkins的Master和Slave之间的通信。
部署Jenkins:
[root@master ~]# kubectl -n devops apply -f jenkins-deploy.yaml
查看Pod:
[root@master ~]# kubectl -n devops get pods
NAME READY STATUS RESTARTS AGE
jenkins-cc97fd4fc-v5dh2 1/1 Running 0 21s
(2)访问Jenkins
查看Jenkins Service端口:
[root@master ~]# kubectl -n devops get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jenkins NodePort 192.96.215.194 <none> 8080:30880/TCP,50000:30850/TCP 47s
在Web端使用浏览器访问Jenkins(http://master:30880),如图所示:
获取Jenkins密码:
[root@master ~]# kubectl -n devops exec deploy/jenkins -- cat /var/jenkins_home/secrets/initialAdminPassword
a3ac7ba3812746d0bc8ed40e122ba20b
输入密码后单击“继续”按钮,如图所示:
将离线插件包拷贝到Jenkins:
[root@master ~]# kubectl -n devops cp BlueOcean/plugins/ jenkins-cc97fd4fc-v5dh2:/var/jenkins_home
重启Jenkins:
[root@master ~]# kubectl -n devops rollout restart deployment jenkins
刷新Jenkins页面,选择“跳过插件安装”,安装完成后进入用户创建页面,创建一个用户jenkins,密码000000,如图所示:
单击“保存并完成”按钮,如图所示:
单击“保存并完成”,如图所示:
单击“开始使用Jenkins”按钮并使用新创建的用户登录Jenkins,如图所示:
三、部署Gitlab
GitLab是利用Ruby on Rails一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。与GitHub类似,GitLab能够浏览源代码,管理缺陷和注释,可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库,团队成员可以利用内置的简单聊天程序(Wall)进行交流。GitLab还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。
本项目GitLab与Harbor共用一台服务器。
(1)部署GitLab
编写GitLab资源清单文件:
[root@master ~]# vi gitlab-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: gitlab
spec:
type: NodePort
ports:
- port: 443
nodePort: 30443
targetPort: 443
name: gitlab-443
- port: 80
nodePort: 30888
targetPort: 80
name: gitlab-80
selector:
app: gitlab
┅ # 此三横请手动输入,不要复制
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitlab
spec:
selector:
matchLabels:
app: gitlab
revisionHistoryLimit: 2
template:
metadata:
labels:
app: gitlab
spec:
containers:
- image: gitlab/gitlab-ce:latest
name: gitlab
imagePullPolicy: IfNotPresent
env:
- name: GITLAB_ROOT_PASSWORD # 设置root用户密码
value: admin@123
- name: GITLAB_PORT
value: "80"
ports:
- containerPort: 443
name: gitlab-443
- containerPort: 80
name: gitlab-80
部署GitLab:
[root@master ~]# kubectl -n devops apply -f gitlab-deploy.yaml
查看Pod:
[root@master ~]# kubectl -n devops get pods
NAME READY STATUS RESTARTS AGE
gitlab-645dd88cd7-6vv2q 1/1 Running 0 29s
jenkins-cc97fd4fc-kmjtl 1/1 Running 0 7m20s
查看GitLab Service:
[root@master ~]# kubectl -n devops get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gitlab NodePort 192.104.250.77 <none> 443:30443/TCP,80:30888/TCP 57s
jenkins NodePort 192.98.107.152 <none> 8080:30880/TCP,50000:30850/TCP 7m48s
GitLab启动较慢,可以通过“kubectl logs”查看其启动状态。启动完成后,在Web端访问GitLab(http://master:30888),如图所示:
登录GitLab,如图所示:
(2)创建项目
单击“New project”按钮,如图所示:
单击“Create blank project”按钮创建项目springcloud,可见等级选择“Public”,如图所示:
单击“Create project”按钮,进入项目,如图所示:
push源代码到GitLab的springcloud项目:
[root@master ~]# cd BlueOcean/springcloud/
[root@master springcloud]# git config --global user.name "administrator"
[root@master springcloud]# git config --global user.email "admin@example.com"
[root@master springcloud]# git remote remove origin
[root@master springcloud]# git remote add origin http://10.26.10.143:30888/root/springcloud.git
[root@master springcloud]# git add .
[root@master springcloud]# git commit -m "initial commit"
# On branch master
nothing to commit, working directory clean
[root@master springcloud]# git push -u origin master
Username for 'http://10.26.10.143:30888': root
Password for 'http://root@10.26.15.244:30888':
Counting objects: 3192, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (1428/1428), done.
Writing objects: 100% (3192/3192), 1.40 MiB | 1.70 MiB/s, done.
Total 3192 (delta 1233), reused 3010 (delta 1207)
remote: Resolving deltas: 100% (1233/1233), done.
remote:
remote: To create a merge request for master, visit:
remote: http://gitlab-6778c45f9-xx5gs/root/springcloud/-/merge_requests/new?merge_request%5Bsource_branch%5D=master
remote:
To http://10.26.15.244:30888/root/springcloud.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
刷新网页,springcloud项目master分支中的文件已经更新了(使用火狐浏览器打开网页),如图所示:
四、配置Jenkins连接GitLab
(1)设置Outbound requests
登录Gitlab管理员界面(http://master:30888/admin),如图所示:
在左侧导航栏选择“Settings→Network”,设置“Outbound requests”,勾选“Allow requests to the local network from web hooks and services”复选框,如图所示:
配置完成后保存。
(2)创建GitLab API Token
单击GitLab用户头像图标,如图所示:
在左侧导航栏选择“Preferences”,如图所示:
在左侧导航栏选择“Access Tokens”添加Token,如图所示:
单击“Create personal access token”按钮生成Token,如图所示:
记录下Token(U6p_ubRixGSdRvs6MGft),后面配置Jenkins时会用到。
(3)设置Jenkins
登录Jenkins首页,选择“系统管理→系统配置”,配置GitLab信息,取消勾选“Enable authentiviion for ‘/project’ end-point”,输入“Connection name”和“Gitlab host URL”,如图所示:
添加Credentials,单击“添加”→“Jenkins”按钮添加认证信息,将Gitlab API Token填入,如图所示:
选择新添加的证书,然后单击“Test Connection”按钮,如图所示:
返回结果为Success,说明Jenkins可以正常连接GitLab。
五、配置Jenkinsfile
1)新建任务
登录Jenkins首页,新建任务springcloud,任务类型选择“流水线”,如图所示:
单击“确定”按钮,配置构建触发器,如图所示:
记录下GitLab webhook URL的地址(http://10.26.15.244:30880/project/springcloud),后期配置webhook需要使用。
配置流水线,在定义域中选择“Pipeline script from SCM”,此选项指示Jenkins从源代码管理(SCM)仓库获取流水线。在SCM域中选择“Git”,然后输入“Repository URL”,如图所示:
在Credentials中选择“添加”,凭据类型选择“Username with password”,然后输入对应信息,如图所示:
单击“保存”按钮,回到流水线中,在Credentials域选择刚才添加的凭证,如图所示:
保存任务。
(2)编写流水线
Pipeline有两种创建方法——可以直接在Jenkins的Web UI界面中输入脚本;也可以通过创建一个Jenkinsfile脚本文件放入项目源码库中。
一般推荐在Jenkins中直接从源代码控制(SCMD)中直接载入Jenkinsfile Pipeline这种方法。
登录GitLab进入springcloud项目,选择新建文件,如图所示:
将流水线脚本输入到Jenkinsfile中,如图所示:
Pipeline包括声明式语法和脚本式语法。声明式和脚本式的流水线从根本上是不同的。声明式是Jenkins流水线更友好的特性。脚本式的流水线语法,提供更丰富的语法特性。声明式流水线使编写和读取流水线代码更容易设计。
此处选择声明式Pipeline,完整的流水线脚本如下:
pipeline{
agent none
stages{
stage('mvn-build'){
agent {
docker {
image '10.26.15.244/library/maven'
args '-v /root/.m2:/root/.m2'
}
}
steps{
sh 'cp -rfv /opt/repository /root/.m2/ && ls -l /root/.m2/repository'
sh 'mvn package -DskipTests'
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
}
}
stage('image-build'){
agent any
steps{
sh 'cd gateway && docker build -t 10.26.15.244/springcloud/gateway -f Dockerfile .'
sh 'cd config && docker build -t 10.26.15.244/springcloud/config -f Dockerfile .'
sh 'docker login 10.26.15.244 -u=admin -p=Harbor12345'
sh 'docker push 10.26.15.244/springcloud/gateway'
sh 'docker push 10.26.15.244/springcloud/config'
}
}
stage('cloud-deploy'){
agent any
steps{
sh 'sed -i "s/sqshq\\/piggymetrics-gateway/10.26.15.244\\/springcloud\\/gateway/g" yaml/deployment/gateway-deployment.yaml'
sh 'sed -i "s/sqshq\\/piggymetrics-config/10.26.15.244\\/springcloud\\/config/g" yaml/deployment/config-deployment.yaml'
sh 'kubectl create ns springcloud'
sh 'kubectl apply -f yaml/deployment/gateway-deployment.yaml'
sh 'kubectl apply -f yaml/deployment/config-deployment.yaml'
sh 'kubectl apply -f yaml/svc/gateway-svc.yaml'
sh 'kubectl apply -f yaml/svc/config-svc.yaml'
}
}
}
}
(3)开启Jenkins匿名访问
登录Jenkins首页,选择“系统管理→全局安全配置”,授权策略选择“任何用户可以做任何事(没有任何限制)”,如图所示。
六、构建CI/CD
(1)触发构建
在GitLab的项目中,通常会使用Webhook的各种事件来触发对应的构建,通常配置好后会向设定好的URL发送post请求。
登录GitLab,进入springcloud项目,现在左侧导航栏“Settings→Webhooks”,将前面记录的GitLab webhook URL地址填入URL处,禁用SSL认证,如图所示。
单击“Add webhook”按钮添加webhook,完成后如图所示:
单击“Test→Push events”按钮进行测试,如图所示:
结果返回HTTP 200则表明Webhook配置成功。
(2)Jenkins查看
登录Jenkins,可以看到springcloud项目已经开始构建,如图所示:
选择左侧导航栏“打开Blue Ocean”,如图所示:
Blue Ocean是pipeline的可视化UI,同时兼容经典的自由模式的job。Jenkins Pipeline从头开始设计,但仍与自由式作业兼容,Blue Ocean减少了经典模式下的混乱并为团队中的每个成员增加了清晰度。
单击项目名称springcloud,如图所示:
单击正在构建的pipeline可以查看阶段视图,如图所示:
单击任意“>”符号可查看每个Step的构建详情,如图所示:
若构建成功,Blue Ocean界面会变为绿色。构建完成后如图所示:
退出阶段试图界面,如图所示:
返回Jenkins首页,如图所示:
(3)Harbor查看
进入Harbor仓库springcloud项目查看镜像列表,可以看到已自动上传了一个gateway镜像,如图所示:
(4)Kubernetes查看
Pod的启动较慢,需等待3–5分钟。在命令行查看Pod:
[root@master ~]# kubectl -n springcloud get pods
NAME READY STATUS RESTARTS AGE
config-6b6875fffd-p2g7j 1/1 Running 0 3m6s
gateway-5d5f8cc944-vstgm 1/1 Running 0 3m6s
查看service:
[root@master ~]# kubectl -n springcloud get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
config NodePort 192.109.170.192 <none> 8888:30015/TCP 3m18s
gateway NodePort 192.110.243.17 <none> 4000:30010/TCP 3m18s
通过端口30010访问服务,如图所示:
至此,完整的CI/CD流程就完成了。
评论区