环境预备
- 本实行采用华为云ECS举行,模拟真实工作环境
- 当然当地电脑环境设置达标,也可以在当地电脑使用VMware假造机完成
- 本实行供需4台云主机,全部使用Rocky Linux8.5操纵系统,2vCPU,4G内存
- 具体要求如下:
主机名IP地址设置角色windows––程序员develop192.168.0.10|公网IP2vCPU,4G内存程序员gitlab192.168.0.20|公网IP2vCPU,4G内存远程堆栈jenkins192.168.0.30|公网IP2vCPU,4G内存CI/CD服务器web1192.168.0.40|公网IP2vCPU,4G内存web服务器 项目架构图
GitLab
- 它是一个开源的git堆栈服务器。用于实现代码集中托管
- 分为企业版和CE社区版
- 摆设方式:软件包摆设、容器摆设
摆设GitLab服务器
- 云主机192.168.0.20,远程连接时需要连接其对应的公网IP地址
- 将2024-AI大模型Java全链路工程师环境资料/第四模块/gitlab_zh.tar拷贝到gitlab服务器的/root
- 将2024-AI大模型Java全链路工程师环境资料/第四模块/docker文件夹拷贝到gitlab服务器的/root
- 通过容器摆设GitLab服务
- [root@gitlab ~]# cd /root/docker
- [root@gitlab docker]# dnf -y localinstall *.rpm #安装容器管理软件docker
- [root@gitlab docker]# dnf -y install bash-completion #安装tab键(刷新生效)
- [root@gitlab ~]# systemctl start docker #启动服务
- [root@gitlab ~]# systemctl enable docker #将服务设置为开机自启
复制代码 修改gitlab服务器的的sshd服务端口号为8022,因为gitlab容器也要用到22端口,有冲突。
vim +17是指打开设置文件时,光标直接定位到第17行。
- [root@gitlab ~]# vim +17 /etc/ssh/sshd_config #修改配置文件
- 17 Port 8022
- [root@gitlab ~]# systemctl restart sshd #重启sshd远程管理服务
- #重启之后需要使用远程工具重新连接gitlab服务器,并且指定8022端口号
复制代码 gitlab容器运行需要/etc/resolv.conf文件,如果该文件已存在,则无需创建
- [root@gitlab ~]# touch /etc/resolv.conf
复制代码
- 导入镜像
- 一个镜像可以创建很多容器。镜像是只读的,容器是可以改变的。
- 容器相当于是精简的假造机,可以像假造机一样,对外提供服务。
- [root@gitlab ~]# docker load < /root/gitlab_zh.tar
- [root@gitlab ~]# docker images #查看镜像是否导入
复制代码
- 保障数据完备性
- 为了删容器,不丢失数据,需要把容器需要的数据生存在宿主机上。
- 在哪台主机上启动容器,哪台主机就是宿主机。
- [root@gitlab ~]# mkdir -p /srv/gitlab/{config,logs,data} #创建持久化目录
- [root@gitlab ~]# ls /srv/gitlab/
- config data logs
复制代码
- 创建容器
- -d背景运行
- -h gitlab设置容器的主机名
- –name gitlab是docker ps查看到的容器名
- -p指定发布的端口号,当访问宿主机443/80/22端口时,这样的请求就发给容器的相关端口
- –restart always是开机自启
- -v是映射路径,将容器中指定的路径,映射到宿主机,以便生存容器产生的数据
- 最后的gitlab_zh是镜像名
- [root@gitlab ~]# docker run -d -h gitlab --name gitlab -p 443:443 -p 80:80 -p 22:22 --restart always -v /srv/gitlab/config:/etc/gitlab -v /srv/gitlab/logs:/var/log/gitlab -v /srv/gitlab/data:/var/opt/gitlab gitlab_zh
- [root@gitlab ~]# docker ps #查看容器正在运行的容器
- # 如果一切正常,几分钟后,可以访问http://gitlab服务器的公网ip/ (以自己为准)
- # 例如:http://121.36.66.101/
复制代码 附:如果容启动失败,再次创建有以下错误:
- Error: error creating container storage: the container name "gitlab" is already in use by "ca425e33d7ff2给i他d282cbec1033023851cff285fe9b819ed50d47a08a875372fde". You have to remove that container to be able to reuse that name.: that name is already in use
复制代码 则:
- [root@gitlab ~]# docker rm gitlab
- [root@gitlab ~]# docker run -d -h gitlab --name gitlab -p 443:443 -p 80:80 -p 22:22 --restart always -v /srv/gitlab/config:/etc/gitlab -v /srv/gitlab/logs:/var/log/gitlab -v /srv/gitlab/data:/var/opt/gitlab gitlab_zh
复制代码 设置gitlab
- 第一次登岸‑时,要求改密码。密码需要是复杂密码,如1234.com。修改之后,登岸的用户名是root。
点击头像–>退出,重新登录验证
GitLab中重要的概念
- 用户:为使用gitlab的用户创建的账号。
- 组:用户的聚集,可以为部分创建组。未来可以在项目上为组授权,组中所有的用户都会得到相应的权限。
- 项目:用于生存代码文件的空间。
- 用户、组、项目之间的关系如下
填写截图上的几项后,其他使用默认设置,点生存。
创建好用户后,点击编辑,可以为他/她设置密码:
- 生存修改后,退出当前账号,使用新账号jerry与其密码1234.com登岸测试。
- 第一次登岸时,也是要求修改密码,新密码可以设置与旧密码一样。
- 新建的jerry用户因为权限较小,所以看到的界面,没有root的功能多。
- 创建组,注意,需要使用root账号创建,这里需要切换回root账户
- 将jerry用户加到devops组中,角色是"主程序员"
客户端上传代码到gitlab服务器
- 在客户端develop服务器(192.168.0.10,连接其公网IP地址)上下载项目,编写代码并上传
- [root@develop ~]# dnf -y install git #安装git工具
复制代码 从gitlab服务器复制地址之后,需要将gitlab单词改为自己gitlab服务器的公网IP地址
- ~]# git clone http://121.36.66.101/devops/myproject.git #克隆远程仓库
- [root@develop ~]# ls #本地出现一个myproject目录
- myproject
复制代码 windows客户端也可以使用git clone克隆远程堆栈,提前安装git客户端(安装包在2024-AI大模型Java全链路工程师环境资料/第四模块/cicd中)
如果是刚刚安装的git软件需要首先界说全局设置,方可继续使用(实行一次即可)
- git config --global user.name "jerry"
- git config --global user.email "jerry@tedu.cn"
复制代码
使用develop服务器编写README.txt文件,并上传至远程堆栈
- [root@develop ~]# cd myproject/
- [root@develop myproject]# vim README.md
- Welcome to my beautiful world!
- [root@develop myproject]# git add . #保存到暂存区
- [root@develop myproject]# git commit -m "init data" #提交至本地仓库
- # 将master分支推送到origin仓库。origin是默认仓库名。
- [root@develop myproject]# git push -u origin master
- Username for 'http://192.168.4.20': jerry #用户名
- Password for 'http://jerry@192.168.4.20': 1234.com #密码(输入不显示)
- # 在服务器上刷新web页面,可以看到仓库中已经多出了README.md文件
复制代码 重新操纵编写代码,并提交远程堆栈
- # 将来就可以重得操作:写代码、确认到版本库、上传到服务器
- [root@develop myproject]# cp /etc/hosts .
- [root@develop myproject]# git add .
- [root@develop myproject]# git commit -m "add hosts"
- [root@develop myproject]# git push #不需要再使用-u选项
- Username for 'http://192.168.4.20': jerry
- Password for 'http://jerry@192.168.4.20': 1234.com #密码(输入不显示)
- # 在服务器上刷新web页面,可以看到仓库中已经多出了hosts文件
复制代码 另一个客户端Windows拉取新代码,并且上传自己的代码(需要windows安装好git客户端)
- $ git pull #拉取代码
- remote: Counting objects: 6, done.
- remote: Compressing objects: 100% (4/4), done.
- remote: Total 6 (delta 0), reused 0 (delta 0)
- Unpacking objects: 100% (6/6), 515 bytes | 0 bytes/s, done.
- From http://121.36.66.101/devops/myproject
- * [new branch] master -> origin/master
复制代码 Windows当地堆栈中已经多出了数据
Windows上传数据至远程堆栈,编写win.txt文件,内容为"Here is Windows file."
- $ git add . #提交暂存区
- $ git commit -m 'add Win.txt' #提交本地仓库
- $ git push -u origin master #将master分支推送到origin仓库
- # 在服务器上刷新web页面,可以看到仓库中已经多出了Win.txt文件
复制代码 develop服务器拉取新代码,验证是否可以或许同步Win.txt
- [root@devlop myproject]# git pull
- [root@devlop myproject]# ls #查看多出Win.txt
- hosts README.md Win.txt
- [root@devlop myproject]# cat Win.txt #内容正确
- Here is Windows file.[root@devlop myproject]#
复制代码 CI-CD概述
- CI:连续集成(Continuous Integration)
- CD:连续交付(Continuous Delivery/Deployment)
软件程序上线流程
- 程序员将代码上传到gitlab服务器
- SRE工程师,通过jenkins服务器主动下载gitlab上的代码
- SRE工程师编写主动摆设到服务器上的脚本
安装Jenkins服务器
- jenkins服务器操纵(192.168.0.30,需要远程它的公网IP地址)
- # 安装依赖包
- # jenkins需要通过git下载代码,所以装git。
- # jenkins是java程序,所以装java
- # postfix和mailx是邮件程序,jenkins可以通过它们给管理员发邮件
- [root@jenkins ~]# dnf -y install git postfix mailx java-11-openjdk
复制代码- [root@jenkins ~]# ls #查看是否上传完毕
- jenkins-2.263.1-1.1.noarch.rpm jenkins_plugins.tar.gz
- ~]# dnf -y localinstall jenkins-2.263.1-1.1.noarch.rpm #安装jenkins
- [root@jenkins ~]# systemctl start jenkins #启动jenkins服务
- [root@jenkins ~]# systemctl enable jenkins #将jenkins服务设置为开机自启
- [root@jenkins ~]# ss -nutlp | grep :8080 #查看端口8080是否正常
复制代码
- 访问http://jenkins服务器公网IP:8080,举行初始化
- # 查看初始化密码,每个人的都不一样,请以自己的为准
- [root@jenkins ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
- b9d26edeef714940ab10aaa541081d90
复制代码 把查看到的密码粘贴到文本框中,如下:
使用admin用户,密码123456登录jenkins
设置jenkins
- 安装插件:jenkins的很多功能都是能过插件实现的,好比发邮件、好比中文支持
- [root@jenkins ~]# tar -xf jenkins_plugins.tar.gz
- #拷贝文件的时候,注意选项,-r可以拷贝目录,-p保留权限
- [root@jenkins ~]# cp -rp jenkins_plugins/* /var/lib/jenkins/plugins/
- [root@jenkins ~]# systemctl restart jenkins #重启jenkins服务
- #刷新web页面,如果出现中文,则插件安装成功
复制代码 软件版本管理
- develop服务器操纵
- 可以在git中使用tag标记将某一次commit提交标识为某一版本
- [root@develop ~]# cd myproject/ #进入项目目录
- [root@develop myproject]# git tag #查看标记,默认没有标记
- [root@develop myproject]# git tag 1.0 #将当前提交,标识为1.0
- [root@develop myproject]# git tag #查看标记
- 1.0
- [root@develop myproject]# echo 'hello world' > index.html
- [root@develop myproject]# git add .
- [root@develop myproject]# git commit -m "add index.html"
- [root@develop myproject]# git tag 1.1 #将当前提交,标识为1.1
- # 将本地文件和tag推送到gitlab服务器
- [root@develop myproject]# git push #只推送文件,不推送标记
- [root@develop myproject]# git push --tags
复制代码 在gitlab上查看标记
设置jenkins访问gitlab远程堆栈
- 参数化构建过程中,"名称"是自己界说的变量名,用于标识tag或分支
git堆栈地址,在gitlab上找到myproject堆栈的http地址,注意将gitlab名称改为IP地址
指定分支构建的时候,使用上面步骤创建的变量$web
在jenkins服务器查看内容,查看是否下载乐成
- [root@jenkins ~]# ls /var/lib/jenkins/workspace/myproject/
- hosts index.html README.md Win.txt
复制代码 下载到子目录
- 此时有个问题,1.1版本的代码会覆盖1.0版本的代码,无法实现多个版本代码并存
- 这个问题可以使用jenkins子目录的方式解决
- jenkins下载不同的版本到自己的子目录,不共享雷同目录
新增时,如果没有中文,英文是"checkout to a sub directory"
测试
- [root@jenkins ~]# rm -rf /var/lib/jenkins/workspace/myproject/ #删除之前下载的
复制代码 实行多次构建,构建不同版本
查看下载目录
- [root@jenkins ~]# ls /var/lib/jenkins/workspace/myproject/
- myproject-1.0 myproject-1.1
复制代码 摆设代码到web服务器
主动化摆设流程
- 程序员编写代码,推送到gitlab服务器
- Jenkins服务器从gitlab上下载代码
- Jenkins处置惩罚下载的代码
- 删除下载目录的版本库(.git当地堆栈)
- 将下载的代码打包
- 计算程序压缩包的md5值
- 在Jenkins上安装httpd服务,共享程序压缩包
- web服务器下载软件包,并应用(通过脚本实现)
- 访问测试
设置共享服务器
- [root@jenkins ~]# dnf -y install httpd #安装apache的软件包
- [root@jenkins ~]# mkdir -p /var/www/html/deploy/packages #创建jenkins从gitlab上下载的打包代码存放的目录
- [root@jenkins ~]# chown -R jenkins:jenkins /var/www/html/deploy/ #修改权限,因为是jenkins自动下载的,需要修改存放的权限
- [root@jenkins ~]# systemctl start httpd
- [root@jenkins ~]# systemctl enable httpd
复制代码 设置jenkins把gitlab下载的代码打包
- pkg_dir=/var/www/html/deploy/packages
- cp -r myproject-$web $pkg_dir
- rm -rf $pkg_dir/myproject-$web/.git
- cd $pkg_dir
- tar -zcf myproject-$web.tar.gz myproject-$web
- rm -rf myproject-$web
- md5sum myproject-$web.tar.gz | awk '{print $1}' > myproject-$web.tar.gz.md5
- cd ..
- echo -n $web > ver.txt
复制代码 测试修改的任务
浏览器访问:http://jenkins公网IP/deploy/packages/即可看到打包的代码
web服务主动摆设
- [root@web1 ~]# dnf -y install httpd wget
- [root@web1 ~]# mkdir /var/www/download #存储jenkins主机上下载的应用代码
- [root@web1 ~]# mkdir /var/www/deploy #部署应用代码
- [root@web1 ~]# systemctl start httpd #启动httpd服务
- [root@web1 ~]# systemctl enable httpd #将httpd服务设置为开机自启
- [root@web1 ~]# ss -ntulp | grep :80 #查看80端口是否正常
复制代码 编写主动上线脚本
- 下载软件包
- 检查软件包是否破坏
- 解压、摆设到web服务器
- [root@web1 ~] # vim web.py
- import os
- import requests
- import hashlib
- import tarfile
- def has_new_ver(web1_ver_path, ver_url):
- # web1_ver_path 为应用服务器web1主机的当前版本文件路径
- # 如果文件不存在,返回True, 提示没有新版本
- if not os.path.exists(web1_ver_path):
- return True
- # 当web1_ver_path存在时,先获取当前应用的版本号
- with open(web1_ver_path, mode="r") as fr:
- local_ver = fr.read()
- # 通过requests获取jenkins服务器上的最新版本号
- r = requests.get(ver_url)
- # 当web1上的版本号和Jenkins服务器上的版本号不相等时,返回True, 即有新的版本
- if local_ver != r.text:
- return True
- return False
- # 声明函数file_ok(), 功能:如果下载的包文件未损坏,则返回True,否则返回False
- def file_ok(web1_tar_path, jenkins_tar_md5_url):
- m = hashlib.md5()
- with open(web1_tar_path, mode="rb") as fw:
- while True:
- data = fw.read(4096)
- if len(data) == 0:
- break
- m.update(data)
- # jenkins_tar_md5_url 为jenkins服务器上的压缩包的md5值文件链接地址
- r = requests.get(jenkins_tar_md5_url)
- if m.hexdigest() == r.text.strip():
- # 相等,代表文件未损坏,返回True
- return True
- return False
- # 声明函数deploy(), 功能:用于部署软件到 web1 服务器
- def deploy(web1_tar_path, web1_deploy_dir, dest):
- tar = tarfile.open(web1_tar_path) # 打开压缩包web1_tar_path
- tar.extractall(path=web1_deploy_dir) # 解压到web1_deploy_dir目录下
- tar.close() # 关闭tar
- # 获取web1_tar_path变量中,最后一个'/',右边的内容,然后做切片,去除".tar.gz",只留下文件名
- file_name = os.path.basename(web1_tar_path)[:-7]
- # 将变量web1_deploy_dir和变量file_name拼接在一起
- app_dir = os.path.join(web1_deploy_dir, file_name)
- # 创建链接,如果软链接dest存在,删除软连接,然后为app_dir创建新的软链接
- if os.path.exists(dest):
- os.remove(dest)
- os.symlink(app_dir, dest)
- if __name__ == "__main__":
- ### 判断jenkins服务器上是否有新版本
- # ver_url 为jenkins服务器的当前版本文件路径
- # web1_ver_path 为应用服务器web1主机的当前版本文件路径
- # 这里的地址需要求改为自己的IP地址
- ver_url = "http://120.46.84.196/deploy/ver.txt"
- web1_ver_path = "/var/www/deploy/ver.txt"
- if not has_new_ver(web1_ver_path, ver_url):
- print("no new version~")
- exit(1)
- # ==========================================
- # 如果服务器上有新版本,则下载新版本
- # r.text 为jenkins服务器的当前版本内容
- # jenkins_tar_url 为jenkins服务器上的压缩包链接地址
- # web1_tar_path 为应用服务器web1主机的压缩包路径
- # 这里的地址需要修改为自己的IP地址
- r = requests.get(ver_url)
- jenkins_tar_url = f"http://120.46.84.196/deploy/packages/myproject-{r.text}.tar.gz"
- web1_tar_path = f"/var/www/download/myproject-{r.text}.tar.gz"
- with open(web1_tar_path, mode="wb") as fw:
- fw.write(requests.get(jenkins_tar_url).content)
- # 校验下载的软件包是否损坏,如果损坏则删除 os.remove()
- # jenkins_tar_md5_url 为jenkins服务器上的压缩包的md5值文件链接地址
- jenkins_tar_md5_url = jenkins_tar_url + ".md5"
- if not file_ok(web1_tar_path, jenkins_tar_md5_url):
- print("File has been broken~")
- os.remove(web1_tar_path)
- exit(2)
- # =========================================
- web1_deploy_dir = '/var/www/deploy'
- dest = '/var/www/html/current'
- deploy(web1_tar_path, web1_deploy_dir, dest)
- # 更新本地的版本文件
- if os.path.exists(web1_ver_path):
- os.remove(web1_ver_path)
- with open(web1_ver_path, mode="w") as fw:
- fw.write(requests.get(ver_url).text)
复制代码- [root@web1 ~]# python3 web.py
- [root@web1 html]# ls /var/www/deploy
- myproject-1.1 ver.txt
复制代码 浏览器访问http://web服务器公网IP/current 可以看到摆设的文件页面
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |