HelloWorld 自由风格软件项目
Gitlab 集成配置与实践
WeiyiGeek Blog - 为了能到远方,脚下的每一步都不能少。
Tips : 本文章来源 Blog 站点或者 WeiyiGeek
公众账号 (技术交流、友链交换请邮我哟
), 原文地址: 2.Jenkins入门基础使用与Gitlab持续化集成部署
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
Step 2.工程 freestyle-helloworld
构建与控制台输出查看;
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
简单说明:
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.
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'.
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 "[email protected]" ~$ ls ~/.ssh/id_ed25519 # id_ed25519 id_ed25519.pub # (2) 添加公钥到gitlab中 # > 用户设置 -> SSH Keys -> jenkins-CI ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINFb2ALOnOpePb7e/tss4/ZKxNHb3srh7NXntW5jAWSf [email protected] # (3) 主机认证指纹绑定 jenkins@jenkins:~$ git ls-remote -h -- [email protected]: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
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 相应的设置
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.3680:30088/TCP 5m9s app=blog-html,release=stabel kubernetes ClusterIP 10.96.0.1 443/TCP 49d ~/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:[email protected]:ci-cd/blog.git > Credentials (密钥认证) -> 分支机构建设 (指定分支(为空时代表any)
)-> 引入 ${git_version} 变量
构建 > 执行shell > /bin/sh -x /tmp/script/blog-script.sh
应用 > 保存
(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="[email protected]" 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 [email protected]:${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 [email protected] # /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. # [email protected]'s password: # Number of key(s) added: 1 # Now try logging into the machine, with: "ssh -p '20211' '[email protected]'" 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 "[email protected]" 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 ;
(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 版本
(6) 项目回退验证 > 请选择您要部署的RELEASE版本
v1.1
, 然后选择部署或是回退;
WeiyiGeek Blog - 为了能到远方,脚下的每一步都不能少。
Tips : 本文章来源 Blog 站点或者 WeiyiGeek
公众账号 (友链交换请邮我哟
):
微信公众号-WeiyiGeek` # 精华文章发布地址
https://weiyigeek.top # 采用cloudflare CDN 国内有时访问较慢
https://weiyigeek.gitee.io # 国内访问快可能会有更新不及时得情况
个人知乎-WeiyiGeek
Tips: 更多学习笔记文章请关注
WeiyiGeek
公众账号
【微信公众号关注(点击)】
【邮箱联系: Master#weiyigeek.top】