目录一览:

0x04 基础使用

  • HelloWorld 自由风格软件项目
  • Gitlab 集成配置与实践

0x04 基础使用

HelloWorld 自由风格软件项目

Q: Jenkins Free Style 基本使用?
目的: 构建一个自由风格的软件项目, 这是Jenkins的主要功能Jenkins将会结合任何SCM和任何构建系统来构建你的项目, 甚至可以构建软件以外的系统.

操作流程:

Step 1.项目创建

(1) 面板 -> 新建一个任务 -> 任务名称 freestyle-helloworld -> 保存
(2) Dashboard -> 项目名称 freestyle-helloworld -> General

# 重要的配置项
丢弃旧的构建:(保持构建的天数 / 保持构建的最大个数)
参数化构建过程: 比如添加的环境变量或者API密钥等等

(3) Dashboard -> 项目名称 freestyle-helloworld > 构建 > 执行 Shell 命令

echo "FreeStyle - HelloWorld"
touch hello-world.txt

2.Jenkins入门基础使用与Gitlab持续化集成部署_nginx


Step 2.工程 ​​freestyle-helloworld​​​ 构建与控制台输出查看;
2.Jenkins入门基础使用与Gitlab持续化集成部署_nginx_02

PS : 如果是蓝色圆点表示构建成功, 如果是红色圆点表示构建失败!


Step 3.构建后的工作区存放目录

jenkins:/var/lib/jenkins/workspace/freestyle-helloworld$ ls
# hello-world.txt
jenkins:/var/lib/jenkins/workspace/freestyle-helloworld$ cat hello-world.txt


Gitlab 集成配置与实践

简单说明:
Q: Jenkins 为啥要集成Gitlab?

答:由于我们需要依托于Jenkins将Gitlab上的项目获取至本地,为后续网站的代码发布工作做好准备;

Q: Jenkins 如何集成Gitlab?

答: 由于Jenkins 只是一个调度平台,所以需要安装和Gitlab相关的插件即可完成集成;

Jenkins 与 Gitlab 集成思路

  • 1.开发提交代码 至 Gitlab
  • 2.Jenkins 安装 Gitlab 所需插件
Credentials Plugin (2.3.14) - This plugin allows you to store credentials in Jenkins.
Git client plugin (3.6.0) - Utility plugin for Git support in Jenkins
Git plugin (4.5.0) - This plugin integrates Git with Jenkins.
Gitlab Authentication plugin (1.10) - This is the an authentication plugin using gitlab OAuth.
Gitlab Hook Plugin (1.4.2) - Enables Gitlab web hooks to be used to trigger SMC polling on Gitlab projects
GitLab Plugin (1.5.13) - This plugin allows GitLab to trigger Jenkins builds and display their results in the GitLab UI.

2.Jenkins入门基础使用与Gitlab持续化集成部署_nginx_03

  • 3.Jenkins 创建 FreeStyle 项目,然后配置Gitlab仓库对应的地址;


操作流程:

  • Step 1.首先需要将我们所用的项目代码推送到Gitlab(此处假设您已安装Gitlab)之中;

(1) 管理中心 -> 群组 -> 新建群组 -> 完善信息 -> 创建群组
(2) 管理中心 -> 项目 -> 创建项目 -> 完善仓库信息 -> 创建项目
(3) 推送现有文件夹到Gitlab之中

cd existing_folder
git init
git remote add origin http://gitlab.weiyigeek.top/ci-cd/blog.git
git add .
git commit -m "Initial commit"
git push -u origin master
# remote: Resolving deltas: 100% (829/829), done.
# To http://gitlab.weiyigeek.top/ci-cd/blog.git
# * [new branch] master -> master
# Branch 'master' set up to track remote branch 'master' from 'origin'.

2.Jenkins入门基础使用与Gitlab持续化集成部署_html_04

  • Step 2.此处假设您已经按照上面​​Gitlab 集成配置​​安装了相应的插件, 并且配置好gitlab域名访问的解析记录;
# 此处由于没有自己搭建DNS,则将其写入到Jenkins 服务器的hosts文件中进行相应的IP与域名绑定
cat /etc/hosts
# 127.0.0.1 localhost
# 127.0.1.1 gitlab
# 10.10.107.201 gitlab.weiyigeek.top
  • Step 3.Jenkins 创建 FreeStyle 项目,然后配置Gitlab仓库对应的地址(​​ssh 的方式​​)
# (1) 在Gitlab中添加当前机器ssh密钥(此处以Jenkins用户为例)
jenkins@jenkins:~$ssh-keygen -t ed25519 -C "jenkins@weiyigeek.top"
~$ ls ~/.ssh/id_ed25519
# id_ed25519 id_ed25519.pub

# (2) 添加公钥到gitlab中
# > 用户设置 -> SSH Keys -> jenkins-CI
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINFb2ALOnOpePb7e/tss4/ZKxNHb3srh7NXntW5jAWSf jenkins@weiyigeek.top

# (3) 主机认证指纹绑定
jenkins@jenkins:~$ git ls-remote -h -- git@gitlab.weiyigeek.top:ci-cd/blog.git HEAD
# The authenticity of host 'gitlab.weiyigeek.top (10.10.107.201)' can't be established.
# ECDSA key fingerprint is SHA256:cmG5Ces+96qG9EEaU1b/tJuTR1re7XDXUU4jg7asna4.
# Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

2.Jenkins入门基础使用与Gitlab持续化集成部署_html_05

  • Step 4.Jenkins > FreeStyle 项目 > 源码管理 > Git > Repositories 设置 > Credentials 设置
    PS : 如果是非Jenkins用户下公钥对Gitlab该项目有访问权限时,可以通过 Credentials 添加其认证的密钥即可;
# (1) Weiyigeek 用户密钥 (此时假设Gitlab已经添加该公钥)
weiyigeek@jenkins:~$ cat /home/weiyigeek/.ssh/id_ed25519
# -----BEGIN OPENSSH PRIVATE KEY-----
# b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
# QyNTUxOQAAACAIxH1a4EivkJOSAXqd6LUE8tUvRfgPwwn1Erb7r728cwAAAJgANcy8ADXM
# vAAAAAtzc2gtZWQyNTUxOQAAACAIxH1a4EivkJOSAXqd6LUE8tUvRfgPwwn1Erb7r728cw
# AAAECLw4Wnle7Md7fc5NQN6EohejUx0XMHKfdYXejLAw2/NwjEfVrgSK+Qk5IBep3otQTy
# 1S9F+A/DCfUStvuvvbxzAAAAFG1hc3RlckB3ZWl5aWdlZWsudG9wAQ==
# -----END OPENSSH PRIVATE KEY-----

# (2) 进行 Credentials 相应的设置

2.Jenkins入门基础使用与Gitlab持续化集成部署_nginx_06

  • Step 5.首先手动实现设置NFS共享存储以及 Kubernetes 部署 StatefulSet 资源清单,通过Nginx访问我们的blog;
    基础配置:
# (1) NFS 服务器配置
root@nfs$ showmount -e
# /nfs/data4 *
/nfs/data4# ls -alh /nfs/
# drwxrwxrwx 2 weiyigeek weiyigeek 4.0K Nov 19 13:27 data4
/nfs/data4# mkdir /nfs/data4/tags/
/nfs/data4# ln -s /nfs/data4/tags/ /nfs/data4/web
/nfs/data4# chown -R nobody:weiyigeek /nfs/data4/

# (2) Node 1 && Node 2
sudo mkdir -pv /nfs/data4/
sudo chown -R weiyigeek:weiyigeek /nfs/data4/
sudo mount.nfs -r 10.10.107.202:/nfs/data4/ /nfs/data4/
k8s-node-4:/nfs/data4$ ls -alh # 权限查看
# total 12K
# drwxrwxrwx 3 weiyigeek weiyigeek 4.0K Dec 24 15:44 .
# drwxr-xr-x 3 root root 4.0K Dec 24 15:47 ..
# drwxr-xr-x 2 weiyigeek weiyigeek 4.0K Dec 24 15:44 tags
# lrwxrwxrwx 1 weiyigeek weiyigeek 16 Dec 24 15:44 web -> /nfs/data4/tags/

资源清单:

cat > jenkins-gitlab-ci.yaml <<'EOF'
apiVersion: v1
kind: Service
metadata:
name: deploy-blog-svc
spec:
type: NodePort # Service 类型
selector:
app: blog-html # 【注意】与deployment资源控制器创建的Pod标签进行绑定;
release: stabel # Service 服务发现不能缺少Pod标签,有了Pod标签才能与之SVC对应
ports: # 映射端口
- name: http
port: 80 # cluster 访问端口
targetPort: 80 # Pod 容器内的服务端口
nodePort: 30088
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: deploy-blog-html
spec:
serviceName: "deploy-blog-svc"
replicas: 3 # 副本数
selector: # 选择器
matchLabels:
app: blog-html # 匹配的Pod标签非常重要
release: stabel
template:
metadata:
labels:
app: blog-html # 模板标签
release: stabel
spec:
volumes: # 关键点
- name: web
hostPath: # 采用hostPath卷
type: DirectoryOrCreate # 卷类型DirectoryOrCreate: 如果子节点上没有该目录便会进行创建
path: /nfs/data4/web # 各主机节点上已存在的目录此处是NFS共享
- name: timezone # 容器时区设置
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
containers:
- name: blog-html
image: harbor.weiyigeek.top/test/nginx:v3.0 # 拉取的镜像
imagePullPolicy: IfNotPresent
ports:
- name: http # 此端口在服务中的名称
containerPort: 80 # 容器暴露的端口
volumeMounts: # 挂载指定卷目录
- name: web
mountPath: /usr/share/nginx/html
- name: logs
mountPath: /var/log/nginx
- name: timezone
mountPath: /usr/share/zoneinfo/Asia/Shanghai
volumeClaimTemplates: # 卷的体积要求模板此处采用StorageClass存储类
- metadata: # 根据模板自动创建PV与PVC并且进行一一对应绑定;
name: logs
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: managed-nfs-storage # StorageClass存储类
resources:
requests:
storage: 1Gi
EOF

部署资源清单:

~/K8s/Day12$ kubectl apply -f jenkins-gitlab-ci.yaml
service/deploy-blog-svc unchanged
statefulset.apps/deploy-blog-html configured

~/K8s/Day12$ kubectl get services -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
deploy-blog-svc NodePort 10.104.74.36 <none> 80:30088/TCP 5m9s app=blog-html,release=stabel
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 49d <none>

~/K8s/Day12$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deploy-blog-html-0 1/1 Running 0 72s 10.244.0.193 Master
deploy-blog-html-1 1/1 Running 0 57s 10.244.1.182 k8s-node-4
deploy-blog-html-2 1/1 Running 0 49s 10.244.2.84 k8s-node-5

效果查看:

curl http://10.10.107.202:30088/host.html
# Hostname: deploy-blog-html-0 ,Image Version: 3.0, Nginx Version: 1.19.4
  • Step 6.采用Tag方式发布和回退项目

Q: 为什么要让项目支持Tag版本方式上线?

答: 采用 Tag 的方式可以直观的知道我们部署的项目版本,同时也便于进行回退;
比如: 第一次上线v1.1第二次上线v1.2,如果此时上线的v1.2出现文件,那么我们可以快速回退至上一个版本v1.1;

使用Tag方式发布与回退思路:

1.开发如果需要发布新版本,必须将当前版本打上一个标签。
2.Jenkins需要让其脚本支持传参,比如用户传递v1.1则拉取项目的v1.1标签。


实践操作:

(1) 首先需要安装 ​​Git Parameter​​​ 插件(​​增加了从项目中配置的git存储库中选择分支、标记或修订的能力。​​​),然后配置Jenkins参数化构建过程,让用户在构建时选择对应的Tag版本;
丢弃旧的构建 > 保持构建的最大个数 为 10 个
参数化构建过程 > Git 参数 > git_version (变量) -> 参数类型 Tags -> 默认值 (origin/master) -> 排序方式 (DESCENDING SMART) 倒序 ​​​防止 Tags 顺序乱​​​;
选项参数 (选择) > deploy_option (变量) -> 选项 deploy|rollback
源码管理 > Git > Repository URL:git@gitlab.weiyigeek.top:ci-cd/blog.git > Credentials (密钥认证) -> 分支机构建设 (​​​指定分支(为空时代表any)​​​)-> 引入 ${git_version} 变量
构建 > 执行shell > /bin/sh -x /tmp/script/blog-script.sh
应用 > 保存

2.Jenkins入门基础使用与Gitlab持续化集成部署_git_07

(2) 部署和回退脚本以及自动化发布重复构建的问题处理编写

touch /tmp/script/blog-script.sh && chmod a+x $_

#!/bin/bash
# Description: Jenkins CI & Kubernetes & Gitlab -> Deploy or Rollback Blog HTML
DATE=$(date +%Y%m%d-%H%M%S)
TAG_PATH="/nfs/data4/tags"
WEB_PATH="/nfs/data4/web"
WEB_DIR="blog-${DATE}-${git_version}"
K8S_MATER="weiyigeek@10.10.107.202"
K8S_MATER_PORT="20211"


# 部署
deploy () {
# 1.打包工作目录中的项目
cd ${WORKSPACE}/ && \
tar -zcf /tmp/${WEB_DIR}.tar.gz ./*

# 2.上传打包的项目到master之中
scp -P ${K8S_MATER_PORT} /tmp/${WEB_DIR}.tar.gz weiyigeek@10.10.107.202:${TAG_PATH}

# 3.解压&软链接
ssh -p ${K8S_MATER_PORT} ${K8S_MATER} "mkdir -p ${TAG_PATH}/${WEB_DIR} && \
tar -xf ${TAG_PATH}/${WEB_DIR}.tar.gz -C ${TAG_PATH}/${WEB_DIR} && \
rm -rf ${WEB_PATH} && \
ln -s ${TAG_PATH}/${WEB_DIR} ${WEB_PATH} && \
kubectl delete pod -l app=blog-html"
}

# 回退
rollback () {
Previous_Version=$(ssh -p ${K8S_MATER_PORT} ${K8S_MATER} "find ${TAG_PATH} -maxdepth 1 -type d -name blog-*-${git_version}")
ssh -p ${K8S_MATER_PORT} ${K8S_MATER} "rm -rf ${WEB_PATH} && \
ln -s ${Previous_Version} ${WEB_PATH} && \
kubectl delete pod -l app=blog-html"
}


# 部署 & 回退 入口(坑-==两边没有空格)
if [[ "${deploy_option}" = "deploy" ]]; then
# 坑 (防止字符串为空)
if [[ "v${GIT_COMMIT}" = "v${GIT_PREVIOUS_SUCCESSFUL_COMMIT}" ]];then
echo -e "您已经部署过 ${git_version} 版本"
exit 1
else
deploy
fi
elif [[ "${deploy_option}" = "rollback" ]];then
rollback
else
exit 127
fi

(3) Jenkins 服务器 与 Kubernetes Master 机器中的普通用户进行 ssh 公钥认证登录;

# copy 公钥 到 对端主机
ssh-copy-id -p 20211 weiyigeek@10.10.107.202
# /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/var/lib/jenkins/.ssh/id_ed25519.pub"
# authorized only. All activity will be monitored and reported.
# weiyigeek@10.10.107.202's password:

# Number of key(s) added: 1

# Now try logging into the machine, with: "ssh -p '20211' 'weiyigeek@10.10.107.202'" and check to make sure that only the key(s) you wanted were added.

(4) 为我们的Blog打三个Tag并验证构建脚本

$ cd ~/workspace/freestyle-blog
jenkins:~/workspace/freestyle-blog$ git config --global user.email "jenkins@weiygeek.top"
jenkins:~/workspace/freestyle-blog$ git config --global user.name "Weiyigeek"
vim index.html
git add .
git commit -m "v1.1"
git tag v1.1 -m "Jenkins CI test - v1.1"
git push origin HEAD:master
git push origin v1.1
# Total 0 (delta 0), reused 0 (delta 0)
# To gitlab.weiyigeek.top:ci-cd/blog.git
# * [new tag] v1.1 -> v1.1

(5) 进行项目构建 -> Build With Paramters 查看 部署的版本以及是部署还是回退 -> 如下图所示拉取的指定 Tags ;

2.Jenkins入门基础使用与Gitlab持续化集成部署_html_08

(6) 项目构建部署验证 访问​​http://10.10.107.202:30088/​​博客地址

Built Branches
v1.3: Build #4 of Revision 4f80504ee142cb9866e4a0988cdc1e1693cfd7aa (v1.3)
v1.2: Build #3 of Revision 4e1dd6eded12d7cad3740d2461c3e784ad712632 (v1.2)
v1.1: Build #2 of Revision cd2d5778292ff2cbb7d4ac1b82c684223a38761b (v1.1)

# 如果已经部署过该项目则显示:
# + '[' deploy==deploy ']'
# + [[ v4f80504ee142cb9866e4a0988cdc1e1693cfd7aa = \v\4\f\8\0\5\0\4\e\e\1\4\2\c\b\9\8\6\6\e\4\a\0\9\8\8\c\d\c\1\e\1\6\9\3\c\f\d\7\a\a ]]
# + echo -e '您已经部署过 v1.3 版本'
# 您已经部署过 v1.3 版本

2.Jenkins入门基础使用与Gitlab持续化集成部署_git_09

(6) 项目回退验证 > 请选择您要部署的RELEASE版本​​v1.1​​, 然后选择部署或是回退;

2.Jenkins入门基础使用与Gitlab持续化集成部署_git_10



WeiyiGeek Blog - 为了能到远方,脚下的每一步都不能少。

2.Jenkins入门基础使用与Gitlab持续化集成部署_html_11