CICD 概念
首先我们先了解一下 CICD 的概念:

既持续集成称为 CI
、持续交付和持续部署可以统称为 CD
。
持续集成/持续交付软件
这次使用的持续交付系统是通过Jenkins实现的,通过Jenkins可以快速的搭建符合自己业务场景的流水线流程,结合大量的开源插件,可以轻松的满足不同语言、不同平台、包括不同框架的持续基层场景。
环境搭建
本次使用的环境:
1、Centos 7服务器(可以为虚拟机)
2、容器镜像云服务 (可以为私有,本文中使用的为阿里云容器服务)
3、Kubernetes (我使用的是自己搭建的,也适用阿里云容器)
4、Gitee
首先搭建 Jenkins 系统,这次选择使用容器搭建 Jenkins 系统。我们会在一个 CentOS 7 的机器上去安装 Docker 服务,然后使用 Docker 去启动 Jenkins master,master 启动起来以后我们就可以登录到他的 web 界面上边去,从界面上去给他安装插件,然后配置构建节点,并且运行第一个构建项目。
1、安装Docker运行环境
# 1.移除以前docker相关包
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2. 配置yum源
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 3. 安装docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
# 4. 启动docker
systemctl enable docker --now
# 5. 配置阿里云加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://26t56xmf.mirror.aliyuncs.com"],
"live-restore": true,
"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
上面的命令没有报错的话doker就已经启动成功了,也可以使用systemctl status docker 查看docker是否在运行,running表示已经在运行了

2、安装Jenkins
接下来我们启动Jenkins容器(命令为一整行,因为过长换行了,不要分开复制)
docker run -u root -itd -p 8080:8080 -p 50000:50000 -v /var/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock --name jenkins-master jenkins/jenkins:jdk11
参数解释:
-u root 表示用root运行这个容器
-itd 以交互模式后台运行这个容器
-p 8080:8080 将容器内的8080端口映射到主机8080端口,前面为主机端口,后面为容器内端口,主机端口可以自行更改
-p 50000:50000 同上
-v /var/jenkins_home:/var/jenkins_home 将容器的/var/jenkins_home目录挂在到主机的/var/jenkins_home目录上,方便我们修改Jenkins相关配置,前面为主机目录,后面为容器内目录
-v /var/run/docker.sock:/var/run/docker.sock 因为容器内可能会用到docker命令,所以把主机目录挂载到容器中
–name jenkins-master 为容器命名
jenkinsci/blueocean 表示我们使用的是Jenkins master 镜像的 blueocean 的版
docker会先去拉取镜像,镜像拉取完成以后容器就会开始启动,拉取速度视网络而定,所以要稍等一会,容器运行以后可以使用docker ps命令查看运行状态,运行成功以后就可以通过本机IP:8080的方式访问jenkins了,出现下面的页面表示启动成功(没有可以等一会,程序启动需要时间)

登陆成功后,可以看到 Jenkins 给我们提供了两个选项:一个就是安装推荐的插件,一个是选择插件的安装。我们新手刚搭建起来的话,可以直接点击安装推荐的插件。后续的话,我们可以在 Jenkins 的插件管理界面上边自定义的添加自己想要的插件。选择选择安装推荐的插件即可

推荐插件安装完成之后,会进入到如下图所示界面,可以创建一个管理员用户

接下来的设置我们采用默认的就好



3、配置构建节点
为了方便,构建节点也使用容器部署
# 拉取镜像
docker pull registry.cn-beijing.aliyuncs.com/codepipeline/jenkins-slave-java:latest
# 启动镜像(将容器里的22端口,也就是SSH的端口映射到宿主机的30001上)
docker run -itd -p 30001:22 -v /var/run/docker.sock:/var/run/docker.sock registry.cn-beijing.aliyuncs.com/codepipeline/jenkins-slave-java:latest
因为后面我们要通过ssh连接到容器里,所以我们等容器运行以后进入容器,修改root密码
[root@test ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bff4112a43e6 registry.cn-beijing.aliyuncs.com/codepipeline/jenkins-slave-java:latest "/usr/sbin/sshd -D" 3 days ago Up 3 days 0.0.0.0:30001->22/tcp objective_feynman
2ebfca3486d7 jenkinsci/blueocean "/sbin/tini -- /usr/…" 3 days ago Up 3 days 0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp jenkins-master
[root@test ~]# docker exec -it bff4112a43e6 /bin/bash
root@bff4112a43e6:/# sudo passwd root
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
接着依次点击 系统配置 –> 节点管理,这里我们可以看到只有 master 这一个节点,由于刚才它已经被我们设置了可执行数量为0,因此它现在是没法去构建 job。因此我们需要新建一个节点,起名字叫做 slave-java
,勾选固定节点,然后点击ok

然后进入到详细设置页面,首先来设置并发构建数,我们可以改成5;然后设置 Job 在该构建节点上的工作空间,这里为 /home/jenkins;然后设置标签,标签用于在 Job 的配置中选择,可以映射到具体的构建节点,用法一般选择只允许运行绑定到这台机器上的 Job



30001
,因为我们容器启动的时候将容器内的22映射到了宿主机的30001

以上设置都设置完成后,点击保存即可看到新创建的节点,此时该节点显示❌,代表与 Jekins master 连接是有问题的,这里是因为它在初始化,我们等待一会即可看到 slave-java 节点已经正常的连接,而且它是有五个 executor 的执行者,也就是说有五个 job 可以在这个节点上面并行构建。
4、构建第一个项目
回到 Jenkins 的主页面,现在新建一个任务,名字叫做 java-demo 构建,选择一个自由风格的软件项目。


然后我们需要配置一个源码管理。这里有一个我自己的项目代码,地址为:https://gitee.com/sheepanger/java-demo-manage.git,它是一个公共仓库,可以直接克隆下来,而不需要配置用户名密码。如果是私有仓库的话,这边需要添加一个包含用户名和密码的证书。源码的分支的话,我这是master (根据实际情况填写)

构建这部分的话,我们添加一个执行 shell,将 maven 打包命令写进去

mvn package -B -DskipTests
操作设置完成后,保存任务,然后点击立即构建。我们来看控制台输出,首先是 admin 用户,然后运行在 slave-java 节点上边进行源码的拉取源码构建

据构建命令进行构建。在构建过程中,会先拉取一些依赖的 jar 包

最后构建成功

5、把项目打包成docker镜像推送到镜像仓库
成功运行构建了一个项目,在该任务配置里边的话,我们在 slave-java 节点上将源码的拉取下来进行构建,构建产物也就是这个 jar 包其实是放置在该构建节点上面的,我们应该要将它打包成一个docker 镜像,然后推送到镜像仓库。
需要使用到一个插件,这个插件目前是没有安装的,我们需要在 Manage Jenkins 中的 Manage Plugins 中的可选插件中搜索CloudBees Docker Build and Publish
这个插件点击 Download now and install after restar,也就是下载然后重启安装,因为所有插件的安装都得在 Jenkins master 重启后才生效

我们在 docker 镜像打包完成以后,需要把它推送到镜像仓库里边。这边我们就会使用到另外一个阿里云的服务叫做容器镜像服务,这个服务目前也是免费的,第一次使用我们需要创建一个命名空间

还需要在访问凭证界面中设置一下 Register 的登录密码,这个和你登录阿里云控制台的这个用户密码是不一样的,是拉取/推送镜像时候的验证密码

安装完插件以后,这边就会出现一个docker build and publish 的插件,这个插件就是能帮助我们打包 docker 镜像并且进行推送。接下来我们就是需要填入这个插件所需要的各个参数项

需要添加一个镜像仓库的用户名密码作为证书,账号是阿里云账号,密码就是前面设置的 Registry 的密码


如果构建失败的话查看日志,是不是需要在主机中先登陆阿里云的容器服务,在终端中输入访问凭证,登录Registry实例
sudo docker login --username=你的用户名 registry.cn-hangzhou.aliyuncs.com
然后输入密码就可以推送到仓库了
镜像版本的话,也是 v1 跟 latest 两个版本,因为该插件默认会把 latest 标签也推送上来。这个就完成了docker 镜像的构建和推送这个步骤。

6、部署容器到部署到k8s集群
部署到 k8s 集群中,我们首先需要安装一个插件

插件安装完成以后,在 Jenkins 这端我们要去给 java-demo 这个任务新增一个构建步骤,选则 Deploy to Kubenetes


阿里云容器服务的话在设置里复制config信息即可,先复制一下他的 KubeConfig 的信息添加到 Content 区域,然后点击保存

选择我们刚刚创建的证书,然后 configure files 的话是我们要部署的样本文件,这里为 deployment.yaml,该文件是放在这个gitee源码文件里边的

apiVersion: apps/v1
kind: Deployment
metadata:
name: java-demo
spec:
replicas: 2
selector:
matchLabels:
app: java-demo
template:
metadata:
labels:
app: java-demo
spec:
imagePullSecrets:
- name: aliyun #如果配置了镜像仓库密文的话要加入这段,不然无法拉取镜像
containers:
- name: java-demo
image: registry.cn-hangzhou.aliyuncs.com/anger/java-demo:v1
imagePullPolicy: Always
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: java-demo
spec:
ports:
- port: 80
targetPort: 8080
#集群外可访问的端口
nodePort: 30000
name: java-demo
selector:
app: java-demo
type: NodePort
添加完成以后,我们保存,然后进行构建,可以看一下这个控制台的输出

项目镜像已经成功推送到 k8s 的集群中,然后我们在kubernetes的master节点通过命令就可以看到推送上来的 java-demo-001 服务以及它的外部访问信息,这样我们通过该外部端点就可以直接访问该项目了

至此,就已经完成了一个项目从源码的拉取、编译构建、打包成docker镜像、推送镜像到影响仓库、部署到k8s容器集群这一系列流程的自动化,最终实现可以从浏览器上边访问到这个服务。
写在最后
搭建过程中遇到比较多的坑,还好都解决了,第一次写这么长的文档,如果没有说明白的地方可以留言给我,或者在我的gitee回复我,以及可以给我发邮件,这套环境我都是在本地测试环境中搭建、运行、测试,不保证完全适用你的环境,可以先在测试环境中搭建测试后使用
最后感谢CSDN大神Baret-H提供思路和文档,原文地址 https://bareth.blog.csdn.net/article/details/121272581