草庐IT

gitlab流水线自动部署流程

柠檬不酸495 2023-04-04 原文

自动部署之前,需要准备的是放gitlab的服务器,运行gitlab-runner的服务器以及后端代码运行的服务器。需要先搭建好runner并放在自己的项目中,gitlab的 runner 主要作用是用于监视相关项目的变动,然后可以自动拉取对应的分支进行自动构建,测试,和部署。就是对编写好的ci文件进行管理。
其自动部署就是将存放在gitlab上的仓库代码利用rsync实时同步到实际要跑后端代码的那台服务器上,文件传输的方式就是利用SSH,将文件传输过去之后继续让代码后台跑起来,这样就实现了实时部署。
前端的这个部署文件也是将前端代码传输到后端的服务器上,与后端的jar包放在同一个目录下是一个static文件夹下,然后利用nginx进行方向代理进行端口转发就可以了。
首先需要了解的前提:

  1. runner将整个项目文件导入到一个docker中,设置了将docker作为执行器的话。所有在ci文件里写的指令都是在docker容器中运行的,所以实际上是运行runner的这台服务器里的一个docker在向后端服务器同步文件。
  2. 作为一个什么都没有的docker它的基本运行环境应该是乌班图,所以在ci文件里写的指令应该是基于ubantu的。首先要进行代码的打包,前后端都一样,要运行npm或者mvn指令进行打包,这两种指令依赖于ci文件中image的指定,一般都有了无需特别安装。
  3. 注意,可以想象,在刚进去这个docker的时候就处于整个仓库的根目录下,可以直接进行打包。
  4. 将rsync安装在docker里,为接下来文件传输做准备。注意rsync一般都是利用ssh进行文件传输的。所以难题来了,怎么让后端服务器认识这个docker呢,这个docker也没有已经生成ji好的公私钥。
  5. 为了解决上述问题,我们就需要准备一对主机公私钥,用传递变量的形式注入docker作为其身份信息。然后将后端服务器的主机公钥作为known_host保存到docker这样后期后端验证docker身份时验证通过。之后将docker运行的服务器中的root用户公钥存入pubkey文件,并也存入后端服务器的authorized_keys中,这样docker向后端服务器传输文件时就可以认识docker。
    到此,基本需要注意的都完成了接下来是整个部署流程

准备一对公私钥

在自己本机生成一对公私钥,将public_key和private_key分别在gitlab界面中的项目组中设为变量
添加变量的方式在设置,进入CI/CD,点击变量即可添加

在gitlab界面添加公私钥以及追加known_hosts

这个公私钥就是第一步准备好的公私钥,之后要用这对公私钥进行两台主机之间的文件传输。追加的known_hosts是后端运行代码的服务器的公钥

编写ci文件

image: maven:3-jdk-11  # 要用到的打包工具以及运行环境 这是从image库里看到的是一个docker

stages:
  - test
  - package
  - deploy

maven-test:          # CI/CD 任务名称
    stage: test      # 任务阶段,一般有 build、test、deploy等。执行顺序为:build →test →deploy
    services:
      - name: mysql		#还需要一个mysql服务器
        alias: db
    script:          # 执行任务的脚本,每条是一个 Shell 命令。
      - mvn test -s ci_settings.xml -Dspring.profiles.active=dev # 先用mvn test进行打包 执行jar包的命令 xml文件是项目配置文件可以不写
                     # 通过环境变量$DB_URL、$DB_USER和$DB_PASS提供密码信息。环境变量在仓库设置中配置。
    except:          # 不在 developer 和 master 测试。maven package 会自动执行编译和部署,因此不需要再次执行test阶段的任务。
      - main
      - dev

idrsmc-test-and-package: #名字随意起
    stage: package
    services:
      - name: mysql
        alias: db
    script:
      - mvn package -s ci_settings.xml -Dspring.profiles.active=dev
    artifacts:      # 任务成果,一般为编译后的产物。
        paths:      # 也可以指定一个或多个目录。
          - target/migration-2.1.0-SNAPSHOT.jar
          - target/site/apidocs # api接口文件
        expire_in: 1 week # 产物会占用 GitLab 服务器的空间,应当定期清理。
    only:           # 只在 developer 分支和 master 分支执行部署操作。
      - dev
      - main

deploy-server:
  stage: deploy
  image: ubuntu
  needs:
    - idrsmc-test-and-package # 需要先完成上一步
  script:
    - |
      echo -e "\e[0Ksection_start:`date +%s`:my_first_section\r\e[0K准备 SSH 凭据"
        which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )
        which rsync || ( apt-get update -y && apt-get install rsync -y )
        eval $(ssh-agent -s)
        echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
        mkdir -p ~/.ssh
        chmod 700 ~/.ssh
        echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
        chmod 644 ~/.ssh/known_hosts
        echo "$SSH_PUBLIC_KEY" > ~/.ssh/id_rsa.pub
        chmod 644 ~/.ssh/id_rsa.pub
        echo "$SSH_CERTIFICATE" > ~/.ssh/id_rsa-cert.pub
        chmod 644 ~/.ssh/id_rsa-cert.pub
      echo -e "\e[0Ksection_end:`date +%s`:my_first_section\r\e[0K" 
      #  上述都是在为了之后的文件传输进行铺垫,就是要利用rsync进行ssh传输
      

      echo -e "\e[0Ksection_start:`date +%s`:my_first_section\r\e[0K部署到 $TARGET_SERVER"
        rsync jar包目录 $TARGET_SERVER:文件目录
        ssh $TARGET_SERVER "systemctl restart 项目名称.service" #运行项目
      echo -e "\e[0Ksection_end:`date +%s`:my_first_section\r\e[0K"
  only:
    - dev
    - main

执行流水线

部署好之后,进入gitlab项目,点击流水线,就可以运行了。

流水线执行过程中可能会遇到的问题:

  1. 没有可用的runner所以任务暂存之类,建议直接到设置-》CI/CD中查看runner,是否有可以用的,有的话就检查一下自己ci文件中有没有写tags,tags用来绑定runner
  2. xxx指令不存在,大概是没有安装什么软件,直接安装就好了,注意使用的是ubantu系统的指令(这个好像是可以在哪里修改系统类型)
  3. ssh认证出错,应该主机公钥和用户公钥没有写对。用户公钥是到root下的.ssh目录里找,主机公钥是要到/etc/ssh里面找以ssh_host开头的就是主机公钥

如何远程执行jar包

建议将运行jar作为一个服务进行启动,这样ssh 指令可以直接启动。此时我们的指令还是在ssh环境里,所以要符合ssh语法。写一个jar.service文件

有关gitlab流水线自动部署流程的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  4. ruby-on-rails - Ruby on Rails 可以部署在 Azure 网站上吗? - 2

    我可以在Azure网站上部署RubyonRails吗? 最佳答案 还没有。目前仅支持.NET和PHP。 关于ruby-on-rails-RubyonRails可以部署在Azure网站上吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/12964010/

  5. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  6. jenkins部署1--jenkins+gitee持续集成 - 2

    前置步骤我们都操作完了,这篇开始介绍jenkins的集成。话不多说,看操作1、登录进入jenkins后会让你选择安装插件,选择第一个默认的就行。安装完成后设置账号密码,重新登录。2、配置JDK和Git都需要执行路径,所以需要先把执行路径找到,先进入服务器的docker容器,2.1JDK的路径root@69eef9ee86cf:/usr/bin#echo$JAVA_HOME/usr/local/openjdk-82.2Git的路径root@69eef9ee86cf:/#whichgit/usr/bin/git3、先配置JDK和Git。点击:ManageJenkins>>GlobalToolCon

  7. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  8. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  9. Ruby,使用包含 TK GUI 的 ocra 部署一个 exe - 2

    Ocra无法处理需要“tk”的应用程序require'tk'puts'nope'用奥克拉http://github.com/larsch/ocra不起作用(如链接中的一个问题所述)问题:https://github.com/larsch/ocra/issues/29(Ocra是1.9的"new"rubyscript2exe,本质上它用于将rb脚本部署为可执行文件)唯一的问题似乎是缺少tcl的DLL文件我不认为这是一个问题据我所知,问题是缺少tk的DLL文件如果它们是已知的,则可以在执行ocra时将它们包括在内有没有办法知道tk工作所需的DLL依赖项? 最佳答

  10. ruby - 在 ruby​​ 中使用自动创建插入数组 - 2

    我想知道是否可以通过自动创建数组来插入数组,如果数组不存在的话,就像在PHP中一样:$toto[]='titi';如果尚未定义$toto,它将创建数组并将“titi”压入。如果已经存在,它只会推送。在Ruby中我必须这样做:toto||=[]toto.push('titi')可以一行完成吗?因为如果我有一个循环,它会测试“||=”,除了第一次:Person.all.eachdo|person|toto||=[]#with1billionofperson,thislineisuseless999999999times...toto.push(person.name)你有更好的解决方案吗?

随机推荐