1 基础环境
两条腾讯云主机:124.221.94.200(4c8g)/ 175.178.179.178(2c4g) centos7
-
124.221.94.200下安装如下工具
jdk-8u321-linux-x64.tar.gz
git version 1.8.3.1
apache-maven-3.6.3-bin.tar.gz
jenkins
ansible -
175.178.179.178下安装jdk即可
2 安装jdk1.8
2.1下载jdk安装包
https://www.oracle.com/java/technologies/downloads/
登录后,获取下载连接
使用wget下载安装包到/root/tools目录下
mkdir -p /root/tools && cd /root/tools
wget https://download.oracle.com/otn/java/jdk/8u321-b07/df5ad55fdd604472a86a45a217032c7d/jdk-8u321-linux-x64.tar.gz?AuthParam=1646964063_05c1166d796de42a81bc806f5abe6237
2.2 解压安装包到tools目录
tar -zxvf jdk-8u321-linux-x64.tar.gz?AuthParam=1646964063_05c1166d796de42a81bc806f5abe6237
重命名一下
mv jdk1.8.0_321 jdk1.8
2.3 添加环境变量
vi /etc/profile
# 将如下代码加入文件末尾
export JAVA_HOME=/root/tools/jdk1.8
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
刷新一下,查看Java版本
source /etc/profile
jdk安装成功!
3 安装git
3.1 安装
yum -y install git
3.2 查看版本
git安装成功!
4 安装maven
4.1下载maven安装包
cd /root/tools
wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
4.2 解压并重命名
tar -xf apache-maven-3.6.3-bin.tar.gz
mv apache-maven-3.6.3 maven3.6
4.3 添加环境变量
vi /etc/profile
# 将如下代码加入文件末尾
export PATH=$PATH:/root/tools/maven3.6/bin
刷新一下,查看maven版本
source /etc/profile
mvn -version
备注:maven的运行依赖Java环境,所以需要安装jdk
maven安装成功!
5 安装gitlab
5.1 安装依赖软件
yum -y install policycoreutils openssh-server openssh-clients postfix
5.2设置postfix开机自启,并启动,postfix支持gitlab发信功能
systemctl enable postfix && systemctl start postfix
5.3下载gitlab安装包,然后安装
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-8.0.0-ce.0.el7.x86_64.rpm
rpm -ivh gitlab-ce-8.0.0-ce.0.el7.x86_64.rpm
5.4修改gitlab配置文件指定服务器ip和自定义端口
#编辑配置文件
vim /etc/gitlab/gitlab.rb
#修改访问URL
#格式:external_url 'http://ip:端口'
external_url 'http://192.168.1.1:8001'
#配置时区
gitlab_rails['time_zone'] = 'Asia/Shanghai'
退出并保存
ps:注意这里设置的端口不能被占用,默认是8080端口,如果8080已经使用,请自定义其它端口,并在防火墙设置开放相对应得端口。
开启腾讯云端口,这里直接开启了8000到10000的端口
5.5重置并启动GitLab
gitlab-ctl reconfigure
gitlab-ctl restart
提示“ok: run:”表示启动成功。
5.6访问 GitLab页面
如果没有域名,直接输入服务器ip和指定端口进行访问,初始账户: root 密码: 5iveL!fe
第一次登录修改密码
ps:第一次访问,可能会报响应缓慢,刷新下即可
6 安装jenkins
6.1 添加Jenkins库到yum库,Jenkins将从这里下载安装。
wget https://pkg.jenkins.io/redhat-stable/jenkins-2.332.1-1.1.noarch.rpm
rpm -ivh jenkins-2.332.1-1.1.noarch.rpm
6.2 修改端口号
# 修改内容如下:
JENKINS_USER="root"
JENKINS_PORT="8002"
6.3 启动jenkins
service jenkins start/stop/restart 或者 systemctl start jenkins
启动失败
查看原因
解决方案
建立Java软连接
ln -s /root/tools/jdk1.8/bin/java /usr/bin/java
# jenkins默认用户为jenkins,因此还需为jdk设置开放权限
[root@VM-4-4-centos tools]# service jenkins start
Starting jenkins (via systemctl): [ OK ]
6.4 修改镜像源
编辑文件vim /var/lib/jenkins/hudson.model.UpdateCenter.xml将其中的url替换为https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json,保存退出
vim /var/lib/jenkins/hudson.model.UpdateCenter.xml
重启jenkins服务
service jenkins restart
6.5 打开jenkins
在浏览器中访问 :http://ip:8002/
首次进入会要求输入初始密码如下图,
初始密码在:/var/lib/jenkins/secrets/initialAdminPassword
选择“Install suggested plugins”安装默认的插件,下面Jenkins就会自己去下载相关的插件进行安装。
安装时部分插件会安装不成功,多重试几次即可
6.6 彻底卸载jenkins
systemctl stop jenkins.service
rpm -e jenkins
rpm -qa | grep jenkins # 查看是否还有jenkins依赖,有就删除
rm -rf /etc/sysconfig/jenkins.rpmsave
rm -rf /var/cache/jenkins/
rm -rf /var/lib/jenkins/
rm -rf /var/log/jenkins
rm -rf /usr/lib/jenkins
## 另一种卸载方式
rpm -e jenkins
rpm -ql jenkins # 查看是否已卸载
find / -iname jenkins | xargs -n 1000 rm -rf # 删除残留文件
7 安装ansible
7.1 安装
yum install epel-release -y
yum install ansible -y
7.2 查看是否安装成功
ansible --version
8 自动部署一个springboot项目
8.1 生成一个springboot项目
https://start.spring.io/
8.2 修改pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<!--开发环境-->
<profile>
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--测试环境-->
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
<profile>
<id>uat</id>
<properties>
<profiles.active>uat</profiles.active>
</properties>
</profile>
<!--shpfm测试环境-->
<profile>
<id>shpfm</id>
<properties>
<profiles.active>shpfm</profiles.active>
</properties>
</profile>
<profile>
<id>pfm</id>
<properties>
<profiles.active>pfm</profiles.active>
</properties>
</profile>
<!--生产环境-->
<profile>
<id>pro</id>
<properties>
<profiles.active>pro</profiles.active>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 资源根目录排除各环境的配置,防止在生成目录中多余其它目录 -->
<excludes>
<exclude>dev/**/*</exclude>
<exclude>test/**/*</exclude>
<exclude>pro/**/*</exclude>
<exclude>uat/**/*</exclude>
<exclude>pfm/**/*</exclude>
<exclude>shpfm/**/*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources/${profiles.active}</directory>
</resource>
</resources>
<finalName>demo-${profiles.active}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.example.demo.DemoApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-war</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
<destFileName>demo-${profiles.active}.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>playbook/roles/task/files/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
8.3 创建ansible-playbook脚本
按照如下目录创建playbook文件
playbook/group_vars/dev内容如下:
jarpath : /opt/demo/
jar : demo-dev.jar
jarname : demo
playbook/group_vars/uat内容如下:
jarpath : /opt/demo/
jar : demo-uat.jar
jarname : demo
playbook/group_vars/sit内容如下:
jarpath : /opt/demo/
jar : demo-sit.jar
jarname : demo
playbook/roles/task/handlers/main.yml 内容为空
playbook/roles/task/meta/main.yml 内容为空
playbook/roles/task/tasks/main.yml 内容如下:
- name : stop jar
shell : ps -ef |grep "{{ jarname }}"|grep -v "grep"|awk '{print$2}'| xargs kill -9
ignore_errors: True
- name : clean files
file : path={{ item }} state=absent
with_items:
- "{{ jarpath }}{{ jar }}"
- name : upload jar
copy : src={{ jar }} dest={{ jarpath }}{{ jar }} owner=root group=root mode=0755
- name: mv java
shell: chdir="{{ jarpath }}" su -c "mv {{ jar }} {{ jarname }}.jar" root
- name : start jar
shell : 'chdir="{{ jarpath }}" ./fundsboot.sh start {{ jarname }}'
playbook/roles/task/templates/main.yml 内容为空
playbook/roles/task/vars/main.yml 内容为空
playbook/ansible.cfg
[defaults]
remote_user=root
host_key_checking=False
playbook/dev
[dev]
175.178.179.178 ansible_ssh_private_key_file=/root/.ssh/WL_DEV ansible_ssh_user=root
playbook/sit
[sit]
175.178.179.178 ansible_ssh_private_key_file=/root/.ssh/WL_DEV ansible_ssh_user=root
playbook/site.yml
- hosts :
- all
roles :
- task
playbook/uat
[uat]
175.178.179.178 ansible_ssh_private_key_file=/root/.ssh/WL_DEV ansible_ssh_user=root
8.4 将demo上传至gitlab
8.5 配置jenkins流水线脚本
流水线脚本
node {
environment{
envs="$ENV"
branch="$BRANCH"
action="$ACTION"
}
stage('Preparation') {
envs="$ENV"
println "发布环境: " + envs
if(!envs){
error " ############ ERROR: 必须选择发布环境!"
}
branch="$BRANCH"
println "发布分支: " + branch
if(!branch){
error " ############ ERROR: 必须输入发布分支!"
}
action="$ACTION"
println "发布动作: " + action
if(!action){
error " ############ ERROR: 必须选择发布动作!"
}
}
stage('Check out SCM') {
println " ############# 从Git服务器拉取项目代码 ############"
parentGit="http://124.221.94.200:10246/Musi/demo.git"
branchName = "*/" + branch
println branchName
println parentGit
checkout([$class: 'GitSCM', branches: [[name: branchName]], userRemoteConfigs: [[credentialsId: 'gitpassword', url: parentGit]]])
}
stage('Packaging') {
println " ############# 编译打包项目代码 ###########"
//apps_array = apps.split(",")
//mvnD="-Dmaven.test.skip=true -DskipTests"
if(envs == "test"){
sh '/root/myspace/tools/maven3.6/bin/mvn clean package -Ptest -DskipTests -U'
}else if(envs == "uat"){
sh '/root/myspace/tools/maven3.6/bin/mvn clean package -Puat -DskipTests -U'
}else if(envs == "pfm"){
sh '/root/myspace/tools/maven3.6/bin/mvn clean package -Ppfm -DskipTests -U'
}else if(envs == "shpfm"){
sh '/root/myspace/tools/maven3.6/bin/mvn clean package -Pshpfm -DskipTests -U'
}else if(envs == "pro"){
sh '/root/myspace/tools/maven3.6/bin/mvn clean package -Ppro -DskipTests -U'
}
archiveArtifacts 'playbook/roles/task/files/*.jar'
}
stage('Deployment') {
if(envs != "pro"){
if(action == "Deploy"){
println " ############# 部署项目代码到应用服务器 ###########"
sh "/usr/bin/ansible-playbook -i playbook/" + envs + " playbook/site.yml"
}
}
}
}
添加gitlab登陆凭据
8.6 将应用发布至175.178.179.178
在jenkins&ansible所在服务器124.221.94.200生成ssh公私钥
ssh-keygen
将公钥拷贝至175.178.179.178
ssh-copy-id root@175.178.179.178
重命名124.221.94.200 目录下 /root/.ssh/id_rsa
mv /root/.ssh/id_rsa /root/.ssh/WL_DEV
chmod 600 /root/.ssh/WL_DEV
175.178.179.178服务器创建如下目录
mkdir -p /opt/demo
创建启动脚本 /opt/demo/fundsboot.sh,内容如下:
#!/bin/bash
JAVA=$(which java)
JAVA_OPTIONS="-server -Xms4g -Xmx4g -Xmn3g -XX:MetaspaceSize=768m -XX:MaxMetaspaceSize=768m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/$2-heapdump.hprof"
app_name=$2
jar_file="${app_name}.jar"
profiles_active="-Dspring.profiles.active=test"
config_env="-Dwdph.config.env=UAT"
host_ip=$(/sbin/ifconfig -a|grep inet|grep 127.0.0.1|awk '{print $2}'|tr -d "addr:")
config_hostIp="-Dserver.host.ip=$host_ip"
WDPH_ENV="$profiles_active $config_env $config_hostIp"
echo "############ 应用服务启动模板 ####################"
echo "sh wdph-loan-api-center.sh start|stop|restart|status 服务名"
echo "#################################################"
#echo $WDPH_ENV
#echo $log_dir
#echo $1
#echo $2
#echo $app_name
if [ "$1" = "" ];
then
echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m"
exit 1
fi
if [ "$2" = "" ];
then
echo -e "\033[0;31m 未输入应用名 \033[0m"
exit 1
fi
function start()
{
count=`ps -ef |grep java|grep $app_name|grep -v grep|wc -l`
if [ $count != 0 ];then
echo "$app_name is running..."
else
echo $JAVA $JAVA_OPTIONS $WDPH_ENV -jar ${jar_file}
nohup $JAVA $JAVA_OPTIONS $WDPH_ENV -jar ${jar_file} &>/dev/null &
#nohup $JAVA $JAVA_OPTIONS -jar ${jar_file} > ${log_file} 2>&1 &
#echo -e "Start $SpringBoot success...Please see the detail log "
fi
}
function stop()
{
echo "####################### Stop $app_name ############################"
boot_id=`ps -ef |grep java|grep $app_name|grep -v grep|awk '{print $app_name}'`
count=`ps -ef |grep java|grep $app_name|grep -v grep|wc -l`
echo $count
while [ $count != 0 ];
do
kill $boot_id >> /dev/null 2>&1
count=`ps -ef |grep java|grep $app_name|grep -v grep|wc -l`
echo -n '.'
boot_id=`ps -ef |grep java|grep $app_name|grep -v grep|awk '{print $app_name}'`
kill $boot_id >> /dev/null 2>&1
done
}
function restart()
{
stop
sleep 3
start
}
function status()
{
echo "########## 查看应用服务 $app_name 是否在线 ######################"
count=`ps -ef |grep java|grep $app_name|grep -v grep|wc -l`
if [ $count != 0 ];then
echo "$app_name is running..."
else
echo "$app_name is not running..."
fi
}
case $1 in
start)
start;;
stop)
stop;;
restart)
restart;;
status)
status;;
*)
echo -e "\033[0;31m Usage: \033[0m \033[0;34m sh $0 {start|stop|restart|status} {SpringBootJarName} \033[0m
\033[0;31m Example: \033[0m
\033[0;33m sh $0 start esmart-test.jar \033[0m"
esac
注意: 根据linux服务器的实际内存大小调整启动脚本中的内存设置
8.7 发布应用
9 可能会用到的卸载命令
rpm -qa | grep -i mysql
rpm -e mysql57-community-release-el7-9.noarch
ls -l | head -n 500
ln -s /usr/local/bin/python3.6 /bin/python