当前位置: 首页 > news >正文

MySQL是如何做容器测试的?

传统的基础设施管理是一项手动任务,由系统管理员管理静态服务器。现代云平台的自动化能力改变了这种工作方式:基础设施通常被描述为“代码”,基础设施管理系统会对基础设施自动做出变更。因此,基础设施的变得更加动态,周转时间也要短得多。

\\

基础设施测试框架通常被用于验证机器镜像的状态(Amazon Machine Images、Google Compute Images或Oracle OCI Images)。随着容器基础设施的出现,容器基础设施的测试变得与机器镜像的测试一样重要。

\\

在MySQL,我们有很多基础设施,我们越来越多地使用容器来代替真实(虚拟)机器。此外,越来越多的核心基础设施运行在Oracle的云基础设施(OCI)上。这要求我们实现多个级别的自动化,并且可以利用基础设施测试来验证我们的服务器(或虚拟机、容器)的状态。基础设施测试还用于验证我们发布的一些工件的状态。

\\

在这篇博文中,我们将重点介绍如何使用自动化基础设施测试来验证MySQL Server Docker镜像。我们将比较三个可用于进行容器测试的框架,并给出示例代码。

\\

自动化基础设施测试

\\

基础设施测试用于测试基础设施的状态:Apache服务器是否在监听80端口?是否正确配置了DNS服务器,这些设置是否正确反映在resolv.conf文件中?要安装的二进制文件是否都已经存在于机器镜像中?

\\

这类测试可以作为bash脚本的一部分,因此通常被用于配置任务,或者在(手动)创建实例后进行手动验证。自动化基础设施测试更进一步,它假设需要对很多基础设施和脚本的正确性做出验证,以及动态的现代云环境有很多东西需要通过手动的方式处理。

\\

基础设施测试工具通常与Ansible、Puppet或Chef等配置工具结合使用。配置工具在机器上安装软件,测试框架则确保它们能够正常运行。然后,任何东西都可以通过代码来表示,并使用工具进行自动化。

\\

我们的重点是测试Docker镜像,对我们来说,这些工作有点偏向底层。由于我们所有的Docker镜像主要是由经过测试并发布的yum软件包层组成,这些层位于非常可靠的OS层之上,我们主要想要验证软件包的版本是否正确,以及这些二进制文件的功能是否正常。在镜像构建期间,可能会发生网络故障,出现软件包安装不完整的情况,我们想要通过自动化测试来捕捉它们。

\\

在评估测试工具时,需要考虑到以下两个方面的问题:

\\
  • 配置语言,即想要测试的内容(可用包、必要的文件等)\\t
  • 测试执行,即如何运行测试(local/ssh/container)\

对于以下的工具,我们将关注这两个方面的问题。这个领域最常见的工具包括:

\\
  • InSpec/Serverspec\\t
  • Goss\\t
  • Container Structure Test\

接下来,我们将逐个简要介绍它们。

\\

InSpec

\\

InSpec基于RSpec(Ruby)测试框架,并借鉴了Serverspec(也是基于RSpec构建,并被广泛采用)的经验。它是Chef生态系统的一部分,用于配置和测试基础设施。它的配置保存在一个ruby文件中。

\\

可以通过resources指定多种配置语言

\\

通过targets(local/ssh/docker)来测试执行

\\

Goss

\\

Goss是Serverspec的一个快速而简单的替代品,是使用Go语言开发的一个服务器测试和验证框架。它的配置保存在一个yaml文件中,这个文件可以很方便地从当前系统状态生成。

\\

支持多种配置语言

\\

支持在本地和Docker容器中执行测试(通过dgoss脚本)

\\

Container Structure Test

\\

Container Structure Test是一个用于验证容器镜像结构的框架。与Goss一样,它也是用Go语言编写,并使用了yaml配置文件。该项目于今年早些时候发布,它的应用范围相对较窄(只支持容器),但它提供了足够的功能来测试镜像。

\\
  • 支持的配置语言较少\\t
  • 测试执行仅限于本地容器\

示例:MySQL Server Images

\\

接下来,我们将演示如何安装所需工具,解释各个配置文件,并在本地运行测试。我们针对最新的MySQL Server容器(latest或8.0标签)运行测试。为了方便起见,我们跳过构建步骤,从公共注册表下载容器并在本地运行测试。在我们的构建管道中,我们首先构建容器,运行测试,在运行成功之后才会推送到公共注册表。可以通过输入以下命令来获取最新版本的mysql-server镜像:

\\
\docker pull mysql/mysql-server
\\

总的来说,我们想测试两个东西:

\\
  • 容器是否存在主机上,并包含正确的元数据\\t
  • 容器是否包含所有的包和二进制文件\

先决条件

\\

除了可用的Docker环境之外,运行该示例还需要在本地安装InSpec、Goss和Container Structure Test。

\\

InSpec的说明可以在这里找到:https://downloads.chef.io/inspec。在Linux平台上,可以通过运行以下命令安装Goss和Container Structure Test二进制文件:

\\
\curl -L https://github.com/aelsabbahy/goss/releases/download/v0.3.6/goss-linux-amd64 -o goss \u0026amp;\u0026amp; chmod +x goss\curl -L https://raw.githubusercontent.com/aelsabbahy/goss/master/extras/dgoss/dgoss -o dgoss \u0026amp;\u0026amp; chmod +x dgoss\curl -L https://storage.googleapis.com/container-structure-test/latest/container-structure-test-linux-amd64 -o container-structure-test \u0026amp;\u0026amp; chmod +x container-structure-test
\\

安装好所有二进制文件并将它们添加到系统路径中,然后就可以通过shell脚本运行测试。

\\

测试配置

\\

为了比较配置和测试执行过程的不同之处,我们提供了用于测试这三个框架的MySQL Server Docker镜像的示例文件:https://github.com/neumayer/mysql-server-image-tests。

\\

可以通过以下命令来克隆它:

\\
\git clone https://github.com/neumayer/mysql-server-image-tests.git
\\

存储库中包含的配置文件:

\\
  • mysql-server-inspec.rb\\t
  • goss.yaml\\t
  • mysql-server-container-structure-test.yml\

让我们来依次查看这些文件,先从InSpec配置文件开始:

\\
\control 'container' do                                                                                             \    impact 0.5                                                                                                       \    describe docker_container('mysql-server') do                                                                     \      it { should exist }                                                                                            \      it { should be_running }                                                                                       \      its('repo') { should eq 'mysql/mysql-server' }                                                                 \      its('ports') { should eq '3306/tcp, 33060/tcp' }                                                               \      its('command') { should match '/entrypoint.sh mysqld' }                                                        \    end                                                                                                              \  end                                                                                                                \  control 'server-package' do                                                                                        \    impact 0.5                                                                                                       \    describe package('mysql-community-server-minimal') do                                                            \      it { should be_installed }                                                                                     \      its ('version') { should match '8.0.12.*' }                                                                    \    end                                                                                                              \  end                                                                                                                \  control 'shell-package' do                                                                                         \    impact 0.5                                                                                                       \    describe package('mysql-shell') do                                                                               \      it { should be_installed }                                                                                     \      its ('version') { should match '8.0.12.*' }                                                                    \    end                                                                                                              \  end
\\

InSpec通过profile和control来组织测试用例,其中control是较小的单元,是与给定主题相关的一组测试。第一个control叫“container”,针对宿主机器运行,与运行在localhost上的Docker守护进程通信,验证容器是否正在运行。另外两个control检查容器内的包。这种区别很重要,因为后两个control可以针对localhost、ssh主机或Docker容器运行。在我们的例子中,我们让它们针对容器运行,这样可以带来非常好的可重用性和灵活性。虽然我们在示例中只使用了Docker和包资源,但实际上control可以使用任何现有的InSpec资源。

\\

下面是运行流程:

\\
  • 启动容器\\t
  • 针对localhost运行 “container” control\\t
  • 针对容器运行剩余的control\

脚本看起来是这样的:

\\
\docker run -d --name mysql-server mysql/mysql-server\inspec exec mysql-server-inspec.rb --controls container\inspec exec mysql-server-inspec.rb -t docker://mysql-server --controls server-package
\\

如果运行成功,InSpec将输出以下内容:

\\
\Profile: tests from mysql-server-inspec.rb (tests from mysql-server-inspec.rb)\Version: (not specified)\Target:  local://\\  ✔  container: Docker Container mysql-server\     ✔  Docker Container mysql-server should exist\     ✔  Docker Container mysql-server should be running\     ✔  Docker Container mysql-server repo should eq \"mysql/mysql-server\"\     ✔  Docker Container mysql-server ports should eq \"3306/tcp, 33060/tcp\"\     ✔  Docker Container mysql-server command should match \"/entrypoint.sh mysqld\"\\\Profile Summary: 1 successful control, 0 control failures, 0 controls skipped\Test Summary: 5 successful, 0 failures, 0 skipped\\Profile: tests from mysql-server-inspec.rb (tests from mysql-server-inspec.rb)\Version: (not specified)\Target:  docker://d06da2588b80a4ee9b839b55c2f719ab9e860904eeb831b71488704f50f8b994\\  ✔  server-package: System Package mysql-community-server-minimal\     ✔  System Package mysql-community-server-minimal should be installed\     ✔  System Package mysql-community-server-minimal version should match \"8.0.12.*\"\\\Profile Summary: 1 successful control, 0 control failures, 0 controls skipped\Test Summary: 2 successful, 0 failures, 0 skipped
\\

Goss的配置文件如下所示:

\\
\file:                                                                                                              \    /usr/sbin/mysqld:                                                                                                \      exists: true                                                                                                   \      contains: []                                                                                                   \  package:                                                                                                           \    mysql-community-server-minimal:                                                                                  \      installed: true                                                                                                \    mysql-shell:                                                                                                     \      installed: true                                                                                                \  port:                                                                                                              \    tcp6:3306:                                                                                                       \      listening: true                                                                                                \      ip: []                                                                                                         \    tcp6:33060:                                                                                                      \      listening: true                                                                                                \      ip: []                                                                                                         \  user:                                                                                                              \    mysql:                                                                                                           \      exists: true                                                                                                   \  process:                                                                                                           \    mysqld:                                                                                                          \      running: true
\\

除了mysqld文件,我们还要检查所需的软件包是否已安装、公开端口是否正确以及所需的进程是否在运行。Goss将为我们启动容器:

\\
\GOSS_SLEEP=10 dgoss run -p 3306:3306 mysql/mysql-server
\\

因为设置了GOSS_SLEEP,所以我们的服务器有足够时间完成初始化,其余参数被传给docker run。输出如下:

\\
\INFO: Starting docker container\INFO: Container ID: 75bc8869\INFO: Sleeping for 10\INFO: Running Tests\File: /usr/sbin/mysqld: exists: matches expectation: [true]\User: mysql: exists: matches expectation: [true]\Process: mysqld: running: matches expectation: [true]\Port: tcp6:33060: listening: matches expectation: [true]\Port: tcp6:33060: ip: matches expectation: [[]]\Port: tcp6:3306: listening: matches expectation: [true]\Port: tcp6:3306: ip: matches expectation: [[]]\Package: mysql-shell: installed: matches expectation: [true]\Package: mysql-community-server-minimal: installed: matches expectation: [true]\\Total Duration: 0.038s\Count: 9, Failed: 0, Skipped: 0\INFO: Deleting container
\\

Container Structure Test的yaml配置片段如下:

\\
\schemaVersion: \"2.0.0\"                                                                                             \  metadataTest:                                                                                                      \    exposedPorts: [ \"3306\

相关文章:

  • C# 异或校验算法
  • gitbook.explore更新升级了, 不能再搜索了
  • 通过flat.vmdk恢复esxi虚拟机
  • MFS分布式存储部署
  • 使用shell脚本自动安装Apache2.4.35
  • JAVA 同步实现原理
  • Java Agent 学习笔记
  • mysql如何直接查出从1开始递增的数
  • GlassFish新纪元
  • 基于树莓派的桌上足球计分器
  • C# 高级编程03----细节内容
  • mongodb之 oplog 日志详解
  • 动态库空间优化
  • 贝叶斯分类器
  • 【完整教程】新版直播频道上线,马上开始创建你的直播吧!
  • 【译】JS基础算法脚本:字符串结尾
  • egg(89)--egg之redis的发布和订阅
  • ES10 特性的完整指南
  • GitUp, 你不可错过的秀外慧中的git工具
  • Gradle 5.0 正式版发布
  • Java-详解HashMap
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • Solarized Scheme
  • VuePress 静态网站生成
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • windows下如何用phpstorm同步测试服务器
  • 从PHP迁移至Golang - 基础篇
  • 大整数乘法-表格法
  • 动态魔术使用DBMS_SQL
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 前端技术周刊 2019-01-14:客户端存储
  • 前端面试之闭包
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 详解NodeJs流之一
  • 怎么把视频里的音乐提取出来
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • #stm32驱动外设模块总结w5500模块
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (第二周)效能测试
  • (动态规划)5. 最长回文子串 java解决
  • (二)学习JVM —— 垃圾回收机制
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .Net的C#语言取月份数值对应的MonthName值
  • .NET开发者必备的11款免费工具
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .Net下的签名与混淆
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • @reference注解_Dubbo配置参考手册之dubbo:reference