最近公司开始做新项目,项目组叫帮把开发环境搭建。为了介绍后面减少少各种人海提交和代价检查,
同时也把未来的k8s容器化部署考虑进行,于是就学习了一把,这里把笔记下来。
如有问题可以前往个人主页https://www.qingxueline.com
项目源码下载:https://github.com/qingxueline/qxl-web
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates
接下来,安装Postfix以发送通知电子邮件。如果要使用其他解决方案发送电子邮件,请跳过此步骤并在安装GitLab后配置外部SMTP服务器。
sudo apt-get install -y postfix
在Postfix安装期间,可能会出现配置屏幕。选择“Internet Site”并按Enter键。使用服务器的外部DNS作为“邮件名称”,然后按Enter键。如果出现其他屏幕,请继续按Enter键接受默认值。
添加GitLab软件包到系统存储库
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
接下来,安装GitLab包。
sudo apt-get install gitlab-ce
vim /etc/gitlab/gitlab.rb
改:external_url 'http://gitlab.example.com'
为:external_url 'http://192.168.98.101:7777'
gitlab-ctl reconfigure
sudo gitlab-ctl start # 启动所有 gitlab 组件;
sudo gitlab-ctl stop # 停止所有 gitlab 组件;
sudo gitlab-ctl restart # 重启所有 gitlab 组件;
sudo gitlab-ctl status # 查看服务状态;
sudo gitlab-ctl reconfigure # 重新编译gitlab的配置;
sudo gitlab-rake gitlab:check SANITIZE=true --trace # 检查gitlab;
sudo gitlab-ctl tail # 查看日志;
sudo gitlab-ctl tail nginx/gitlab_access.log
sudo gitlab-ctl tail unicorn 监控unicorn
在您第一次访问时,您将被重定向到密码重置屏幕。提供初始管理员帐户的密码,您将被重定向回登录屏幕。使用默认帐户的用户名root
登录。
访问地址:http://192.168.98.101:7777
默认情况下,NGINX将侦听指定的端口external_url
或隐式使用正确的端口(HTTP为80,HTTPS为443)。如果您在反向代理后面运行GitLab,您可能希望将侦听端口覆盖为其他内容。例如,要使用端口7786:
nginx['listen_port'] = 7786
此时nginx就会监听7786,当执行gitlab-ctl reconfigure
时就会自动加载进行nginx服务配置里面/var/opt/gitlab/nginx/conf/gitlab-http.conf
.
如nginx就会自动更改为如下:
server {
#listen *:80;
listen *:7777;
}
注意:在修改vim /etc/gitlab/gitlab.rb这个配置文件的
external_url ‘http://192.168.98.101:7777’
属性时,如果加了端口号,执行重新加载时。一样会自动对/var/opt/gitlab/nginx/conf/gitlab-http.conf的端口进行修改,效果和
nginx['listen_port'] = 7786
一样,但如果已经在external_url配置了,就没必要在nginx['listen_port'] = 7786
配置,他们可以有一个执行顺序的问题,我没有进行具体验证。
如果您希望通过SMTP服务器而不是通过Sendmail发送应用程序电子邮件,请将以下配置信息添加到 /etc/gitlab/gitlab.rb
并运行gitlab-ctl reconfigure
。
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.server"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "smtp user"
gitlab_rails['smtp_password'] = "smtp password"
gitlab_rails['smtp_domain'] = "example.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
# If your SMTP server does not like the default 'From: gitlab@localhost' you
# can change the 'From' with this setting.
gitlab_rails['gitlab_email_from'] = '[email protected]'
gitlab_rails['gitlab_email_reply_to'] = '[email protected]'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.exmail.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "[email protected]"
gitlab_rails['smtp_password'] = "password"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = '[email protected]'
gitlab_rails['smtp_domain'] = "exmail.qq.com"
您可以使用Rails控制台验证GitLab正确发送电子邮件的能力。在GitLab服务器上,执行gitlab-rails console
以进入控制台。然后,您可以在控制台提示符处输入以下命令以使GitLab发送测试电子邮件:
Notify.test_email('[email protected]', 'Message Subject', 'Message Body').deliver_now
默认,使用 Postfix 发送邮件
service postfix start
chkconfig postfix on
# 停止gitlab
sudo gitlab-ctl stop
# 查看进程
ps -e | grep gitlab
# 删除所有包含gitlab的文件及目录
find / -name gitlab | xargs rm -rf
# 卸载
sudo apt-get remove gitlab-ce
# 检查还有没有卸载的gitlab相关软件
dpkg --get-selections | grep gitlab
gitlab-ce deinstall
# 再执行
sudo apt-get --purge remove gitlab-ce
sudo rm -rf /opt/gitlab/embedded/service/gitlab-rails
持续交付工具目前使用比较多的是Jenkins和git-runner,目前新版本Gitlab本身也提供了CI/CD的,只需要安装git-runner和配置gitlab-ci.yml文件就能实现持续交付,如果在小团队开发中,这个不需要运维的接入就可以很方便的实现CI/CD。
gitlab-runner配置简单,很容易与gitlab集成。当新建一个项目的时候,不需要配置webhook回调地址,也不需要同时在jenkins新建这个项目的编译配置,只需在工程中配置gitlab-ci.yml文件,就可以让这个工程可以进行编译。
gitlab-runner没有web页面,但编译的过程直接就在gitlab中可以看到,不需要像jenkins进入web控制台查看编译过程。
gitlab-runner仅仅是提供了一个编译的环境而已,全部的编译都通过shell脚本命令进行。当然,jenkins也可以是全部的编译都通过shell脚本命令进行。
jenkins的好处就是编译服务和代码仓库分离,而且编译配置文件不需要在工程中配置,如果团队有开发、测试、配置管理员、运维、实施等完整的人员配置,那就采用jenkins,这样职责分明。不仅仅如此,jenkins依靠它丰富的插件,可以配置很多gitlab-ci不存在的功能,比如说看编译状况统计等。如果团队是互联网类型,讲究的是敏捷开发,那么开发=devOps,肯定是采用最便捷的开发方式,推荐gitlab-ci。
下面讲解的主要是使用Jenkins实现CI/CD。
下面面几张图是实际生产环境中会使用到的一些部署方案,在本文中,我们不会搞那么复杂。直接使用gitlab+spingboot+jenkins+maven来实现,把重要的东西记录下来,然后让整个环境运行起来。
在搭建环境前我们我们需要明白正常情况下是不会安装在一台主机的,他们都是分表部署的,所以我们这里也是这样去模拟。
我安装了3台主机分别如下:
主机 | 端口 | 作用 |
---|---|---|
192.168.98.101 | 7777 | gitlab代码仓库 |
192.168.98.102 | 8080 | jenkins服务端口 |
192.168.98.102 | 8099 | qx-web.jar程序端口(测试环境) |
192.168.98.103 | 8855 | docker仓库,本案例不使用这台服务(生产环境) |
上面的主机我使用的是ubuntu的系统。
工作流程如下:
流程说明:
程序员提交代码到gitlab,gitlab触发推送事件,推送事件会让钩子程序通知jenkins,jenkins收到通知后再gitlab仓库获取到最新的版本代码,然后jenkins先触发构建(job)maven插件打包(当然也可以触发其他的,这里可以自选的,看你喜欢什么样的方式生成jar包了),maven完成打包后继续执行第二个构建(job)
这个job我是写了个shell,让它启动qxl-web.jar,如果成功那么开发人家就可以访问了,表示工程测试环境运行正常,此时我们就可以做构建操作操作,必须进行代码合并、生产镜像、推送到Harbor、推送到k8s、推送到生产环境等,看个人业务需求。
温馨提醒:
业务的部署需要使用到大量的shell和liunx命令,如果不熟悉shell,那么很多东西你是不会懂怎么去操作的,所以不懂shell请自行去脑补,否则就不能达到为所欲为了。同时也要熟悉使用
Jenkinsfile
,不过我这里也没有使用。Using a Jenkinsfile
各主机所需要的基础组件如下:
主机 | 作用 |
---|---|
192.168.98.101 | gitlab安装包 |
192.168.98.102 | jenkins.war、apache-tomcat-8.0+、JDK1.8+、maven3.5+、git2.0+ |
主要192.168.98.102的基础组件个人建议使用手动安装的方式安装,这样方便设置环境变量。自动安装的方式个人不推荐。
Tomcat、JDK、Maven、Git的安装我就不在这里说明了,除了Git,其他我使用的都是手动安装,所以需要手动的设置环境变量。
为什么git我没有使用手动安装,其实git手动安装需要手动安装会需要用到很多的依赖,安装成功后能够在机器上使用,但是在Jenkins上就出现各种莫名其妙的错误,很是郁闷,所以就干脆使用自动安装了。
使用自动安装如果要找git的安装位置可以使用
which -a git
查看,后续在Jenkins配置环境变量要用到。
全局环境变量的设置是在操作系统的etc文件下,可以使用一下命令打开:
vim etc/profile
如果你想加入自己的环境变量,那么就在文件的最底部加入即可,如:
if [ "${PS1-}" ]; then
if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
# The file bash.bashrc already sets the default PS1.
# PS1='\h:\w\$ '
if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi
else
if [ "`id -u`" -eq 0 ]; then
PS1='# '
else
PS1='$ '
fi
fi
fi
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
# 以下是自动定义的环境变量
export MAVEN_HOME=/usr/local/apache-maven-3.6.1
export JAVA_HOME=/usr/lib/java
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${MAVEN_HOME}/bin:${JAVA_HOME}/bin:$PATH
环境变量设置保存后默认是未生效的,如果要环境变量生效需要使用以下命令
. etc/profile或者source etc/profile
备注:
我当前所在的目录是
/
目录下,如果你是etc目录就是写. profile
就可以了。
通过上面的部署把基础组件搭建好之后,那么接下来就是要让jenkins跑起来了,然后跑呢?其实很简单就是直接将jenkins.war
放到Tomcat的apache-tomcat-9.0.22/webapps
目录下即可,因为jenkins.war
是使用java写的,放到apache-tomcat-9.0.22/webapps
目录下会自动生成class文件,然后按照正常的启动就行了。
启动文件在apache-tomcat-9.0.22/bin/
下,在该目录下执行以下命令即可
./startup.sh
说明:
apache-tomcat-9.0.22
是我解压后的版本生成的目录名。完整的路径是/home/acc/apache-tomcat-9.0.22
表示是我的安装位置,个人可以自行修改。
在启动Tomcat时记得修改下apache-tomcat-9.0.22/conf/
下的server.xml
的
标签,加入要部署的项目。
我的修改如下:
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
<Context path="/" docBase="./jenkins" reloadable="true"/>
Host>
端口号什么的我都保持了默认的。这样就能够启动了,启动返回访问http://192.168.98.102:8080/
就会到Jenkins的工作台了,第一次进入需要解锁Jenkins,解锁网页上提示的红色路径字去访问查看解锁密码即可。
进入后创建用户名和密码、安装默认推荐的插件。
全局工具配置是用来配置我们的基础组件工具,如果Git、JDK、Maven等。这些变量都是根据自己安装软件的具体位置去定义的,所以每个人的定义方式是不一样的,我就按照我定义的给做个说明。
Maven settings 配置
我的Maven安装在/usr/local/
目录下,如:/usr/local/apache-maven-3.6.1
。
所以在选择配置的时候设置settings
如下:
默认 settings 提供:选择【文件系统中的 settings 文件】,文件路径为:/usr/local/apache-maven-3.6.1/conf/settings.xml
默认全局 settings 提供:选择【文件系统中全局的 settings 文件】,文件路径为:/usr/local/apache-maven-3.6.1/conf/settings.xml
如图:
**Maven **
这里配置的是Maven 的环境变量,如何你已经配置了环境变量可以通过echo $MAVEN_HOME
获取,然后拷贝进去即可。
JDK
jdk需要新增一个jdk,别名可以随便取,环境变量就必须按照系统设置的去填,如果你已经设置了环境变量那么可以通过echo $JAVA_HOME
查看到当前系统的环境变量,然后把路径添加进去即可。
Git
git是用来拉取代码和更新代码的,名字自己随便取,Path to Git executable
s是git的执行路径,因为我是自动安装的,所以通过which -a git
可以在系统中查询到,然后复制进去即可。
新建任务就是建立一个和我们Gilab仓库一样名字的项目名称,然后进入项目里面进行插件配置。
[外链图片转存失败(img-pxbUGP5P-1564938914467)(D:\project\文档\z_images\1564765971254.png)]
添加项目名称【qxl-web】>【配置】分别对【源码管理】、【构建触发器】、【构建环境】、【构建】、【构建后操作】进行配置。
源码管理
源码管理我们使用的是git来获取远程仓库的源码,所以需要填写远程仓库名和访问远程仓库的账号密码,如果是配置了ssh秘钥,可以通过ssh秘钥访问。
构建触发器
构建触发器,就是在外部访问到这个触发器的时候就会触发构建流程,我这里设置了2种触发方式,一种是触发远程构建 (例如,使用脚本)
,另外一种是GitLab webhook
触发。
1)、触发远程构建 (例如,使用脚本):
这种触发器,需要自定义一个身份验证令牌
,身份令牌是可以随便填写的,然后放在token=xxxxx后面,通过拼接成url,通过脚本或者浏览器又或者curl命令去访问。
原文提示是:
Use the following URL to trigger build remotely: JENKINS_URL/job/qxl-web/build?token=TOKEN_NAME 或者 /buildWithParameters?token=TOKEN_NAME
Optionally append &cause=Cause+Text to provide text that will be included in the recorded build cause.
上面的大概意思就是JENKINS_URL
j就是我们jenkins访问其的地址+/job/qxl-web/build?token=TOKEN_NAME,如果需要加入提交说明,那么可以再拼接**&cause=Cause+Text**
那么根据我这个实际情况,访问地址可以是这样的2种,
http://192.168.98.102:8080/job/qxl-web/build?token=m3XMjwi
http://192.168.98.102:8080/job/qxl-web/build?token=m3XMjwi&cause=test
以上地址直接在浏览器、脚本、curl等其他能够访问的地方访问就能触发构建。
2)、Build when a change is pushed to GitLab.
Build when a change is pushed to GitLab. GitLab webhook URL: http://192.168.98.102:8080/project/qxl-web
意思就是程序员将项目推送到Gitlab时就会触发构建,所以使用这个触发器的时候需要在Gitlab上的GitLab webhook配置URL为 http://192.168.98.102:8080/project/qxl-web。同时还要配置Secret token
,Secret token可以点开高级下面生成。
下面这张图是Gitlab的配置图,URL和Secret Token对应上jenkins的URL和Secret Token即可。
上面的页面可以通过进入个人项目点击具体项目,然后找到项目下的【Setting】>【Integrations】进行配置。
构建
前面的构建环境我就不说了,根据根据自己的需求进行勾选,我就使用默认的。这里直接进入构建。
构建这一步很重要,一般是通过脚本和命令完成构建操作构建工作,程序运行、测试工作。这里我使用了一个maven命令进行打包,使用了一个shell脚本进行启动程序。
start.sh脚本内容如下
#!/bin/bash
# 必须定义,如果不定义jenkins会在一个job执行完成后将tomcat程序杀死,造成程序无法再启动
export BUILD_ID=dontKillMe
# 定义变量
JAR_NAME="qxl-web.jar"
JAR_FILE=~/.jenkins/workspace/qxl-web/target/${JAR_NAME}
execute_target=~/qxl-web/
# 在部署前杀死上一次的程序
pid=$(ps -ef | grep ${JAR_NAME} | grep -v grep | awk '{print $2}')
if [ -n "${pid}" ]; then
echo "kill -9 pid:"${pid}
# grep ${JAR_NAME} 查询一个程序
# grep -v grep 去除 grep
# awk '{print $2}' 获取第二列数据
# xargs kill -9 xargs可以将返回的数据传到给下一个命令使用
ps -ef | grep ${JAR_NAME} | grep -v grep | awk '{print $2}' | xargs kill -9
fi
# 判定目录和文件是否存在
if [ ! -f ${JAR_FILE} ]; then
echo "qxl-web.jar not exist!"
exit
else
if [ ! -d ${execute_target} ]; then
echo "create directory:${execute_target}"
mkdir -p ${execute_target}
fi
cp ${JAR_FILE} ~/qxl-web/${JAR_NAME}
fi
# 部署新的程序
cd ~/qxl-web/ || exit
echo "Go to the execution directory >> $(pwd)"
echo "Startup SpringBoot Application"
nohup java -jar ${JAR_NAME} >consoleMsg.log 2>&1 &
完成到这里,我们提交代码就会自动的执行代码的构建和启动了,执行过程会和下图一样就表示环境搭建成功。
构建后操作就不写了,大概流程就这样了。
更新使用文档请参考官网:https://jenkins.io/zh/doc/pipeline/tour/hello-world/
常见问题是在这个篇幅中遇到的一些问题,同时已经有了解决方案的,如果你也遇到了问题,并且已经解决欢迎联系我进行提交,方便日后的小伙伴一起查阅。
Running handlers:
There was an error running gitlab-ctl reconfigure:
gitlab_sysctl[kernel.shmall] (postgresql::enable line 66) had an error: Mixlib::ShellOut::ShellCommandFailed: execute[load sysctl conf kernel.shmall] (/opt/gitlab/embedded/cookbooks/cache/cookbooks/package/resources/gitlab_sysctl.rb line 46) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '255'
---- Begin output of sysctl -e --system ----
STDOUT: * Applying /etc/sysctl.d/10-console-messages.conf ...
kernel.printk = 4 4 1 7
* Applying /etc/sysctl.d/10-ipv6-privacy.conf ...
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
* Applying /etc/sysctl.d/10-kernel-hardening.conf ...
kernel.kptr_restrict = 1
* Applying /etc/sysctl.d/10-link-restrictions.conf ...
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/10-magic-sysrq.conf ...
kernel.sysrq = 176
* Applying /etc/sysctl.d/10-network-security.conf ...
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
* Applying /etc/sysctl.d/10-ptrace.conf ...
kernel.yama.ptrace_scope = 1
* Applying /etc/sysctl.d/10-zeropage.conf ...
vm.mmap_min_addr = 65536
* Applying /usr/lib/sysctl.d/50-default.conf ...
net.ipv4.conf.all.promote_secondaries = 1
net.core.default_qdisc = fq_codel
* Applying /etc/sysctl.d/90-omnibus-gitlab-kernel.sem.conf ...
* Applying /etc/sysctl.d/90-omnibus-gitlab-kernel.shmall.conf ...
kernel.shmall = 4194304
* Applying /etc/sysctl.d/90-omnibus-gitlab-kernel.shmmax.conf ...
kernel.shmmax = 17179869184
* Applying /etc/sysctl.d/90-omnibus-gitlab-net.core.somaxconn.conf ...
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.conf ...
STDERR: sysctl: cannot open "/etc/sysctl.d/90-omnibus-gitlab-kernel.sem.conf": No such file or directory
sysctl: cannot open "/etc/sysctl.d/90-omnibus-gitlab-net.core.somaxconn.conf": No such file or directory
---- End output of sysctl -e --system ----
Ran sysctl -e --system returned 255
解决方法:
vim /etc/gitlab/gitlab.rb
找到 unicorn['port'] = 8080,将8080修改为9090,之后重新加载配置文件and重启
gitlab-ctl reconfigure
sudo gitlab-ctl restart
如果是在使用脚本启动程序的时候程序启动不起来,可以通过在脚本加入下面的变量进行解决。
解决方法:
# 必须定义,如果不定义jenkins会在一个job执行完成后将tomcat程序杀死,造成程序无法再启动
export BUILD_ID=dontKillMe