基于k8s构建持续集成
一、实施准备
登录 OpenStack 平台,使用提供的 CentOS_7.5_x86_64_XD.qcow2 镜像创建两台云主机,并使用提供的软件包部署好双节点 Kubernetes 集群。
项目目标:jenkins的离线安装步骤、gitlab的使用和管理、CICD的配置步骤和方法。
二、案例实施
1、安装Jenkins环境
# 查看k8s集群状态
[root@master jenkins]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
etcd-0 Healthy {"health":"true","reason":""}
scheduler Healthy ok
controller-manager Healthy ok
# 查看k8s集群节点信息
[root@master jenkins]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 9d v1.25.0
node NotReady <none> 9d v1.25.0
# 创建 Jenkins 目录
[root@master ~]# mkdir -p /root/cicd/jenkins && cd /root/cicd/jenkins
# 上传离线包到master节点 jenkins 目录,然后解压文件
[root@master jenkins]# tar -zxvf CICD_Offline.tar -C /opt/
# 导入镜像
[root@master jenkins]# cd /opt/
[root@master opt]# ls
apache-maven-3.6.3-bin.tar.gz cni containerd jenkins.tar plugins repository springcloud
[root@master opt]# docker load -i jenkins.tar
...略
Loaded image: jenkins/jenkins:2.262-centos
...略
Loaded image: gitlab/gitlab-ce:12.9.2-ce.0
...略
Loaded image: java:8-jre
# 编写jenkins编排文件
[root@master jenkins]# vi docker-compose.yml
version: '3.3'
services:
jenkins:
image: 'jenkins/jenkins:2.262-centos'
volumes:
- /home/jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- /usr/bin/kubectl:/usr/local/bin/kubectl
- /root/.kube:/root/.kube
ports:
- "8080:8080"
expose:
- "8080"
- "50000"
privileged: true
user: root
restart: always
container_name: jenkins
# 启动jenkins
[root@master jenkins]# docker-compose -f docker-compose.yml up -d
[+] Running 2/2
⠿ Network jenkins_default Created 0.1s
⠿ Container jenkins Started 0.6s
[root@master jenkins]# docker-compose up -d
[+] Running 1/0
⠿ Container jenkins Running 0.0s
[root@master jenkins]# docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
jenkins "/sbin/tini -- /usr/…" jenkins running 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
# 安装插件
[root@master jenkins]# cp -rfv /opt/plugins/* /home/jenkins_home/plugins/
[root@master jenkins]# docker restart jenkins
jenkins
在 web 端通过 http://10.104.43.110:8080 访问 Jenkins
根据上面的信息查看密码:
[root@master jenkins]# docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
9dcd074ea5d645618314a5f68085a45e
输入密码并点击“继续”,进入jenkins欢迎页面。
依次点击“系统管理”、“管理用户”按钮进入用户列表界面,如图所示:
再点击“新建用户”,输入用户信息:
- 用户名:springcloud
- 密码/确认密码:1234
- 全名:springcloud-guo
- 电子邮箱:example@qq.com
创建用户后,退出admin用户登录,使用新建用户'springcloud'登录Jenkins,依次点击“系统管理”——“系统配置”按钮进入系统配置界面,在 “Resource root URL”处配置 jenkins URL 为:http://10.104.43.110:8080/,然后点击“保存”。
2、部署Gitlab
GitLab 是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面进行访问公开的或者私人项目。与 Github 类似,GitLab 能够浏览源代码,管理缺陷和注释,可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库,团队成员可以利用内置的简单聊天程序(Wall)进行交流。Gitlab 还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。
(1)启动gitlab
[root@master cicd]# mkdir gitlab && cd gitlab/
[root@master gitlab]# pwd
/root/cicd/gitlab
# 编写gitlab编排文件
[root@master gitlab]# vi docker-compose.yml
version: '3.3'
services:
gitlab:
image: "gitlab/gitlab-ce:12.9.2-ce.0"
container_name: gitlab
restart: always
hostname: '10.104.43.110'
privileged: true
environment:
TZ: 'Asia/Shanghai'
ports:
- '81:80'
- '443:443'
- '1022:22'
volumes:
- /srv/gitlab/config:/etc/gitlab
- /srv/gitlab/gitlab/logs:/var/log/gitlab
- /srv/gitlab/gitlab/data:/var/opt/gitlab
# 启动gitlab
[root@master gitlab]# docker-compose up -d
[+] Running 2/2
⠿ Network gitlab_default Created 0.1s
⠿ Container gitlab Started 0.6s
[root@master gitlab]# docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
gitlab "/assets/wrapper" gitlab running (starting) 0.0.0.0:1022->22/tcp, 0.0.0.0:81->80/tcp, 0.0.0.0:443->443/tcp, :::1022->22/tcp, :::81->80/tcp, :::443->443/tcp
启动完成后,在 web 端访问 Gitlab(http://10.104.43.110:81)。
设置 root 用户信息(密码:12345678),并使用 root 用户登录 Gitlab .
(2)创建项目
点击 “Create a project”,创建项目 springcloud ,可见等级选择 “public”,如下所示:
点击“创建项目”按钮后,进入项目页面。
push 源代码到 gitlab 的 springcloud 项目:
[root@master ~]# cd /opt/springcloud/
[root@master springcloud]# ls
account-service docker-compose.dev.yml LICENCE notification-service registry
auth-service docker-compose.yml mongodb pom.xml statistics-service
config gateway monitoring README.md yaml
[root@master springcloud]# yum install -y git
[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.104.43.110:81/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.104.43.110:81': root 《————git用户名
Password for 'http://root@10.104.43.110:81': 《————git密码:12345678
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.48 MiB/s, done.
Total 3192 (delta 1233), reused 3010 (delta 1207)
remote: Resolving deltas: 100% (1233/1233), done.
To http://10.104.43.110:81/root/springcloud.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
刷新网页(http://10.104.43.110:81/root/springcloud),springcloud项目中文件已经更新了。
3、配置 Jenkins 连接Gitlab
(1)设置 Outbound requests
登录 Gitlab 首页,点击管理区域的扳手图标进入 “Admin area”,如图所示:
点击左侧导航栏的 “settings”——》“network”,设置 “Outbound requests”,勾选 “Allow requests to the local network form web hooks and services”,然后点击“save changes”保存配置。
(2)创建 Gitlab API Token
点击“头像”——》点击“Settings”——》点击左侧导航栏的“Access Tokens”添加 token。
点击 “Greate personal access token” 生成 Token。
复制Token (GGftEPPy_32MBQS29JZh)。
(3)设置jenkins
登录 Jenkins 首页,点击“系统管理”→“系统配置”,配置 Gitlab 信息.
取消勾选“Enable authentication for '/project' end-point”。
填入Gitlab信息,点“添加”——》“jenkins”添加认证信息。
将 Gitlab API Token 填入
点击 “Test Connection”,应用并保存。
4、配置 Jenkins 连接 maven
(1)安装 maven
由于 Jenkins 是采用 docker in docker 的方式启动的,需要在 jenkins 容器内安装。
[root@master ~]# cp -rf /opt/apache-maven-3.6.3-bin.tar.gz /home/jenkins_home/
[root@master ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
efd2441d6dc2 gitlab/gitlab-ce:12.9.2-ce.0 "/assets/wrapper" 2 days ago Up 2 hours (healthy) 0.0.0.0:443->443/tcp, :::443->443/tcp, 0.0.0.0:1022->22/tcp, :::1022->22/tcp, 0.0.0.0:81->80/tcp, :::81->80/tcp gitlab
8c688e17439b jenkins/jenkins:2.262-centos "/sbin/tini -- /usr/…" 2 days ago Up 2 hours 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 50000/tcp jenkins
[root@master ~]# docker exec -ti jenkins bash
[root@8c688e17439b /]# tar -zxvf /var/jenkins_home/apache-maven-3.6.3-bin.tar.gz -C .
[root@8c688e17439b /]# ls
apache-maven-3.6.3 dev home 略...
[root@8c688e17439b /]# mv apache-maven-3.6.3/ /usr/local/maven
# 行末添加两行
[root@8c688e17439b /]# echo 'export M2_HOME=/usr/local/maven
export PATH=$PATH:$M2_HOME/bin' >> /etc/profile
# 使配置生效
[root@8c688e17439b /]# vi /root/.bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
source /etc/profile 《————添加此行内容
fi
# 退出容器重新进入
[root@8c688e17439b /]# exit
exit
[root@master ~]# docker exec -ti jenkins bash
[root@8c688e17439b /]# mvn -v
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/local/maven
Java version: 1.8.0_265, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.265.b01-0.el8_2.x86_64/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "3.10.0-1160.el7.x86_64", arch: "amd64", family: "unix"
(2)连接maven
登录 Jenkins 首页,点击“系统管理”→“全局工具配置”,配置 maven 信息。
点击“新增Maven”,取消勾选“自动安装”,填入maven信息,点击“应用”和“保存”。
5、配置CI/CD
(1)新建任务
登录 Jenkins 首页,点击“新建任务”,输入任务名称“springcloud”,选择“流水线”,点击“确定”,进入配置页面。
配置触发器如下所示:
配置流水线,点击“流水线语法”,示例步骤选“git: Git”,将springcloud项目地址填入仓库url。
点击“添加”——》“jenkins”添加凭证。用户名:root,密码:12345678。
添加凭证后,点选凭证。点击“生成流水线脚本”按钮,生成如下信息:
git credentialsId: '39707334-c50c-40ad-8a50-724b618034b2', url: 'http://10.104.43.110:81/root/springcloud.git'
将上面的值填入流水线脚本中,完整脚本如下:
node{
stage('git clone'){
// check CODE
git credentialsId: '39707334-c50c-40ad-8a50-724b618034b2', url: 'http://10.104.43.110:81/root/springcloud.git'
}
stage('maven build'){
sh '''/usr/local/maven/bin/mvn package -DskipTests -f /var/jenkins_home/workspace/springcloud'''
}
stage('image build'){
sh '''
echo $BUILD_ID
docker build -t 10.104.43.110/springcloud/gateway:$BUILD_ID -f /var/jenkins_home/workspace/springcloud/gateway/Dockerfile /var/jenkins_home/workspace/springcloud/gateway
docker build -t 10.104.43.110/springcloud/config:$BUILD_ID -f /var/jenkins_home/workspace/springcloud/config/Dockerfile /var/jenkins_home/workspace/springcloud/config
'''
}
stage('test'){
sh '''
docker run -itd --name gateway 10.104.43.110/springcloud/gateway:$BUILD_ID
docker ps -a|grep springcloud|grep Up
if [ $? -eq 0 ];then
echo "Success!"
docker rm -f gateway
else
docker rm -f gateway
exit 1
fi
'''
}
stage('upload registry'){
sh '''
docker login 10.104.43.110 -u=admin -p=Harbor12345
docker push 10.104.43.110/springcloud/gateway:$BUILD_ID
docker push 10.104.43.110/springcloud/config:$BUILD_ID
'''
}
stage('deploy Rancher'){
// 执行部署脚本
sh 'sed -i "s/sqshq\\/piggymetrics-gateway/10.104.43.110\\/springcloud\\/gateway:$BUILD_ID/g" /var/jenkins_home/workspace/springcloud/yaml/deployment/gateway-deployment.yaml'
sh 'sed -i "s/sqshq\\/piggymetrics-config/10.104.43.110\\/springcloud\\/config:$BUILD_ID/g" /var/jenkins_home/workspace/springcloud/yaml/deployment/config-deployment.yaml'
sh 'kubectl create ns springcloud'
sh 'kubectl apply -f /var/jenkins_home/workspace/springcloud/yaml/deployment/gateway-deployment.yaml --kubeconfig=/root/.kube/config'
sh 'kubectl apply -f /var/jenkins_home/workspace/springcloud/yaml/deployment/config-deployment.yaml --kubeconfig=/root/.kube/config'
sh 'kubectl apply -f /var/jenkins_home/workspace/springcloud/yaml/svc/gateway-svc.yaml --kubeconfig=/root/.kube/config'
sh 'kubectl apply -f /var/jenkins_home/workspace/springcloud/yaml/svc/config-svc.yaml --kubeconfig=/root/.kube/config'
}
}
脚本中所有IP地址均为本机IP地址,需要根据实际情况修改,在网页中写入完整脚本,完成后点击“应用”。
(2)开启Jenkins 匿名访问
登录 Jenkins 首页,点击“系统管理”→“全局安全配置”,配置授权策略允许匿名用户访问。
点选“登录用户可以做任何事”,点选“匿名用户具有可读权限”。再点击“应用”。
(3)配置Webhook
登录 Github ,进入springcloud项目,点击“设置”→“Webhook”,点击“添加Webhook”,填入Jenkins地址,点击“添加Webhook”。
进入页面后,填入URL: http://10.104.43.110:8080/project/springcloud
。点选取消 Enable SSL verification
,点击“添加Webhook”。
点击 “Test”——》“Push events”进行测试,显示出: “Hook executed successfully:HTTP 200”。表示Webhook配置成功。
(4)创建仓库项目
登录 Harbor,新建项目 springcloud,访问级别设置为公开。
当前进入项目springcloud查看镜像列表,可以看到镜像列表为空。
6、触发CI/CD
(1)触发构建
上传代码触发自动构建
[root@master ~]# docker cp /opt/repository/ jenkins:/root/.m2/
Successfully copied 98.6MB to jenkins:/root/.m2/
[root@master ~]# docker restart jenkins
jenkins
[root@master ~]# cd /opt/springcloud/
[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.104.43.110:81': root
Password for 'http://root@10.104.43.110:81': 《————密码:12345678
Branch master set up to track remote branch master from origin.
Everything up-to-date
(2)jenkins查看
登录 Jenkins,进入项目 springcloud,可以看到构建已经开始。
(3)harbor查看
登录 Harbor,进入项目 springcloud,可以看到镜像已经上传成功。
(4)kubernetes查看
Pod 的启动较慢,需等待 3--5 分钟。在命令行查看 Pod:
# 由于harbor之前没有配置成本地,一直处于pending状态,所以这里手动修改成本地镜像
# 查看pod日志
[root@master ~]# kubectl describe pod gateway-7c6947d8cc-scpsj -n springcloud
# 改完后重启docker和pod
[root@master ~]# systemctl restart docker
[root@master ~]# kubectl -n springcloud delete pod config-687f4c88fc-9fbtn
pod "config-687f4c88fc-9fbtn" deleted
[root@master ~]# kubectl -n springcloud delete pod gateway-7c6947d8cc-x5vdh
pod "gateway-7c6947d8cc-x5vdh" deleted
[root@master ~]# kubectl -n springcloud get pods
NAME READY STATUS RESTARTS AGE
config-687f4c88fc-tfzv2 0/1 Pending 0 12s
gateway-7c6947d8cc-scpsj 0/1 Pending 0 3s
# 查看pod状态
[root@master ~]# kubectl -n springcloud get pods
NAME READY STATUS RESTARTS AGE
config-687f4c88fc-7jhz9 1/1 Running 0 3h27m
gateway-7c6947d8cc-pxzqb 1/1 Running 1 (3h25m ago) 3h26m
[root@master ~]# kubectl -n springcloud get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
config NodePort 10.107.215.217 <none> 8888:30015/TCP 27h
gateway NodePort 10.103.164.83 <none> 4000:30010/TCP 27h
然后就可以通过端口30010访问服务了。http://10.104.43.110:30010/