gitlab+jenkins+k8s实现持续集成springboot+springcloud

环境准备

下载安装vm
下载centos7镜像

虚拟机中没有IP解决方案

在这里插入图片描述

  • vi /etc/sysconfig/network-scripts/ifcfg-ens33
  • onboot设置为yes
    在这里插入图片描述
  • systemctl restart network 重启网络
    在这里插入图片描述
  • 关闭防火墙命令
systemctl status firewalld.service
systemctl stop firewalld.service

gitlab+jenkis+tomcat集成springboot项目

安装gitlab (192.168.174.128)
  • 安装相关依赖
yum -y install policycoreutils openssh-server openssh-ckuebts postfix

在这里插入图片描述

  • 启动ssh服务&设为开机启动
systemctl enable sshd && sudo systemctl start sshd
  • 设置postfix开机自启,并启动,postfix支持gitlab发信功能
systemctl enable postfix && systemctl start postfix
  • 开放ssh以及http服务,然后重新加载防火墙列表 (防火墙关闭则忽略操作)
firewall-cmd --add-service=ssh --permanent
firewall-cmd --add-service=http --permanent
firewall-cmd --reload

在这里插入图片描述

在这里插入图片描述

  • 安装
rpm -ivh gitlab-ce-12.4.2-ce.0.el7.x86_64.rpm

在这里插入图片描述

  • 如果报了这个错,运行以下命令
  • yum install policycoreutils-python
  • 然后重新执行解压命令
    在这里插入图片描述
  • 修改gitlab外部访问端口和地址
vi /etc/gitlab/gitlab.rb

在这里插入图片描述

在这里插入图片描述

  • wq保存
  • 重载配置及启动gitlab (需要等好几分钟)
    • gitlab-ctl reconfigure
      在这里插入图片描述

    • gitlab-ctl restart
      在这里插入图片描述

  • 把端口添加到防火墙
    • firewall-cmd --zone=public --add-port=82/tcp --permanent
    • firewall-cmd --reload
      在这里插入图片描述

操作gitlab

  • 访问 http://192.168.174.128:82/
    在这里插入图片描述
  • 在登陆界面更改根密码,第一次登陆需要更改
  • 更改完成后使用root + 密码登陆访问

在这里插入图片描述
在这里插入图片描述

  • 创建组、用户、项目

在这里插入图片描述

  • New Project
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • admin area中创建新用户
    在这里插入图片描述
    在这里插入图片描述
  • 创建完成后点击Edit设置密码
    在这里插入图片描述
    在这里插入图片描述
  • 进入groups

在这里插入图片描述

  • 选择成员

在这里插入图片描述

  • 选择刚才创建好的成员,并且赋予权限
    在这里插入图片描述
    在这里插入图片描述
  • Guest:可以创建issue、发表评论,不能读写版本库
  • Reporter:可以克隆代码,不能提交,QA、PM可以赋予这个权限
  • Developer:可以克隆代码、开发、提交、push,普通开发可以赋予这个权限
  • Maintainer:可以创建项目、添加tag、保护分支、添加项目成员、编辑项目,核心开发可以赋予这个
    权限
  • Owner:可以设置项目访问权限 - Visibility Level、删除项目、迁移项目、管理组成员,开发组组
    长可以赋予这个权限

在这里插入图片描述

  • 使用张三的账号登录
    • 首次登陆需要重置密码
      在这里插入图片描述
      在这里插入图片描述

创建一个项目并上传源码

  • 新建一个项目并且添加servlet-api依赖
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
  • VCS中选择Enable Version Control Integration
    在这里插入图片描述
  • 选择git
    在这里插入图片描述
  • 右键项目,选择git,+add
  • add后再次点击commit directory提交
    在这里插入图片描述
  • 此时已经本地提交
    在这里插入图片描述
  • 选择git中的manager Remotes或者remotes
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 登陆
    在这里插入图片描述
  • git push
    在这里插入图片描述
  • 刷新项目(代码提交成功)

在这里插入图片描述

jenkins安装和持续集成环境配置(192.168.174.129)

  • 安装jdk依赖
yum install java-1.8.0-openjdk* -y

在这里插入图片描述

下载jenkins 或者使用 rpm 安装包

在这里插入图片描述

  • 解压
rpm -ivh jenkins-2.346.1-1.1.noarch.rpm

在这里插入图片描述

  • 修改jenkins配置
vi /etc/sysconfig/jenkins

在这里插入图片描述
在这里插入图片描述

  • 启动jenkins
systemctl start jenkins
  • 把端口添加到防火墙

    • firewall-cmd --zone=public --add-port=8888/tcp --permanent
    • firewall-cmd --reload
  • 也可以直接关掉防火墙
    在这里插入图片描述

  • 访问 http://192.168.174.129:8888/ 发现配置的8888没有生效

    • vi /usr/lib/systemd/system/jenkins.service

      • 把里面的端口和用户名和组改掉,不然后面有坑。。
        在这里插入图片描述
        在这里插入图片描述
    • systemctl restart jenkins

      • 如果报错Restarting jenkins (via systemctl): Warning: jenkins.service changed on disk. Run ‘systemctl daemon-reload’ to reload units.
      • 那就先输入 systemctl daemon-reload
  • cat /var/lib/jenkins/secrets/initialAdminPassword 获取密码
    在这里插入图片描述

  • 跳过插件安装

    • 自定义插件安装(选择插件来安装)
      在这里插入图片描述

    • 选择无
      在这里插入图片描述

  • 安装并创建第一个用户
    在这里插入图片描述
    在这里插入图片描述

  • 安装插件

  • 进入Manage Jenkins -> Pulgin Manager

在这里插入图片描述

  • 需先中Available等待加载完成
    在这里插入图片描述
  • 在服务器查看jenkins插件下载地址
    • cd /var/lib/jenkins/updates
    • ll
      在这里插入图片描述
  • 把插件下载地址替换成国内的
sed -i 's/http:\/\/updates.jenkinsci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
  • 在Advanced中把插件下载地址替换成国内的
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

在这里插入图片描述

  • restart重启jenkins
    在这里插入图片描述
  • 下载中文语言包
    • 在插件管理处勾选中插件,选择下载完重启
      在这里插入图片描述
  • 下载完成后重启
    在这里插入图片描述
  • 已经替换为了中文,使用账号登陆(zhangsan)
    在这里插入图片描述
jenkins权限管理
  • 安装插件 Role-based Authorization Strategy
    在这里插入图片描述

  • 安装完成

  • 点击主菜单,进入全局安全配置
    在这里插入图片描述

  • 选择新下载的策略并保存

    • role-based strategy
      在这里插入图片描述
  • 进入角色管理
    在这里插入图片描述

  • 进入Manage Roles

    • 在Global roles中 新建一个baseRole
    • 勾选read权限
  • item roles中新建项目权限

    • 勾选所有权限
    • 规则中配置访问 xxx.* 来配置可访问url
      • role1 -> test.*
      • role2 -> web.*
        在这里插入图片描述
  • 保存

  • user manager中 新建两个用户
    在这里插入图片描述

  • 使用新用户登陆做测试

    • 没有权限访问任何内容
      在这里插入图片描述
  • 使用管理员账户登录,分配角色
    在这里插入图片描述

  • 使用管理员账号分配权限

    • test1分配role1
    • test2分配role2
    • test1和test2使用baseRole权限
      在这里插入图片描述
  • 新建两个项目

    • web01
    • test01
      在这里插入图片描述
  • 管理员账号可以看到两个项目
    在这里插入图片描述
    -test1 可以看到web01

在这里插入图片描述
-test2 可以看到test01

在这里插入图片描述

jenkins凭证管理
  • 安装插件
    在这里插入图片描述
    在这里插入图片描述
  • 在Manager中多出个凭证管理
    在这里插入图片描述
  • 进入全局,查看(添加凭据)

在这里插入图片描述

  • 一共有五种
    • Username with password:用户名和密码登陆凭证 (常用)
    • SSH Username with private key: 使用SSH用户和密钥 (ssh免密登陆)(常用)
    • Secret file:需要保密的文本文件,使用时Jenkins会将文件复制到一个临时目录中,再将文件路径
      设置到一个变量中,等构建结束后,所复制的Secret file就会被删除。
    • Secret text:需要保存的一个加密的文本串,如钉钉机器人或Github的api token
    • Certificate:通过上传证书文件的方式
      在这里插入图片描述
以gitlab为例进行测试
  • 安装git插件
    在这里插入图片描述
    在这里插入图片描述
  • 创建一个空项目
    在这里插入图片描述
  • 发现已经可以选择git
    在这里插入图片描述
    - 在jenkins服务器中安装git
yum install git -y

在这里插入图片描述

  • 用户密码的方式

    • 新建一个凭证,选择账号密码方式
    • 使用(gitlab)张三的账号密码,填写描述
      在这里插入图片描述
      在这里插入图片描述
  • 选择刚才创建的test-git项目

    • 进入配置
      在这里插入图片描述
    • 选择git方式,填写gitlab中的http地址
    • 选择刚才创建好的凭证
    • 保存
      在这里插入图片描述
    • 点击build now
      在这里插入图片描述
    • 点击#1进入,查看控制台输出,已经完成了first commit代码拉取
      在这里插入图片描述
    • 进入build in workspace目录,发现代码已经存在
      在这里插入图片描述
  • ssh私钥凭证形式

    • 免密登陆示意图
      • 在jenkins服务器存放私钥
      • 在gitlab服务器存放公钥
        在这里插入图片描述
    • 使用root用户生成公钥和秘钥
      • ssh-keygen -t rsa
      • 使用root用户生成公钥和秘钥(不输入任何东西,全部回车跳过)
        在这里插入图片描述
      • cd /root/.ssh 查看公钥(.pub)和私钥
        在这里插入图片描述
    • 使用root账号登陆gitlab
      • 点击头像处settings 找到 ssh keys
      • 把公钥的内容粘贴到右侧文本处
        在这里插入图片描述
        在这里插入图片描述
      • 复制完成点击add key
        在这里插入图片描述
        在这里插入图片描述
  • 配置好公钥后先在服务器测试一下拉取代码
    在这里插入图片描述

    • jenkins配置私钥
      • 添加一个凭证,选择SSH的形式
      • 添加描述
      • 把私钥从服务器复制到Enter directly中
        在这里插入图片描述
        在这里插入图片描述
  • 添加一个新项目
    在这里插入图片描述

  • 拷贝ssh连接
    在这里插入图片描述

  • 选择刚才创建好的用户
    在这里插入图片描述

  • build now
    在这里插入图片描述

jenkins安装maven+jdk
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.342.b07-1.el7_9.x86_64
export MAVEN_HOME=/opt/maven
export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin

在这里插入图片描述

  • 执行 source /etc/profile 命令
  • 执行mvn -v ,查看版本号

在这里插入图片描述

  • 进入jenkins Manage Jenkins -> Global Tool Configuration

    • 配置jdk
    • 配置maven
  • jdk
    在这里插入图片描述
    在这里插入图片描述

  • maven
    在这里插入图片描述
    在这里插入图片描述

  • 进入Configure System

    • 全局变量添加以下三个键值对
JAVA_HOME
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.342.b07-1.el7_9.x86_64


M2_HOME
/opt/maven

PATH+EXTRA
$M2_HOME/bin

在这里插入图片描述

  • 更改maven settings配置

    • 新建一个仓库地址 mkdir -p /opt/repo
    • 编辑 maven的settings.xml文件
      在这里插入图片描述
  • 更改仓库地址
    在这里插入图片描述

  • 在镜像处追加阿里云地址

    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>
    </mirror>

在这里插入图片描述

  • 测试构建maven

    • 进入之前创建好的test-git项目
    • 在 构建部分增加以下shell指令
      在这里插入图片描述
  • 如果遇到HTTP ERROR 403 No valid crumb is included in the request

    • 在 安全配置中勾选此项
      在这里插入图片描述
  • 如果遇到以下报错信息
    在这里插入图片描述

  • 改变 目录 /opt/repo 的用户组 为 jenkins 即可。

    • chown -R jenkins:jenkins /opt/repo
  • 第一次会从仓库下载很多东西
    在这里插入图片描述

  • 保存后重新build now
    在这里插入图片描述

  • 在代码目录发现已经成功打包
    在这里插入图片描述

tomcat服务器搭建 (192.168.174.130)

  • 安装jdk
yum install java-1.8.0-openjdk* -y

在这里插入图片描述

  • tomcat安装 tomcat官网
    • 下载,上传,解压tomcat
      在这里插入图片描述
  • tar -xzf apache-tomcat-8.5.47.tar.gz
  • mkdir -p /opt/tomcat 创建目录
  • mv /root/apache-tomcat-8.5.47/* /opt/tomcat 移动到创建好的目录
  • /opt/tomcat/bin/startup.sh 启动tomcat

在这里插入图片描述

  • 访问 http://192.168.174.130:8080/
  • 访问不到,把端口添加到防火墙
    • firewall-cmd --zone=public --add-port=82/tcp --permanent
    • firewall-cmd --reload
      在这里插入图片描述
  • 配置tomcat权限 (jenkins使用)
    • 进入tomcat 的conf目录
      在这里插入图片描述
    • vi tomcat-users.xml 并添加以下内容
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <role rolename="manager-script"/>
  <role rolename="manager-gui"/>
  <role rolename="manager-status"/>
  <role rolename="admin-gui"/>
  <role rolename="admin-script"/>
  <user username="tomcat" password="tomcat" roles="manager-gui,manager-script,tomcat,admin-gui,admin-script"/>

在这里插入图片描述

  • 进入 /opt/tomcat/webapps/manager/META-INF/ 修改context.xml

    • 注释掉此行
      在这里插入图片描述
  • 重启tomcat

在这里插入图片描述

  • 点击 manager webapp
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

jenkins构建项目部署到tomcat

  • 常见的构建方式有以下三种
    • 自由风格 (FeeStyle Project)
    • maven项目 (Maven Project)
    • 流水线项目 (Pipeline Project) -> 灵活度高

自由风格构建流程

  • 拉取代码->编译->打包->部署
自由风格项目实战
  • 创建一个freestyle项目

在这里插入图片描述

  • 选择连接方式
    在这里插入图片描述
  • 构建项目
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 编译打包
echo "开始编译和打包"
mvn clean package
echo "编译和打包完成"
  • 在项目中添加一个shell脚本
    在这里插入图片描述

  • 构建build now ,构建完成后项目下会产生target目录,下面有war包
    在这里插入图片描述
    在这里插入图片描述

  • 安装远程部署插件 Deploy to container
    在这里插入图片描述
    在这里插入图片描述

  • 回到项目添加一个构建后操作 Depoly war/ear to a container
    在这里插入图片描述

  • war路径写一个通配符 target/*.war 扫描所有target下的war包

  • 选择tomcat8.x容器
    在这里插入图片描述

  • 新增tomcat角色权限
    在这里插入图片描述
    在这里插入图片描述

  • 选择刚才创建好的tomcat账号,填写tomcat地址 http://192.168.174.130:8080
    在这里插入图片描述

  • tomcat管理界面刷新查看 http://192.168.174.130:8080/manager/html
    在这里插入图片描述
    在这里插入图片描述
    持续集成

  • 代码修改
    在这里插入图片描述

  • 本地提交代码
    在这里插入图片描述
    在这里插入图片描述

  • push到远程仓库
    在这里插入图片描述
    在这里插入图片描述

  • 重新构建

在这里插入图片描述
在这里插入图片描述

  • 刷新服务器,看到已经变更了
    在这里插入图片描述
Maven风格项目实战
  • 安装插件 Maven Integration
    在这里插入图片描述
    在这里插入图片描述
  • 新建一个maven项目

在这里插入图片描述

  • 拉取源码
    在这里插入图片描述
  • maven构建与自由风格的区别在于会执行一个pom.xml文件
    • 如果有子项目,在root pom 处前加上子项目目录
    • 在Goals and options 直接写要执行的mvn指令,不需要指出mvn
      在这里插入图片描述
  • 配置tomcat
    在这里插入图片描述
  • 新增一行代码,提交(与之前的项目区分一下)
    在这里插入图片描述
  • 提交完成build now

在这里插入图片描述

Pipeline(流水线)构建项目
  • 支持两种语法
    • Declarative(声明式)
    • Scripted (脚本式)
  • 创建方式
    • jenkins 的Web UI 界面
    • jenkinsfile脚本文件(代码)
  • 安装插件
    在这里插入图片描述
  • 新建流水线项目

在这里插入图片描述

  • 流水线脚本选择
    在这里插入图片描述

  • hello word

    • 基于声明式的模板
    • pipeline开头标记
    • jenkins推荐使用
      • stages:代表整个流水线的所有执行阶段。通常stages只有1个,里面包含多个stage
      • stage:代表流水线中的某个阶段,可能出现n个。一般分为拉取代码,编译构建,部署等阶段。
      • steps:代表一个阶段内需要执行的逻辑。steps里面是shell脚本,git拉取代码,ssh远程发布等任意内

        在这里插入图片描述
  • Scripted Pipeline

    • node开头标记
    • 脚本式
      • Node:节点,一个 Node 就是一个 Jenkins 节点,Master 或者 Agent,是执行 Step 的具体运行
        环境,后续讲到Jenkins的Master-Slave架构的时候用到。
      • Stage:阶段,一个 Pipeline 可以划分为若干个 Stage,每个 Stage 代表一组操作,比如:
        Build、Test、Deploy,Stage 是一个逻辑分组的概念。
      • Step:步骤,Step 是最基本的操作单元,可以是打印一句话,也可以是构建一个 Docker 镜像,
        由各类 Jenkins 插件提供,比如命令:sh ‘make’,就相当于我们平时 shell 终端中执行 make 命令
        一样。
        在这里插入图片描述
脚本体验测试
  • 声明式
pipeline {
    agent any

    stages {
        stage('pull code') {
            steps {
                echo 'pull code'
            }
        }
        stage('build project') {
            steps {
                echo 'build project'
            }
        }
        stage('publish project') {
            steps {
                echo 'publish project'
            }
        }
    }
}

在这里插入图片描述

  • Scripted
node {
    def mvnHome
    stage('pull code') { 
        echo 'pull code'
    }
    stage('Build') {
        echo 'pull Build'
    }
    stage('Results') {
        echo 'pull Results'
    }
}

在这里插入图片描述

拉取代码+编译打包

  • 进入配置,找到流水线语法
    在这里插入图片描述
拉取代码
  • 在片段生成器中,选择check out from version control
    在这里插入图片描述
  • 生成流水线脚本
    • credentialsId 对应ssh连接凭证
      在这里插入图片描述
  • 把流水线脚本复制到配置
    在这里插入图片描述
  • build now 构建
    在这里插入图片描述
  • 查看代码,拉取成功
    在这里插入图片描述
编译打包
  • 脚本生成器选择 sh:shell script
    • 输入 mvn clean package 生成脚本
      在这里插入图片描述
  • 把脚本拷贝到第二个stage

在这里插入图片描述

  • 构建完成,并且生成了war包
    在这里插入图片描述
    在这里插入图片描述
发布到远程服务器
  • 脚本生成器选择 deploy:Deploy war/ear to a container

在这里插入图片描述

  • 脚本复制到第三个stage
    在这里插入图片描述
  • 执行成功
    在这里插入图片描述
jenkinsfile脚本
  • 好处

    • 利于版本控制
    • 不会因jenkins服务器崩溃丢失
    • 。。。
  • 代码中新建Jenkinsfile文件

    • 文件中把上面的脚本复制到文件内,提交到gitlab仓库
      在这里插入图片描述

在这里插入图片描述

  • 流水线中选择 from SCM
    在这里插入图片描述
  • 配置获取地址,以及文件名(默认存放在项目根目录)
    在这里插入图片描述
  • build now构建测试
    在这里插入图片描述
构建触发器
  • jenkins内置的4中构建触发器
    • 触发远程构建
    • 其他工程构建后触发
    • 定时构建
    • 轮询SCM
  • 触发远程构建
    在这里插入图片描述
  • 在设置中选择触发远程构建,配置token令牌(生产环境使用加密字符串,测试使用6666)
  • 当前构建为第9次
    在这里插入图片描述
  • 打开浏览器输入 http://192.168.174.129:8888//job/web_demo_pipeline/build?token=6666
  • 可以看到已经开始了第10次构建
    在这里插入图片描述
  • 构建成功
    在这里插入图片描述
  • 其它工程构建后触发
  • 建立一个新的自由风格工程(任意类型都可以)
    在这里插入图片描述
  • 里面只执行输出一句话
    在这里插入图片描述
  • 刚才的项目中取消 触发远程构建,选择build after other projects are built
    • 输入前一步创建好的工程名
      在这里插入图片描述
  • 构建前置工程
    在这里插入图片描述
    在这里插入图片描述
  • 刚才配置好的项目开始构建第11次
    在这里插入图片描述
  • 构建成功

在这里插入图片描述

定时构建字符串
  • 从左往右分别分:分 时 日 月 周
  • H代表形参 是可以变化的,H可以替换为0,代表准点
30分钟构建一次:
H/30 * * * *
执行时间为 00:00 00:30 。。。

每2个小时构建一次: 
H H/2 * * *

每天的8点,12点,22点,一天构建3次: (多个时间点中间用逗号隔开) 
0 8,12,22 * * *

每天中午12点定时构建一次 
H 12 * * *

每天下午18点定时构建一次 
H 18 * * *

在每个小时的前半个小时内的每10分钟 
H(0-29)/10 * * * *

每两小时一次,每个工作日上午9点到下午5(也许是上午10:38,下午12:38,下午2:38,下午4:38)
H H(9-16)/2 * * 1-5
  • 定时构建

  • 设置中选择 Build periodically
    在这里插入图片描述

  • 等待2分钟左右,就可以看到开始第12次构建
    在这里插入图片描述

  • 再等两分钟,可以看到第13次构建
    在这里插入图片描述

  • 轮询SCM构建

  • 定时扫描本地代码仓库的代码是否有变更,如果有就触发构建项目

  • jenkins会定时扫描本地整个项目的代码,增大系统开销,不建议使用

在这里插入图片描述

  • 等待两分钟,没有触发构建
  • 代码做一些改动提交,则会触发构建
  • 没做测试,感兴趣的可以自己试试

git hook自动触发构建 (着重推荐使用方案)

在这里插入图片描述

  • 安装插件
    • GitLab
    • Gitlab Hook ()
      在这里插入图片描述
  • 配置中选择 Build when a change is pushed to GitLab. GitLab webhook URL: http://192.168.174.129:8888/project/web_demo_pipeline

在这里插入图片描述

  • 使用root账号登陆gitlab
  • 找到settings中的network
    在这里插入图片描述
  • 勾选Allow requests to the local network from web hooks and services保存
    在这里插入图片描述
  • 打开项目,找到settings中的Intergrations

在这里插入图片描述

  • 把上一步产生的地址填写到URL,Add webhook
    在这里插入图片描述
    在这里插入图片描述
  • test 测试推送
    在这里插入图片描述
  • 返回403信息
  • 在jenkins的configure system中,找到gitlab模块,把Enable authentication for ‘/project’ end-point的勾选取消
    在这里插入图片描述
  • 再次测试
    在这里插入图片描述
  • jenkins触发了构建事件
    在这里插入图片描述
  • 代码中修改片段测试
    在这里插入图片描述
  • push完成后开始构建
    在这里插入图片描述
  • 构建完成,成功部署
    在这里插入图片描述
    在这里插入图片描述
jenkins参数化构建
  • 在配置中,把现有构建触发器取消
    • 在This project is parameterized选择String Parameter
      在这里插入图片描述
  • 名称输入branch,默认值master
    在这里插入图片描述
  • 保存后菜单栏多出一行build with parameters
    在这里插入图片描述
  • 在代码中把branches中的值改为 */${branch}
    在这里插入图片描述
  • 在测试jsp中修改文字
    在这里插入图片描述
  • 代码push到仓库(master分支)
  • 在代码中选择git - > Branches
    在这里插入图片描述
  • 创建v1分支
    在这里插入图片描述
  • 修改jsp代码
    在这里插入图片描述
  • push代码到v1分支
  • 在gitlab上查看

在这里插入图片描述

  • 在这里插入图片描述
    在这里插入图片描述
  • 构建master分支

在这里插入图片描述

  • 构建完成后
    在这里插入图片描述
  • 构建v1分支
    在这里插入图片描述
  • 构建完成后
    在这里插入图片描述
jenkins配置邮箱服务器发送构建结果
  • 下载插件 Email Extension Template

  • 在插件管理,高级中找到Deploy Plugin,选择下载好的hpi文件,Deploy
    在这里插入图片描述

  • 使用2.7.1版本
    在这里插入图片描述

  • 进入QQ邮箱客户端

    • 在设置,账户下开启POP3/IMAP/SMTP服务
    • 需要验证手机号,并返回给一个字符串授权码
    • wystxlmanijrbeda

在这里插入图片描述

  • 进入Configure System->Extended E-mail Notification
    • smtp服务器
    • smtp端口 465
    • 勾选使用ssl
    • 勾选Use SMTP Authentication
    • 输入邮箱和令牌
    • 默认点子邮件后缀
    • 默认内容类型选择html
    • 默认收件人
      在这里插入图片描述

在这里插入图片描述

  • jenkins location中把管理员邮件地址改成收件地址
    在这里插入图片描述
  • jenkins默认邮件通知
    • smtp服务器
    • 默认后缀
    • 使用SMTP认证并且输入邮箱和刚才的那一串令牌
    • 使用SSL协议
    • 端口改成465
    • 回复邮箱同收件邮箱
      在这里插入图片描述
  • 测试邮件发送
    在这里插入图片描述
    在这里插入图片描述
  • 定制邮件发送通用模板
  • 把邮件html房子根目录与src平级,否则按下面的示例会导致找不到html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>

<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
      offset="0">
<table width="95%" cellpadding="0" cellspacing="0"
       style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
    <tr>
        <td>(本邮件是程序自动下发的,请勿回复!)</td>
    </tr>
    <tr>
        <td><h2>
            <font color="#0000FF">构建结果 - ${BUILD_STATUS}</font>
        </h2></td>
    </tr>
    <tr>
        <td><br />
            <b><font color="#0B610B">构建信息</font></b>
            <hr size="2" width="100%" align="center" /></td>
    </tr>
    <tr>
        <td>
            <ul>
                <li>项目名称&nbsp;&nbsp;${PROJECT_NAME}</li>
                <li>构建编号&nbsp;&nbsp;第${BUILD_NUMBER}次构建</li>
                <li>触发原因:&nbsp;${CAUSE}</li>
                <li>构建日志:&nbsp;<a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
                <li>构建&nbsp;&nbsp;Url&nbsp;&nbsp;<a href="${BUILD_URL}">${BUILD_URL}</a></li>
                <li>工作目录&nbsp;&nbsp;<a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
                <li>项目&nbsp;&nbsp;Url&nbsp;&nbsp;<a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
            </ul>
        </td>
    </tr>
    <tr>
        <td><b><font color="#0B610B">Changes Since Last
            Successful Build:</font></b>
            <hr size="2" width="100%" align="center" /></td>
    </tr>
    <tr>
        <td>
            <ul>
                <li>历史变更记录 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li>
            </ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat="&nbsp;&nbsp;&nbsp;&nbsp;%p"}
        </td>
    </tr>
    <tr>
        <td><b>Failed Test Results</b>
            <hr size="2" width="100%" align="center" /></td>
    </tr>
    <tr>
        <td><pre
                style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTS</pre>
            <br /></td>
    </tr>
    <tr>
        <td><b><font color="#0B610B">构建日志 (最后 100):</font></b>
            <hr size="2" width="100%" align="center" /></td>
    </tr>
    <tr>
        <td><textarea cols="80" rows="30" readonly="readonly"
                      style="font-family: Courier New">${BUILD_LOG, maxLines=100}</textarea>
        </td>
    </tr>
</table>
</body>
</html>
  • 模板中的参数为jenkins固定值

    • 具体其它参数可以从安全配置中找到content token reference点击小问号展开查看
      在这里插入图片描述
  • 在jenkinsfile中配置邮件发送

    • 流水线语法中找到 Directive Generator,选择post
      在这里插入图片描述
  • 根据提示可以生成对应脚本

在这里插入图片描述

  • 片段生成器可以选择emailext
    在这里插入图片描述
pipeline {
    agent any

    stages {
        stage('pull code') {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: 'f9831a99-2028-4c36-b10a-d9a36d687f42', url: 'git@192.168.174.128:first_group/web_demo.git']]])
            }
        }
        stage('build project') {
            steps{
                sh 'mvn clean package'
            }
        }
        stage('publish project') {
            steps{
                deploy adapters: [tomcat8(credentialsId: '726b8934-8c30-4b05-941a-2d7cdeff151b', path: '', url: 'http://192.168.174.130:8080')], contextPath: null, war: 'target/*.war'
            }
        }
    }

    post {
         always {
            emailext body: '${FILE,path="email.html"}',
                subject: '构建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} -${BUILD_STATUS}!',
                to: '843635953@qq.com'
         }
    }
}


  • 把代码提交到gitlab
  • 构建代码提交的分支
    在这里插入图片描述
  • 构建成功通知
    在这里插入图片描述

在这里插入图片描述

代码审查 SonarQube

  • 先安装mysql5.7
    • wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
      在这里插入图片描述

    • yum -y install mysql57-community-release-el7-10.noarch.rpm
      在这里插入图片描述

    • yum -y install mysql-community-server
      在这里插入图片描述

  • 如果提示软件包失败。。。公钥尚未安装
    • 先执行 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
    • 再次执行 yum -y install mysql-community-server
  • systemctl start mysqld
    在这里插入图片描述
  • grep “password” /var/log/mysqld.log
    • 得到初始秘钥 d&PfEfytd1uB
      在这里插入图片描述
  • mysql -uroot -p
    • 使用上一步的密码登陆
    • 直接改密码会报错
      在这里插入图片描述
    • set global validate_password_policy=LOW;
    • set global validate_password_length=6;
    • ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
    • grant all privileges on *.* to 'root'@'192.168.174.129' identified by '123456' with grant option;
    • flush privileges;
    • exit
    • 防火墙添加3306
    • firewall-cmd --zone=public --add-port=3306/tcp --permanent
    • firewall-cmd --reload
    • mysql -uroot -p 123456
    • use mysql
    • select host, user from user;
    • update user set host='%' where user='root'; 或者 update user set host='%' where user='localhost'; //看查出来的名字什么
    • flush privileges;
    • 这个错误不用理会
      在这里插入图片描述
      在这里插入图片描述
  • 安装sonarqube
    • 官网 https://www.sonarqube.org/downloads/
    • 先创建一个sonar的数据库
      在这里插入图片描述
    • 先创建一个sonar的数据库
    • 压缩包下载好上传至虚拟机
      在这里插入图片描述
    • unzip sonarqube-6.7.4.zip
    • mkdir /opt/sonar
    • mv sonarqube-6.7.4/* /opt/sonar
      在这里插入图片描述
  • 创建普通用户sonar用于启动,用root会报错
    • useradd sonar
    • chown -R sonar. /opt/sonar 更改sonar目录及文件权限
      在这里插入图片描述
  • vi /opt/sonar/conf/sonar.properties
sonar.jdbc.username=root 
sonar.jdbc.password=123456
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?
useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=
maxPerformance&useSSL=false

在这里插入图片描述

  • sonar 监听数据库9000端口,如果9000被占用,需要改掉
    在这里插入图片描述
  • cd /opt
  • su sonar /opt/sonar/bin/linux-x86-64/sonar.sh start
su sonar /opt/sonar/bin/linux-x86-64/sonar.sh start 启动
su sonar /opt/sonar/bin/linux-x86-64/sonar.sh status 查看状态
su sonar /opt/sonar/bin/linux-x86-64/sonar.sh stop 停止
tail -f /opt/sonar/logs/sonar.log 查看日志

在这里插入图片描述

  • 查看日志,出现Process[ce] is up 就是成功了
    在这里插入图片描述
  • 防火墙放开9000端口
    • firewall-cmd --zone=public --add-port=9000/tcp --permanent
    • firewall-cmd --reload
  • http://192.168.174.129:9000/
    在这里插入图片描述
  • 默认账号密码都是admin,点击登录
  • 输入一个名字生成秘钥
    在这里插入图片描述
  • 994b30f143cfa4ed135dd905c40ec166feef7917
    在这里插入图片描述
jenkins+SonarQube代码审查

在这里插入图片描述

  • 安装SonarQube Scanner插件
    在这里插入图片描述
  • 添加全局配置
    在这里插入图片描述
  • Configure System->SonarQube servers配置
    在这里插入图片描述
  • Global Tool Configuration 配置SonarQube Scanner
    在这里插入图片描述
  • 非流水线项目 (测试)
    • 进入web_demo_freestyle构建部分
    • 新增Execute SonarQube Scanner构建步骤
    • Task to run (scan)
    • 选择jdk8
    • 填写以下内容
# must be unique in a given SonarQube instance
sonar.projectKey=web_demo_freestyle

# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=web_demo_freestyle
sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.

# This property is optional if sonar.modules is set.
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**

sonar.java.source=1.8
sonar.java.target=1.8

# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8

在这里插入图片描述

  • build now 构建
    • 构建完成查看
      在这里插入图片描述
  • 成功捕获错误
    在这里插入图片描述
  • 流水线项目 (测试)
  • 代码中根目录新增配置文件sonar-project.properties
# must be unique in a given SonarQube instance
sonar.projectKey=web_demo_pipline
# this is the name and version displayed in the SonarQube UI. Was mandatoryprior to SonarQube 6.1.

sonar.projectName=web_demo_pipline
sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" onWindows.

# This property is optional if sonar.modules is set.

sonar.sources=.
sonar.exclusions=**/test/**,**/target/**

sonar.java.source=1.8
sonar.java.target=1.8

# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
  • jenkinsfile中添加
    • sq-scanner 来自于全局工具配置SonarQube Scanner
    • sonarqube-scanner 来自于系统配置 SonarQube servers
        stage('code check') {
            steps{
                script {
                    scannerHome = tool 'sq-scanner'
                }
                withSonarQubeEnv('sonarqube-scanner') {
                    sh "${scannerHome}/bin/sonar-scanner"
                }
            }
        }
  • 提交代码
  • web_demo_pipeline 构建
    在这里插入图片描述
    在这里插入图片描述

springcloud+jenkins+docker集成

docker安装 (以下服务器都需要装)
  • jenkins服务器
  • docker + harbor镜像仓库
  • 生产服务器(n台)
    • 使用虚拟机的话,可以用一台新的下载docker,然后镜像2-3台作为生产服务器

安装流程

  • 卸载旧版本(没有安装可忽略)
 sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
  • 安装必要的软件包
 sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
  • 设置下载的镜像源(三选一)
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
 sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum-config-manager \
    --add-repo \
    https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
  • 查看列表
yum list docker-ce --showduplicates | sort -r
  • 安装docker
sudo yum install docker-ce-18.06.1.ce
  • 查看版本
docker -v
  • 启动Docker
启动
sudo systemctl start docker 
设置开机启动
sudo systemctl enable docker 
vi /etc/docker/daemon.json
{
  "registry-mirrors": ["https://3e=x2n.mirror.aliyuncs.com"]
}
sudo systemctl daemon-reload
sudo systemctl restart docker

docker info  查看
  • 下载openjdk
docker pull openjdk:8-jdk-alpine
  • 安装docker-compose
curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
  • docker-compose -version
    在这里插入图片描述
安装docker私有仓库harbor(192.168.174.131)
tar -xzf harbor-offline-installer-v1.9.2.tgz
mkdir /opt/harbor
mv harbor/* /opt/harbor
cd /opt/harbor
vi harbor.yml

修改hostname和port
hostname: 192.168.174.131
port: 85
  • 执行准备命令 ./prepare
    在这里插入图片描述
  • 执行 ./install.sh
    在这里插入图片描述
  • 访问 http://192.168.174.131:85/
    • 默认账户:admin
    • 默认密码:Harbor12345
      在这里插入图片描述
      在这里插入图片描述
创建项目

在这里插入图片描述

创建用户
  • zhangsan Zhangsan123456
    在这里插入图片描述

  • 在tensquera项目中的成员添加用户
    在这里插入图片描述

  • 使用zhangsan用户登陆查看
    在这里插入图片描述

  • 把Harbor地址加入到jenkins的Docker信任列表 (用于上传镜像)

    • 在jenkins服务器中vi /etc/docker/daemon.json
    • 添加一行"insecure-registries": [“192.168.174.131:85”]
{
  "registry-mirrors": ["https://3e=x2n.mirror.aliyuncs.com"],
  "insecure-registries": ["192.168.174.131:85"]
}
  • 重启jenkins的docker
    • systemctl restart docker
  • 使用同样的方法在harbor中添加jenkins的Docker信任列表 (用于下载镜像)
    • 在harbor服务器中vi /etc/docker/daemon.json
    • 添加一行"insecure-registries": [“192.168.174.129:85”]
{
  "registry-mirrors": ["https://3e=x2n.mirror.aliyuncs.com"],
  "insecure-registries": ["192.168.174.131:85"]
}
  • 重启harbor的docker
    • systemctl restart docker

SSH远程调用安装

  • Publish Over SSH

在这里插入图片描述

  • 在jenkins服务器执行 ssh-copy-id pro1服务器IP

    • ssh-copy-id 192.168.174.132
      在这里插入图片描述
      在这里插入图片描述
  • Configure System 目录下找到 jenkins ssh key

    • 把authorized_keys秘钥输入到密码栏
    • path to key 为jenkins 的id_rsa目录
    • 添加一个ssh server
      • ip为pro

      • name 随便写

      • username 为 root

      • 路径 /

      • 测试连接

      • 主节点
        在这里插入图片描述

  • 从节点
    在这里插入图片描述

jenkins添加harbar凭证

在这里插入图片描述

在这里插入图片描述

代码上传到仓库
  • gitlab新建前端和后台项目
    • tensquareAdmin (前端代码)
    • tensquare_parent (微服务代码)
  • 上传
    在这里插入图片描述

后台部署 (192.168.174.132 + 192.168.174.133)

192.168.174.132为pro1,192.168.174.133为pro2

  • 新建流水线项目
    在这里插入图片描述
  • 配置git,使用jenkinsfile
    在这里插入图片描述
  • 安装多选插件 Extended Choice Parameter
    在这里插入图片描述
  • 配置中添加参数
  • 在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 进入构建部分,发现已经可以多选,并且有具体描述
    在这里插入图片描述

  • jenkinsfile

//git凭证ID
def git_auth = "f9831a99-2028-4c36-b10a-d9a36d687f42"
//git的url地址
def git_url = "git@192.168.174.128:root/tensquare_parent.git"
//镜像的版本号
def tag = "latest"
//Harbor的url地址
def harbor_url = "192.168.174.131:85"
//镜像库项目名称
def harbor_project = "tensquare"
//Harbor的登录凭证ID
def harbor_auth = "ff0da5ec-efae-4fd5-bad3-d968e9432055"

node {
   //获取当前选择的项目名称
   def selectedProjectNames = "${project_name}".split(",")
   //获取当前选择的服务器名称
   def selectedServers = "${publish_server}".split(",")

   stage('拉取代码') {
      checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
   }
   stage('代码审查') {
        for(int i=0;i<selectedProjectNames.length;i++){
            //tensquare_eureka_server@10086
            def projectInfo = selectedProjectNames[i];
            //当前遍历的项目名称
            def currentProjectName = "${projectInfo}".split("@")[0]
            //当前遍历的项目端口
            def currentProjectPort = "${projectInfo}".split("@")[1]

            //定义当前Jenkins的SonarQubeScanner工具
            def scannerHome = tool 'sq-scanner'
            //引用当前JenkinsSonarQube环境
            withSonarQubeEnv('sonarqube-scanner') {
                 sh """
                         cd ${currentProjectName}
                         ${scannerHome}/bin/sonar-scanner
                 """
            }
        }


   }
   stage('编译,安装公共子工程') {
      sh "mvn -f tensquare_common clean install"
   }
   stage('编译,打包微服务工程,上传镜像') {
       for(int i=0;i<selectedProjectNames.length;i++){
                 //tensquare_eureka_server@10086
                 def projectInfo = selectedProjectNames[i];
                 //当前遍历的项目名称
                 def currentProjectName = "${projectInfo}".split("@")[0]
                 //当前遍历的项目端口
                 def currentProjectPort = "${projectInfo}".split("@")[1]

                 sh "mvn -f ${currentProjectName} clean package dockerfile:build"

                 //定义镜像名称
                 def imageName = "${currentProjectName}:${tag}"

                 //对镜像打上标签
                 sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"

                //把镜像推送到Harbor
                withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {

                    //登录到Harbor
                    sh "docker login -u ${username} -p ${password} ${harbor_url}"

                    //镜像上传
                    sh "docker push ${harbor_url}/${harbor_project}/${imageName}"

                    sh "echo 镜像上传成功"
                }

                //遍历所有服务器,分别部署
                for(int j=0;j<selectedServers.length;j++){
                       //获取当前遍历的服务器名称
                       def currentServerName = selectedServers[j]

                       //加上的参数格式:--spring.profiles.active=eureka-server1/eureka-server2
                       def activeProfile = "--spring.profiles.active="

                       //根据不同的服务名称来读取不同的Eureka配置信息
                       if(currentServerName=="master_server"){
                          activeProfile = activeProfile+"eureka-server1"
                       }else if(currentServerName=="slave_server"){
                          activeProfile = activeProfile+"eureka-server2"
                       }

                       //部署应用
                       sshPublisher(publishers: [sshPublisherDesc(configName: "${currentServerName}", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deployCluster.sh $harbor_url $harbor_project $currentProjectName $tag $currentProjectPort $activeProfile", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])


                }

        }
   }
}
  • dockerfile模板
#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086
ENTRYPOINT ["java","-jar","/app.jar"]
  • jenkins_shell脚本 deployCluster.sh
#! /bin/sh
#接收外部参数
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5
profile=$6

imageName=$harbor_url/$harbor_project_name/$project_name:$tag

echo "$imageName"

#查询容器是否存在,存在则删除
containerId=`docker ps -a | grep -w ${project_name}:${tag}  | awk '{print $1}'`

if [ "$containerId" !=  "" ] ; then
    #停掉容器
    docker stop $containerId

    #删除容器
    docker rm $containerId
	
	echo "成功删除容器"
fi

#查询镜像是否存在,存在则删除
imageId=`docker images | grep -w $project_name  | awk '{print $3}'`

if [ "$imageId" !=  "" ] ; then
      
    #删除镜像
    docker rmi -f $imageId
	
	echo "成功删除镜像"
fi


# 登录Harbor
docker login -u zhangsan -p Zhangsan123456 $harbor_url

# 下载镜像
docker pull $imageName

# 启动容器
docker run -di -p $port:$port $imageName $profile

echo "容器启动成功"

  • 把脚本放在pro服务器中,在opt目录下新建jenkins_shell,并授权
    • chmod +x deployCluster.sh
  • pro服务器添加harbor镜像信任(用于下载镜像)
    • systemctl daemon-reload
    • systemctl restart docker
{
  "registry-mirrors": ["https://3eygzx2n.mirror.aliyuncs.com"],
  "insecure-registries": ["192.168.174.131:85"]
}
  • build 测试
    在这里插入图片描述
  • 代码检测执行成功

在这里插入图片描述
在这里插入图片描述

  • maven构建成功
    在这里插入图片描述

  • 镜像上传成功
    在这里插入图片描述

  • 镜像下载成功
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • postman测试接口
    在这里插入图片描述
    在这里插入图片描述

前端web网站部署 (192.168.174.132)

pro1安装nginx
  • yum install epel-release
  • yum -y install nginx
  • 修改nginx的端口,默认80,改为9090:
    • vi /etc/nginx/nginx.conf

    server {
        listen       9090;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
  • 还需要关闭selinux,将SELINUX=disabled

    • 永久关闭 vi /etc/selinux/config 编辑文件
    • SELINUX=disabled

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted 



  • nginx命令
systemctl enable nginx 设置开机启动
systemctl start nginx 启动
systemctl stop nginx 停止
systemctl restart nginx 重启
  • 启动Nginx
  • 防火墙放开9090端口
    • firewall-cmd --zone=public --add-port=9090/tcp --permanent
    • firewall-cmd --reload
  • 如果下图报错
  • 安装NodeJS插件
    在这里插入图片描述
  • 配置环境 Global Tool Configuration
    在这里插入图片描述
  • 新建一个web_vue_pipeline 流水线项目
    在这里插入图片描述
  • 添加参数 This project is parameterized
    在这里插入图片描述
  • 流水线添加脚本
    • git_auth 为gitlab的ssh凭证
    • url 为代码地址
//gitlab的凭证
def git_auth = "f9831a99-2028-4c36-b10a-d9a36d687f42"

node {
    
    stage('拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']],doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [],userRemoteConfigs: [[credentialsId: "${git_auth}", url:'git@192.168.174.128:root/tensquareadmin.git']]])
    } 
    stage('打包,部署网站') {
        //使用NodeJS的npm进行打包
        nodejs('nodejs12'){
            sh '''
                npm install
                npm run build
            '''
        } /
        sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server',transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '',execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes:false, patternSeparator: '[, ]+', remoteDirectory: '/usr/share/nginx/html',remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')],usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
    }
}
  • build master

在这里插入图片描述

nginx+zuul高可用网关部署 (192.168.174.133)

  • 在pro2安装nginx,配置以下信息

    upstream  zuulServer{
        server 192.168.174.132:10002 weight=1;
        server 192.168.174.133:10002 weight=1;
    }
    
    server {
        listen       85;
        listen       [::]:85;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
        
        location / {
            proxy_pass http://zuulServer/;
        }
    }

  • systemctl restart nginx

  • 修改前端网关,重新部署
    在这里插入图片描述

  • 把端口添加到防火墙

    • firewall-cmd --zone=public --add-port=85/tcp --permanent
    • firewall-cmd --reload
  • 访问 http://192.168.174.132:9090/#/login

基于k8s构建jenkins持续集成

192.168.174.128(gitlab)
192.168.174.129(k8s-master)
192.168.174.131(harbor)
192.168.174.132(k8s-node1)
192.168.174.133(k8s-node2)

Jenkins的Master-Slave测试

  • Configure Global Security
    在这里插入图片描述
  • manage nodes新建节点
    在这里插入图片描述
    在这里插入图片描述
  • 在132的root目录新建jenkins目录
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 进入salve1,点击下载agent.jar
    在这里插入图片描述
  • 下载好放入从节点根目录
    在这里插入图片描述
  • 执行命令 java -jar agent.jar -jnlpUrl http://192.168.174.129:8888/computer/slave1/jenkins-agent.jnlp -secret 605ecabbbb1caadf7acfd01e9d06bf628acb5b3d9d292dfd3dc4778243490b9a -workDir “/root/jenkins”
    • 需要关闭129的防火墙或者把8888端口放开
      在这里插入图片描述

在这里插入图片描述

  • 新建一个自由风格项目
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 构建
    • 如果构建有问题,可以参考上面文档安装git,创建slave-ssh账户进行连接
      在这里插入图片描述
      在这里插入图片描述
  • 再尝试一个流水线项目
    • 以下内容使用了新的slave-ssh
node('slave1') {
    stage('check out') {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']],doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [],userRemoteConfigs: [[credentialsId: '	7ac724bf-f529-4ef8-879a-999748e10efd', url:'git@192.168.174.128:root/tensquare_parent.git']]])
    }
}

在这里插入图片描述
在这里插入图片描述

k8s实现master-slave分布式构建方案

  • 传统Jenkins的Master-Slave方案的缺陷
    • Master节点发生单点故障时,整个流程都不可用了
    • 每个 Slave节点的配置环境不一样,来完成不同语言的编译打包等操作,但是这些差异化的配置导致管理起来非常不方便,维护起来也是比较费劲
    • 资源分配不均衡,有的 Slave节点要运行的job出现排队等待,而有的Slave节点处于空闲状态资源浪费,每台 Slave节点可能是实体机或者VM,当Slave节点处于空闲状态时,也不会完全释放
      掉资源
  • 以上种种问题,我们可以引入Kubernates来解决!
  • Kubernates简介
    • Kubernetes(简称,K8S)是Google开源的容器集群管理系统,在Docker技术的基础上,为容器化的
      应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的
      便捷性。 其主要功能如下:
      • 使用Docker对应用程序包装(package)、实例化(instantiate)、运行(run)。以集群的方式运行、管理跨机器的容器。以集群的方式运行、管理跨机器的容器。解决Docker跨机器容器之间的通讯问题。解决Docker跨机器容器之间的通讯问题。
      • Kubernetes的自我修复机制使得容器集群总是运行在用户期望的状态。
  • Kubernates+Docker+Jenkins持续集成架构图
    • 大致工作流程
      • 手动/自动构建
      • Jenkins 调度 K8S API
      • 动态生成 Jenkins Slave pod
      • Slave pod
      • 拉取 Git 代码/编译/打包镜像
      • 推送到镜像仓库 Harbor
      • Slave 工作完成,Pod 自动销毁
      • 部署到测试或生产 Kubernetes平台。(完全自动化,无需人工干预)

在这里插入图片描述

  • Kubernates+Docker+Jenkins持续集成方案好处

    • 服务高可用:当 Jenkins Master 出现故障时,Kubernetes 会自动创建一个新的 Jenkins Master容器,并且将 Volume 分配给新创建的容器,保证数据不丢失,从而达到集群服务高可用。
    • 动态伸缩,合理使用资源:每次运行 Job 时,会自动创建一个 Jenkins Slave,Job 完成后,Slave自动注销并删除容器,资源自动释放,而且 Kubernetes 会根据每个资源的使用情况,动态分配Slave 到空闲的节点上创建,降低出现因某节点资源利用率高,还排队等待在该节点的情况。
    • 扩展性好:当 Kubernetes 集群的资源严重不足而导致 Job 排队等待时,可以很容易的添加一个Kubernetes Node 到集群中,从而实现扩展
  • Kubernetes的架构

    • API Server:用于暴露Kubernetes API,任何资源的请求的调用操作都是通过kube-apiserver提供的接口进行的。
    • Etcd:是Kubernetes提供默认的存储系统,保存所有集群数据,使用时需要为etcd数据提供备份计划。
    • Controller-Manager:作为集群内部的管理控制中心,负责集群内的Node、Pod副本、服务端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。
    • Scheduler:监视新创建没有分配到Node的Pod,为Pod选择一个Node。
    • Kubelet:负责维护容器的生命周期,同时负责Volume和网络的管理
    • Kube proxy:是Kubernetes的核心组件,部署在每个Node节点上,它是实现Kubernetes Service的通信与负载均衡机制的重要组件。
      在这里插入图片描述
k8s-master(192.168.174.129) 环境
  • 安装kube-apiserver、kube-controller-manager、kubescheduler、docker、etcd、calico,NFS
  • 修改三台机器的hostname和hosts文件
hostnamectl set-hostname k8s-master

hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2

cat >>/etc/hosts<<EOF 
192.168.174.129 k8s-master 
192.168.174.132 k8s-node1
192.168.174.133 k8s-node2
EOF
  • 三台机器执行不同命令
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

  • 三台机器执行相同命令
    在这里插入图片描述

  • systemctl status firewalld (确保三台机器防火墙关闭)

  • vi /etc/sysconfig/selinux

    • 改为SELINUX=disabled
  • 执行 setenforce 0,否则重启才能生效

  • 设置允许路由转发,不对bridge的数据进行处理 (三台都做)

    • 创建文件 vi /etc/sysctl.d/k8s.conf
    • 内容如下:
      • net.bridge.bridge-nf-call-ip6tables = 1
      • net.bridge.bridge-nf-call-iptables = 1
      • net.ipv4.ip_forward = 1
      • vm.swappiness = 0
    • 执行文件 sysctl -p /etc/sysctl.d/k8s.conf

在这里插入图片描述

  • kube-proxy开启ipvs的前置条件 (三台都执行)
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF


chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -enf_conntrack_ipv4

在这里插入图片描述

  • 所有节点关闭swap (三台都做,如果无法执行临时关闭命令,调大内存)
swapoff -a 临时关闭

vi /etc/fstab 永久关闭
注释掉以下字段
/dev/mapper/cl-swap swap swap defaults 0 0

在这里插入图片描述

  • 安装kubelet、kubeadm、kubectl (三台都装)
  • yum clean all
  • 设置yum安装源
    • yum clean all
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
  • yum install -y kubelet kubeadm kubectl (这个安装的是最新版,可能会有意想不到的错误,建议使用下行)
    • yum install -y kubelet-1.17.0-0 kubeadm-1.17.0-0 kubectl-1.17.0-0
  • kubelet设置开机启动(注意:先不启动,现在启动的话会报错)
    • systemctl enable kubelet
  • 查看版本 kubelet --version
    在这里插入图片描述
master节点完成
  • 运行初始化命令
kubeadm init --kubernetes-version=1.17.0 \
--apiserver-advertise-address=192.168.174.129 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16
  • 报错 [ERROR NumCPU]: the number of available CPUs 1 is less than the required 2

    • 虚拟机CPU设置为2
  • 报错detected “cgroupfs” as the Docker cgroup driver. The recommended driver is “systemd”. Please follow the guide at https://kubernetes.io/docs/setup/cri/

    • vi /etc/docker/daemon.json
      • 加入 “exec-opts”:[“native.cgroupdriver=systemd”]
      • 重启docker
  • 如果没运行成功,报错 swap,可以尝试以下命令

    • swapoff -a && sed -i ‘/ swap / s/^(.*)$/#\1/g’ /etc/fstab
      在这里插入图片描述
  • 节点安装命令保存下来

kubeadm join 192.168.174.129:6443 --token rqydp7.yd7zw5xylk67y9jv \
    --discovery-token-ca-cert-hash sha256:df255c8d19eb9eea59201de81d65752d830608079849c04c8c2c2bf7efc8b2e0
  • 启动k8s
    • systemctl restart kubelet
    • systemctl status kubelet
      在这里插入图片描述
  • 逐行执行命令
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

  • 安装Calico
mkdir k8s

cd k8s

wget https://docs.projectcalico.org/v3.10/manifests/calico.yaml --no-check-certificate 

sed -i 's/192.168.0.0/10.244.0.0/g' calico.yaml

kubectl apply -f calico.yaml
  • 等待几分钟,查看所有Pod的状态,确保所有Pod都是Running状态
    • kubectl get pod --all-namespaces -o wide
      在这里插入图片描述
  • 开启
    • systemctl start kubelet
    • systemctl status kubelet
      在这里插入图片描述
k8s-node1(192.168.174.132) ,k8s-node2(192.168.174.133) 加入主节点
  • 在子节点上执行start命令开启k8s
  • 执行上面的节点命令,把node1加入主节点
    在这里插入图片描述
  • kubectl get nodes
    • node1为Ready状态
      在这里插入图片描述
      在这里插入图片描述
k8s常用命令
kubectl get nodes 查看所有主从节点的状态
kubectl get ns 获取所有namespace资源
kubectl get pods -n {$nameSpace} 获取指定namespace的pod
kubectl describe pod的名称 -n {$nameSpace} 查看某个pod的执行过程
kubectl logs --tail=1000 pod的名称 | less 查看日志
kubectl create -f xxx.yml 通过配置文件创建一个集群资源对象
kubectl delete -f xxx.yml 通过配置文件删除一个集群资源对象
kubectl delete pod名称 -n {$nameSpace} 通过pod删除集群资源
kubectl get service -n {$nameSpace} 查看pod的service情况
安装和配置NFS
  • yum install -y nfs-utils (三台都要做)

  • mkdir -p /opt/nfs/jenkins

  • vi /etc/exports 编写NFS的共享配置

    • 内容如下:
      • /opt/nfs/jenkins *(rw,no_root_squash) *代表对所有IP都开放此目录,rw是读写
  • systemctl enable nfs 设置开机启动

  • systemctl start nfs 启动

  • 在子节点查看

    • showmount -e 192.168.174.129
      在这里插入图片描述
  • 主节点上传配置
    在这里插入图片描述
    在这里插入图片描述

  • cd nfs-client

    • kubectl create -f .
      在这里插入图片描述
  • 创建kube-ops的namespace,因为我们把Jenkins-Master的pod放到kube-ops下

  • cd jenkins-master

    • kubectl create namespace kube-ops
    • 构建Jenkins-Master的pod资源 kubectl create -f .

在这里插入图片描述

  • 查看pod是否创建成功 kubectl get pods -n kube-ops -o wide
    在这里插入图片描述

  • 查看信息,并访问,查看Pod运行在那个Node上 kubectl describe pods -n kube-ops
    在这里插入图片描述

  • 查看分配的端口 kubectl get service -n kube-ops

  • 安装同上
    在这里插入图片描述
    在这里插入图片描述

  • 输入秘钥,不安装插件,创建lisi + 123456
    在这里插入图片描述

  • 替换源
    在这里插入图片描述
    在这里插入图片描述

  • http://192.168.174.132:31162/restart

  • 安装插件

    • Chinese
    • Git
    • Pipeline
    • Extended Choice Parameter
    • Kubernetes
  • 系统管理->系统配置->云->新建云->Kubernetes

    • kubernetes地址采用了kube的服务器发现:https://kubernetes.default.svc.cluster.local
    • namespace填kube-ops,然后点击Test Connection,如果出现 Connection test successful 的提示信息证明 Jenkins 已经可以和 Kubernetes 系统正常通信
    • Jenkins URL 地址:http://jenkins.kube-ops.svc.cluster.local:8080

在这里插入图片描述

jenkins-slave自定义镜像
  • 准备好的文件上传到服务器
    在这里插入图片描述

  • 构建镜像

    • docker build -t jenkins-slave-maven:latest .
      在这里插入图片描述
  • 镜像拷贝到harbor仓库

    • docker tag jenkins/jnlp-slave:latest 192.168.174.131:85/library/jenkins/jnlp-slave:latest
    • docker login -u admin -p Harbor12345 192.168.131.85
    • docker push 192.168.174.131:85/library/jenkins/jnlp-slave:latest

在这里插入图片描述
在这里插入图片描述

132的jenkins创建流水线项目(测试)
  • 创建一个用户名的凭证
    在这里插入图片描述
def git_address = "http://192.168.174.128:82/root/tensquare_parent.git"
def git_auth = "0e53c6eb-dffc-423c-b430-8d4e48953aa6"
//创建一个Pod的模板,label为jenkins-slave
podTemplate(label: 'jenkins-slave', cloud: 'kubernetes', containers: [
    containerTemplate(
        name: 'jnlp',
        image: "192.168.174.131:85/library/jenkins/jnlp-slave:latest"
    )
  ]
) 
{
    //引用jenkins-slave的pod模块来构建Jenkins-Slave的pod
    node("jenkins-slave"){
    // 第一步
        stage('拉取代码'){
            checkout([$class: 'GitSCM', branches: [[name: 'master']],userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
        }
    }
}
  • 构建
    • 可以在节点列表动态创建了节点
      在这里插入图片描述
      在这里插入图片描述
  • 构建成功,节点被回收
    在这里插入图片描述
    在这里插入图片描述

Jenkins+k8s+docker完成微服务持续集成

  • 编辑129机器的文件共享
    • vi /etc/exports
      • /opt/nfs/maven *(wr,no_root_squash)
      • systemctl restart nfs
        在这里插入图片描述
  • 131的jenkins添加凭证
    在这里插入图片描述
  • 新建流水线项目
    在这里插入图片描述

在这里插入图片描述

def git_address = "http://192.168.174.128:82/root/tensquare_parent.git"
def git_auth = "0e53c6eb-dffc-423c-b430-8d4e48953aa6"
//构建版本的名称
def tag = "latest"
//Harbor私服地址
def harbor_url = "192.168.174.131:85"
//Harbor的项目名称
def harbor_project_name = "tensquare"
//Harbor的凭证
def harbor_auth = "11c4a594-30f7-4f4c-af60-f7e715d1aea1"

podTemplate(label: 'jenkins-slave', cloud: 'kubernetes', containers: [
        containerTemplate(
            name: 'jnlp',
            image: "192.168.174.131:85/library/jenkins/jnlp-slave:latest"),
        containerTemplate(
            name: 'docker',
            image: "docker:stable",
            ttyEnabled: true,
            command: 'cat'),
],
volumes: [
    hostPathVolume(mountPath: '/var/run/docker.sock', hostPath:'/var/run/docker.sock'),
    nfsVolume(mountPath: '/usr/local/apache-maven/repo', serverAddress:'192.168.174.129' , serverPath: '/opt/nfs/maven'),
],)

{
    node("jenkins-slave"){
            // 第一步
            stage('拉取代码'){
                checkout([$class: 'GitSCM', branches: [[name: '${branch}']],
                userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
            } 
            // 第二步
            stage('代码编译'){
                //编译并安装公共工程
                sh "mvn -f tensquare_common clean install"
            } 
            // 第三步
            stage('构建镜像'){
                //把选择的项目信息转为数组
                def selectedProjects = "${project_name}".split(',')
                for(int i=0;i<selectedProjects.size();i++){
                //取出每个项目的名称和端口
                def currentProject = selectedProjects[i];
                //项目名称
                def currentProjectName = currentProject.split('@')[0]
                //项目启动端口
                def currentProjectPort = currentProject.split('@')[1]
                //定义镜像名称注意:在构建过程会发现无法创建仓库目录,是因为NFS共享目录权限不足,需更改权限还有Docker命令执行权限问题需要手动上传父工程依赖到NFS的Maven共享仓库目录中微服务部署到K8S
                def imageName = "${currentProjectName}:${tag}"
                //编译,构建本地镜像
                sh "mvn -f ${currentProjectName} clean package dockerfile:build"

                container('docker') {
                    //给镜像打标签
                    sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}"
                    //登录Harbor,并上传镜像
                    withCredentials([usernamePassword(credentialsId:"${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')])
                }
                {
                    //登录
                    sh "docker login -u ${username} -p ${password} ${harbor_url}"
                    //上传镜像
                    sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}"
                } 
                //删除本地镜像
                sh "docker rmi -f ${imageName}"
                sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}"
            } 
        }
    }
}
  • build 测试

  • 安装持续集成插件Kubernetes Continuous Deploy

    • 目前官方插件下载地址没有这个插件了,所以从网上找了个添加进去

在这里插入图片描述

  • 配置全局管理凭证k8s-auth

    • 进入主节点 cd /root/.kube/ ,cat config
      在这里插入图片描述
  • 复制内容,添加到Enter directly

    • 点击确定后得到一个全局ID
      在这里插入图片描述
  • 在每个微服务编写deploy.yml

    • 以eureka为例
---
apiVersion: v1
kind: Service
metadata:
  name: eureka
  labels:
    app: eureka
spec:
  type: NodePort
  ports:
    - port: 10086
      name: eureka
      targetPort: 10086
  selector:
    app: eureka
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: eureka
spec:
  serviceName: "eureka"
  replicas: 2
  selector:
    matchLabels:
      app: eureka
  template:
    metadata:
      labels:
        app: eureka
    spec:
      imagePullSecrets:
        - name: $SECRET_NAME
      containers:
        - name: eureka
          image: $IMAGE_NAME
          ports:
            - containerPort: 10086
          env:
            - name: MY_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: EUREKA_SERVER
              value: "http://eureka-0.eureka:10086/eureka/,http://eureka-1.eureka:10086/eureka/"
            - name: EUREKA_INSTANCE_HOSTNAME
              value: ${MY_POD_NAME}.eureka
  podManagementPolicy: "Parallel"
  • 修改每个服务的yml文件
    • 以eureka为例
server:
  port: ${PORT:10086}
spring:
  application:
    name: eureka

eureka:
  server:
    # 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
    eviction-interval-timer-in-ms: 5000
    enable-self-preservation: false
    use-read-only-response-cache: false
  client:
    # eureka client间隔多久去拉取服务注册信息 默认30s
    registry-fetch-interval-seconds: 5
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://127.0.0.1:${server.port}/eureka/}
  instance:
    # 心跳间隔时间,即发送一次心跳之后,多久在发起下一次(缺省为30s)
    lease-renewal-interval-in-seconds: 5
    # 在收到一次心跳之后,等待下一次心跳的空档时间,大于心跳间隔即可,即服务续约到期时间(缺省为90s)
    lease-expiration-duration-in-seconds: 10
    instance-id: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}:${server.port}@${random.long(1000000,9999999)}
    hostname: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}
  • 修改后的代码提交到gitlab

  • 在129服务器先登录 docker login -u admin -p Harbor12345 192.168.174.131:85
    在这里插入图片描述

  • 生成docker凭证,用于k8s到docker私服拉取镜像

kubectl create secret docker-registry registry-auth-secret --docker-server=192.168.174.131:85 --docker-username=admin --docker-password=Harbor12345 --docker-email=843635953@qq.com

在这里插入图片描述

  • 查看秘钥 kubectl get secret
    在这里插入图片描述

  • 修改流水线脚本

def git_address = "http://192.168.174.128:82/root/tensquare_parent.git"
def git_auth = "0e53c6eb-dffc-423c-b430-8d4e48953aa6"
//构建版本的名称
def tag = "latest"
//Harbor私服地址
def harbor_url = "192.168.174.131:85"
//Harbor的项目名称
def harbor_project_name = "tensquare"
//Harbor的凭证
def harbor_auth = "11c4a594-30f7-4f4c-af60-f7e715d1aea1"
//k8s凭证
def k8s_auth = "d60faedf-0e56-425f-8c22-6253697381fa"
//定义k8s连接harbor的凭证
def secret_name = "registry-auth-secret"

podTemplate(label: 'jenkins-slave', cloud: 'kubernetes', containers: [
        containerTemplate(
            name: 'jnlp',
            image: "192.168.174.131:85/library/jenkins/jnlp-slave:latest"),
        containerTemplate(
            name: 'docker',
            image: "docker:stable",
            ttyEnabled: true,
            command: 'cat'),
],
volumes: [
    hostPathVolume(mountPath: '/var/run/docker.sock', hostPath:'/var/run/docker.sock'),
    nfsVolume(mountPath: '/usr/local/apache-maven/repo', serverAddress:'192.168.174.129' , serverPath: '/opt/nfs/maven'),
],)

{
    node("jenkins-slave"){
            // 第一步
            stage('拉取代码'){
                checkout([$class: 'GitSCM', branches: [[name: '${branch}']],
                userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
            } 
            // 第二步
            stage('代码编译'){
                //编译并安装公共工程
                sh "mvn -f tensquare_common clean install"
            } 
            // 第三步
            stage('构建镜像'){
                //把选择的项目信息转为数组
                def selectedProjects = "${project_name}".split(',')
                for(int i=0;i<selectedProjects.size();i++){
                //取出每个项目的名称和端口
                def currentProject = selectedProjects[i];
                //项目名称
                def currentProjectName = currentProject.split('@')[0]
                //项目启动端口
                def currentProjectPort = currentProject.split('@')[1]
                //定义镜像名称注意:在构建过程会发现无法创建仓库目录,是因为NFS共享目录权限不足,需更改权限还有Docker命令执行权限问题需要手动上传父工程依赖到NFS的Maven共享仓库目录中微服务部署到K8S
                def imageName = "${currentProjectName}:${tag}"
                //编译,构建本地镜像
                sh "mvn -f ${currentProjectName} clean package dockerfile:build"

                container('docker') {
                    //给镜像打标签
                    sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}"
                    //登录Harbor,并上传镜像
                    withCredentials([usernamePassword(credentialsId:"${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')])
                }
                {
                    //登录
                    sh "docker login -u ${username} -p ${password} ${harbor_url}"
                    //上传镜像
                    sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}"
                } 
                //删除本地镜像
                sh "docker rmi -f ${imageName}"
                sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}"
            }

            def deploy_image_name = "${harbor_url}/${harbor_project_name}/${imageName}"
            //部署到K8S
            sh """
                sed -i 's#\$IMAGE_NAME#${deploy_image_name}#'${currentProjectName}/deploy.yml
                sed -i 's#\$SECRET_NAME#${secret_name}#'${currentProjectName}/deploy.yml
            """
            kubernetesDeploy configs: "${currentProjectName}/deploy.yml",kubeconfigId: "${k8s_auth}"
        }
    }
}
---
apiVersion: v1
kind: Service
metadata:
  name: zuul
  labels:
    app: zuul
spec:
  type: NodePort
  ports:
    - port: 10020
      name: zuul
      targetPort: 10020
  selector:
    app: zuul
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: zuul
spec:
  serviceName: "zuul"
  replicas: 2
  selector:
    matchLabels:
      app: zuul
  template:
    metadata:
      labels:
        app: zuul
    spec:
      imagePullSecrets:
        - name: $SECRET_NAME
      containers:
        - name: zuul
          image: $IMAGE_NAME
          ports:
            - containerPort: 10020
  podManagementPolicy: "Parallel"
server:
  port: 10020 # 端口

# 基本服务信息
spring:
  application:
    name: tensquare-zuul # 服务ID

# Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://eureka-0.eureka:10086/eureka/,http://eureka-1.eureka:10086/eureka/ # Eureka访问地址
  instance:
    prefer-ip-address: true

# 修改ribbon的超时时间
ribbon:
  ConnectTimeout: 1500 # 连接超时时间,默认500ms
  ReadTimeout: 3000  # 请求超时时间,默认1000ms


# 修改hystrix的熔断超时时间
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMillisecond: 2000 # 熔断超时时长,默认1000ms


# 网关路由配置
zuul:
  routes:
    admin:
      path: /admin/**
      serviceId: tensquare-admin-service
    gathering:
      path: /gathering/**
      serviceId: tensquare-gathering

  # jwt参数
jwt:
  config:
    key: tokenstr
    ttl: 1800000

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完结,撒花

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值