ruby sinatra mysql_一分钟开始持续集成之旅系列之:Ruby + Sinatra 应用

前言

现代软件工程越来越复杂,而开发效率随着软件复杂度增加呈指数型下降。为在提高开发效率的同时也能保证质量,越来越多团队开始践行敏捷开发方法。

持续集成是敏捷开发的重要实践之一。它倡导团队通过自动化构建工具频繁地验证软件可用性,从而尽早发现集成错误并集中精力改善软件质量。

本文将使用 CODING DevOps 工具链和腾讯云容器服务(下称 TKE)为 Ruby + Sinatra 应用项目配置持续集成过程:运行单元测试、构建 Docker 镜像、推送到制品库、部署到 K8s 集群,以实现自动化构建、测试、发布、部署。

可以看到这个 Web 应用项目的结构非常简单。然而随着项目规模的逐步增大、参与人员的不断增加,构建、测试、发布过程变得越来越复杂。单靠开发人员在本地机器上人工手动进行集成变得愈发困难,既消耗时间也分散精力,团队的协作效率越来越低。而借助持续集成,则可以自动化构建、测试、发布的过程,将开发人员从重复的人力劳动中解放出来,更专注于开发且更快地发现和解决问题。

在继续下面的步骤前,请确保在 CODING 项目中开启了“持续集成”和“制品库”功能。

ece3da6790e4772abb9641aad68ef938.png

ab2ba021ee8f3d376b925c0cdee23ccb.png

创建制品库

如今容器化部署已经是大势所趋,无论是伸缩性还稳定性都相较于传统的裸机部署提升不少。本文的应用也选择了容器化部署。容器化部署最后的发布产物则是容器镜像,故需要创建用于存放发布产物的 Docker 制品库。

b23c660e81c0aecf234ba9fbef7907fe.png

0ec137a6ba8cccb38ad4ff71deadc58e.png

设置制品库凭证

K8s 集群从制品库拖取镜像需要访问凭证,这里使用 CODING 制品库自动生成的访问令牌。这里要注意的是,访问令牌生成后需要立即复制下来,否则关闭访问令牌的窗口后将无法再次查看。

0b550f2f0232353365bc1a42d90f3ded.png

454d5362ed096cc9e2ac68e6e4ffe3ff.png

生成访问令牌后会得到一条 Docker 仓库的登录命令,例如:

docker login -u release-1587202817568 -p 2f4f129287b3319c52f760635fxxxxxxxxxxxxxx coding-public-docker.pkg.coding.net

其中提供了 3 部分信息:

仓库域名:coding-public-docker.pkg.coding.net

用户名:release-1587202817568

密码:2f4f129287b3319c52f760635fxxxxxxxxxxxxxx

在 TKE 的集群中创建 Secret,输入上面获得的仓库访问凭证。

dbfd4b54961c105a8dd8dbfbac0cedd5.png

9146524ffaff5537f5fb5152cc87ea57.png

设置集群凭据

要通过 CODING 持续集成触发 K8s 集群部署过程需要在 CODING 中录入集群凭据,以便在 CODING 持续集成中使用 kubectl 命令实现 K8s 集群控制。

在 TKE 控制台中找到“集群APIServer信息”,复制其中的“Kubeconfig”。

f02f1a40da36dbce3b41220df03b6717.png

在 CODING 的凭据管理中录入 Kubeconfig。

b578de09b48f27d52a0de676987184b7.png

8404bcafeafa9eb3ef2ad155bf69777b.png

25e2d5fa9cd3d741ce7e3d1ac5da8d88.png

1c6159556947315505828a8fef189c78.png

创建部署

为方便将应用部署 K8s 集群中,需要先创建 Deployment 工作负载,之后就可以通过 CODING 持续集成反复运行 kubectl deployment patch ... 命令来将新构建出来的应用镜像部署到 K8s 集群上。

由于现在还没有构建本文中 Ruby + Sinatra 应用的 Docker 镜像,这里选用 nginx r 镜像来代替,确保 Deployment 能正常跑起来。

19f62b7b36f3e7449518e0480be86379.png

0156f3d4f844d32f7d9a48fa0894eff1.png

37c5f30ccfa9b44ddd144248c4a13d13.png

创建构建计划

这里选择预置内容较少的“自定义构建过程”模板,之后在这个模板的基础做详细的配置。

8032c462df0c9b577f3e0cef50145898.png

f620c02f95591f98c3679a02ddd49fdb.png

回到“凭据管理”中编辑刚录入的 K8s 凭据,在“凭据授权”列表里勾选刚创建的构建计划并保存。

26baf9aee4d8dbc36175171eb2c0c5b8.png

60f358637ddca20b46d775a1221d9011.png

配置构建流程

这里把 Ruby + Sinatra 应用持续集成过程分成 6 个阶段:

开始

检出

运行单元测试

构建 Docker 镜像

推送到制品库

部署到 K8s 集群

从模板创建的构建计划已经包含了“开始”和“检出” 2 个阶段。其中“检出”阶段可以不用修改直接使用。

914205503de951b3efcd5005b688d1f4.png

下面对其他阶段进行完善。

“开始”阶段

此阶段是默认生成的,所有模板都会包含这个阶段。在这个阶段中可以设置一些全局使用的参数,如“构建基础环境”、“环境变量”等。在这里需要添加 3 个环境变量,它们会被后面阶段引用。

e383c634f3a563798f0ab44d18199383.png

CODING_DOCKER_REG_HOST:制品库主机,用于登录制品库。

DOCKER_IMAGE_NAME:Docker 镜像名称,用于构建和推送镜像。

TKE_CLUSTER_CREDENTIAL_ID:TKE 集群凭据 ID。

上述环境变量的值是根据上面创建的 Docker 制品库来设置的,可以在制品库指引中查看相关信息。注意,页面上的 Docker 镜像名称不完整,需要把 替换成实际的值,如果值为 ruby-sinatra,则镜像名称就是 coding-public-docker.pkg.coding.net/ruby-sinatra/release/ruby-sinatra。

2844a9e0d12718f1088a737277b9f80e.png

而 TKE 的集群凭据 ID 则可以在凭据管理中查看。

76b1a2ab3e5079f9d36c4e9e6a7e55f2.png

“运行单元测试”阶段

在这个阶段里,将运行代码中已经写好的单元测试代码。整个过程会在 Docker 容器中进行,这样可以节省准备运行环境的时间,也可以与后面构建 Docker 镜像时使用的基础环境保持一致。

首先给对模板创建出来的“3-1 自定义构建过程”删除掉,然后添加名为“运行单元测试”的阶段,之后在这个阶段里添加“执行 Pipeline 脚本”的步骤,并在右边的输入框中输入运行单元测试的脚本。这里使用 Jenkins Pipeline 来调用 docker run 命令来运行单元测试。

docker.image('ruby:2.6').withRun('-v $(pwd):/app -w /app') { c ->

sh 'bundle install'

sh 'rake test'

}

25ccc2107731a4105d53a920a7879c1f.png

“构建 Docker 镜像”阶段

接下来是配置 Docker 镜像的构建过程,同上一步类似,添加名为“构建 Docker 镜像”的阶段,在阶段里添加“执行 Pipeline 脚本”的步骤,在脚本输入框中输入脚本。这里使用了 Jenkins Pipeline 来构建 Docker 镜像。

docker.build("${env.DOCKER_IMAGE_NAME}:${env.GIT_BUILD_REF}")

96f74c0cbd66c0ace067540d8c454ab5.png

其中的镜像名称使用了 1-1 阶段设置的环境变量。而标签则使用内置的环境变量 GIT_BUILD_REF,其值对应“构建对应的 Git 修订版本号”。内置环境变量的具体说明请见 https://help.coding.net/docs/devops/ci/env.html

“推送到制品库”阶段

这是构建过程的最后一个阶段,和上一个阶段类似,添加名为“推送到制品库”的阶段,在阶段里添加“执行 Pipeline 脚本”的步骤,在脚本输入框中输入脚本。这里使用了 Jenkins Pipeline 来推送镜像到制品库。

docker.withRegistry("https://${env.CODING_DOCKER_REG_HOST}", "${env.CODING_ARTIFACTS_CREDENTIALS_ID}") {

docker.image("${env.DOCKER_IMAGE_NAME}:${env.GIT_BUILD_REF}").push()

}

d4169b7c18c07d0178173bd5ff39c6d2.png

脚本中用到了在 1-1 阶段定义的环境变量:CODING_DOCKER_REG_HOST 和 DOCKER_IMAGE_NAME。还有两个内置环境变量:CODING_ARTIFACTS_CREDENTIALS_ID 和 GIT_BUILD_REF。其中 CODING_ARTIFACTS_CREDENTIALS_ID 为制品库私钥凭据,用于登录制品库。

“部署到 K8s 集群”

这是构建过程的最后一个阶段,和上一个阶段类似,添加名为“部署到 K8s 集群”的阶段,在阶段里添加“执行 Pipeline 脚本”的步骤,在脚本输入框中输入脚本。这里同样使用了 Jenkins Pipeline 来调用 docker push 命令来运行单元测试。

withKubeConfig([credentialsId: "${env.TKE_CLUSTER_CREDENTIAL_ID}"]) {

sh "kubectl patch deployment ruby-sinatra --patch '{\"spec\": {\"template\": {\"spec\": {\"containers\": [{\"name\": \"ruby-sinatra\", \"image\": \"${env.DOCKER_IMAGE_NAME}:${env.GIT_BUILD_REF}\"}], \"imagePullSecrets\": [{\"name\": \"ruby-sinatra-reg\"}]}}}}'"

}

45abb5e9ec3dbc05d244eb67651595ae.png

脚本中用到了在 1-1 阶段定义的环境变量:TKE_CLUSTER_CREDENTIAL_ID。

配置完成后别忘了保存!

1d5c5e9c78398e97e1b3191c820120f5.png

这是完成后的完整流程。

312c8f139b455f148607a13beebba70b.png

此时,已经可以通过“立即构建”来手动触发持续集成过程了。

e4ff782339ca966155482ecd7d567a7e.png

dc80298f9a81439a844f64da9d9494b9.png

整个流程运行完成后,可以查看每一步的运行日志。

4b4767a94ac18186f62b8759e764ec6e.png

991d80377cb6f319c5fa6d0b1602bfc9.png

配置触发规则

CODING 持续集成提供了多种触发规则,如果默认配置无法满足需求,还可自行配置所需的规则。

bd18f7c27a38800656c1007dee269fad.png

查看构建产物

构建计划运行成功后,可以到 CODING 制品库查看持续集成的构建产物。

251cc637e13b94c357f819bd0935ba2b.png

查看部署结果

构建计划运行成功后,可以到 TKE 控制台查看 Deployment 的部署状态。

b15b65bf1776571b16bc876da7708494.png

简单的、自动化的部署可以用本文的方法来配置一个自动化的部署阶段。对于体系化、需要考虑回退、负载流量控制、发布时间窗口、更新策略等则可以使用 CODING 持续部署。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364941.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++语言实现-邻接表

图的邻接表实现 邻接表是图的一种链式存储结构。主要是应对于邻接矩阵在顶点多边少的时候,浪费空间的问题。它的方法就是声明两个结构。如下图所示: 先来看看伪代码: typedef char Vertextype; //表结点结构 struct ArcNode { int adjvex; …

使用Lucene的新FreeTextSuggester查找长尾建议

Lucene的“ 建议”模块提供了许多有趣的自动建议实现,以便在用户将每个字符输入搜索框时为他们提供实时搜索建议。 例如, WFSTCompletionLookup将所有建议及其权重编译到一个紧凑的有限状态传感器中 ,从而可以对基本建议进行快速前缀查找。 …

mysql 查看锁表日志_MYSQL 表锁情况查看

查看锁表情况mysql> show status like ‘Table%’;—————————-——–| Variable_name | Value |—————————-——–| Table_locks_immediate | 795505 || Table_locks_waited | 0 || Table_open_cache_hits | 0 || Table_open_cache_misses | 0 || Table_ope…

Java,Scala,Guava和Trove集合-它们可以容纳多少数据?

关于我们的数据结构,令人着迷的事情之一是,即使我们对它们非常熟悉,我们仍然很难说出像HashMap这样基本的东西在1GB的内存中可以容纳多少个项目。 我们可能会在学校,高级开发人员那里学到这一点,或者由于数据结构选择不…

switch 失效

switch 开关失效无法切换,可以关闭,无法开启。 发现问题点 require-table.js 中toggle value的数据类型不是 number 导致 (value ? no : yes )判断总为no; 前面将value 强制转换为number类型即可 转载于:https://www.cnblogs.c…

纯php socket mysql_PHP 连接 unix_socket MySQL

当MySQL使用Unix Socket启动时,直接使用localhost会发生了一个数据库错误,发生无法连接数据库错误。 Warning: mysql_connect() [function.mysql-connect]: [2002] 这时应当修改hostname,例如在CI 配置数据库 (database.php) 从: …

mysql为什么不能插入数据_mysql为啥不能插入数据

mysql为何不能插入数据?安装AppServ后首次使用mysql,没有图形界面,在“MySql Command Line Client”的操作如下:mysql> create database cars;Query OK, 1 row affected (0.00 sec)mysql> use cars;Database changedmysql&g…

mocha 测试 mysql_e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDrive

e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 二 图片验证码的识别 , 下面讲一下Node.js中如何访问数据库, 在做自动化测试过程中, 经常可能遇到需要到数据库取值,或是…

在Window上使用Jenkins自动发布Java工件

这篇文章将展示如何使用Jenkins Continuous Integration自动执行Java Web应用程序(使用MYSQL DB和基于Hibernate ORM在基于REST的Jersey2 Spring环境中开发的学生申请应用程序)的发布过程-上载发布工件到发布存储库。 如上一篇文章在Windows上使用Jenkin…

Python开发【第六篇】:模块

Python开发【第六篇】:模块 模块,用一砣代码实现了某个功能的代码集合。 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来…

在jsp文件中通过超链接访问servlet_Eclipse中创建Servlet

1.新建test1.jsp文件,输入如下代码代码解释:一个超链接,跳转到forwardServlet注意forwardServlet 这里是个Servlet2.在工程中新建Servlet3.输入Class名称,注意下边的Supper Class 它自动继承了HttpServlet选择next4.Create Servle…

C# 多线程学习系列四之ThreadPool取消、超时子线程操作以及ManualResetEvent和AutoResetEvent信号量的使用...

1、简介 虽然ThreadPool、Thread能开启子线程将一些任务交给子线程去承担,但是很多时候,因为某种原因,比如子线程发生异常、或者子线程的业务逻辑不符合我们的预期,那么这个时候我们必须关闭它,而不是让它继续执行,消耗资源.让CPU不在把时间和资源花在没有意义的代码上. 2、主线…

Oracle学习:新建表空间

1. 以 sysdba 身份登入Oracle sqlplus / as sysdba; 2. 创建表空间 create tablespace (空间名)fwptfs (数据文件存放路径)datafile D:\xxx (初始大小)size 500m (自动扩容,每次200m)autoextend on next 200m; 3. 创建用户 create user (用户名)fwptfs…

tomcat7使用dbcp连接池遇到的坑

项目部署在tomcat后每隔一段时间便会报错 Cause: java.sql.SQLException: Could not retrieve transation read-only status server ; SQL []; Could not retrieve transation read-only status server; nested exception is java.sql.SQLException: Could not retrieve transa…

纯CSS实现3D照片墙

HTML部分&#xff1a; <body><div class"photo-wrap"> <!-- 舞台 --><div class"container"> <!-- 容器 --><div class"img">我是中心</div><div class"img img01"><img src&q…

Guava之RangeMap

在Guava官方API上面可以得知&#xff1a;RangeMap是一种集合类型( collection type)&#xff0c;它将不相交、且不为空的Range&#xff08;key&#xff09;映射给一个值&#xff08;Value&#xff09;。和RangeSet不一样&#xff0c;RangeMap不可以将相邻的区间合并&#xff0c…

CSS3新增的伪类选择器

伪类选择器的作用&#xff1a;对已有选择器做进一步的限制&#xff0c;对已有选择器能匹配的元素做进一步的过滤。CSS 3提供的伪类选择器主要分为以下三类&#xff1a; 结构性伪类选择器UI元素状态伪类选择器其他伪类选择器 1、结构性伪类选择器 Selector:root&#xff1a;匹…

签名SOAP消息–生成封装的XML签名

数字签名是使数字内容真实可信的一种广泛使用的机制。 通过为某些内容生成数字签名&#xff0c;我们可以让另一方能够验证该内容。 通过此验证&#xff0c;它可以保证在我们签名后不会更改。 通过这个示例&#xff0c;我将分享如何为SOAP信封生成签名。 但是&#xff0c;这当然…

2019 The 19th Zhejiang University Programming Contest

感想&#xff1a; 今天三个人的状态比昨天计院校赛的状态要好很多&#xff0c;然而三个人都慢热体质导致签到题wa了很多发。最后虽然跟大家题数一样(6题)&#xff0c;然而输在罚时。 只能说&#xff0c;水题还是刷得少&#xff0c;看到签到都没灵感实在不应该。 题目链接&#…

openvas安装和基本使用

OpenVAS是开放式漏洞评估系统&#xff0c;也可以说它是一个包含着相关工具的网络扫描器。OpenVAS是开放式漏洞评估系统&#xff0c;也可以说它是一个包含着相关工具的网络扫描器。其核心部件是一个服务器&#xff0c;包括一套网络漏洞测试程序&#xff0c;可以检测远程系统和应…