阿里巴巴集团在中国开源年会上正式开源了其酝酿已久的容器pouch项目,为开源容器引擎家族又添加一名新成员。当前很多云服务提供商在其服务中添加了开源容器引擎,但其测试方式往往只是通过devops进行简单的功能测试,甚至未经测试直接使用开源社区的二进制发行版本。这使得很多缺陷遗漏到下游用户手中。开源引擎在商用时如何保障质量呢?本文通过多个类型的测试来系统的阐述容器引擎质量保障方案。
功能测试
适合场景:
容器功能验证是最基本的质量保障方式,适合于所有使用容器引擎的场景。功能测试中需要建立特性树,覆盖容器引擎常用的命令,如attach、build、commit、cp、create、diff、events、exec、export、history、images等。同时还需要尽可能多的覆盖到每一个命令中的选项,如create--hostname。从对外接口来分类,容器引擎的接口分为命令行接口和restapi接口。
通常做法:
直接使用开源社区中的自动化测试程序。但社区用例通常采用containerincontainer的方式执行功能测试,这样做的好处是可以最大限度的保障测试环境的一致性。不足之处在于,因为采用了容器嵌套,被测试的容器引擎是containerincontainer中的容器中的引擎,而不是主机中的容器引擎。这会导致容器引擎和宿主机适配的缺陷可能遗漏到下游。
优秀实践:
针对社区测试的不足,解决的方法是将整体的测试执行从容器中移植到宿主机中,将测试执行方式由containerincontainer转变为containerinhost。具体的做法是,首先将containerincontainer中的测试镜像对应的Dockerfile中的环境配置工作移植到主机中,之后使用"gotest-c-o${test_binary}"命令将社区源码用例在容器中编译为二进制后在主机中直接运行。这样做的好处是,被测容器引擎是宿主机中的容器引擎,而不是containerincontainer中容器嵌套中的引擎,保证了被测对象的准确性。
适合场景:
压力测试适用于业务中可能遇到大量用户请求的场景。当主机遇到大量请求时,会导致主机资源负载的增加。基本的功能测试只能验证容器引擎的功能是否正常,却无法保证容器引擎的各种操作在宿主机高负载的情况下仍然能够成功执行。通过压力测试可以触发一些在软件设计中未考虑到的隐藏较深的缺陷。
通常做法:
业界的压力测试主要使用开源测试套(如stress、fio等)对被测对象持续加压。这种方式的问题是加压方式比较单一,无法模拟出真实业务的压力场景。某些业务(如用户争抢优惠资源)往往会在几秒钟内会有短时间的压力峰值,之后会趋于平缓。对于这种业务,通常的压力测试方法是无法覆盖到的。
优秀实践:
将宿主机的加压方式分为3中,即CPU加压、内存加压和IO加压。同时可以结合各种业务场景设计对应的加压模型。常见的加压模型有阶梯压力、周期性稳定压力、随机脉冲压力、长期稳定压力。对于短时间内的压力峰值的场景,可以使用随机脉冲加压方式进行模拟,从而保证了加压方式更贴近于真实的场景。
CPU负载加压:使宿主机CPU资源占有率达到30%~100%。
内存负载加压:通过频繁malloc/free操作实现宿主机内存的频繁操作,使内存占用率达到30%~80%。
IO加压:使用fio工具可以实现对多种IO类型(sync,mmap,libaio,posixaio,SGv3,splice,null,network,syslet,guasi等)进行加压。
长时间稳定性测试
适合场景:
长时间稳定性测试适用于需要长久运行容器并且业务不能中断的业务场景。功能测试无法验证系统能否稳定运行较长的时间,一些隐藏较深的缺陷会在系统运行一段时间后爆发,如文件句柄泄露、各状态间锁冲突等。需要对容器引擎进行长时间稳定性测试,执行时间通常在7天以上。
通常做法:
将业务部署到容器中,同时模拟用户请求,观察业务运行一段时间。不足之处在于,业务本身只能覆盖与本业务最相关的部分接口,无法有效覆盖所有接口,并且无法模拟出容器各种状态频繁切换的场景。因此无法触发一些容器状态切换时锁冲突等深层缺陷。
优秀实践:
列举容器所有状态,并遍历状态切换的所有路径。从一个状态切换到另一个状态有多种方式。例如从running状态切换到exited状态可以使用stop命令或kill命令,而每一个命令又对应着多种命令选项。容器状态迁移的方式如下图所示,在执行测试时首先批量启动若干容器,之后通过随机算法频繁的随机切换容器的状态来达到触发深层缺陷的目的。
适合场景:
与私有云相比,公有云对安全性要求较高。需要针对该场景进行安全加固。该项安全测试主要是针对基于runc的容器引擎,runv的加固方式不在其中。
通常做法:
执行开源社区已有的容器安全测试套来确认环境的安全性。不足之处在于社区中只包含了通用的安全检测点,无法针对自有的特定环境进行安全加固的验证。
优秀实践:
将容器安全测试分为安全合规测试和安全渗透测试。
1.安全合规测试
安全合规专项测试排查涉及到账号管理、文件管理、密码和密钥管理、端口占用、日志管理等内容。因安全合规测试涉及内容较多,下面只列举出部分例子,其余部分在此不再敖述,感兴趣的读者可以阅读网络安全的书籍。
· 账号管理:应用账号不能写死在代码中;需要单独接口进行账号权限认证。
· 文件管理:禁止存在无主文件;文件权限需要最小化处理,配置文件权限不高于644,执行文件权限不高于744。
· 密码和密钥管理:密钥不可硬编码到代码中;禁止使用不安全的加密算法(DES、RSA、MD2等);登录hub时需要对密码进行加密(aes加密)。
· 端口占用:通过nmap程序获取容器引擎所占用的端口,确认是否有多余的端口。
· 日志管理:需要提供日志防爆功能,防止恶意用户进行不断操作产生大量日志导致磁盘占满;daemon日志中不能包含debug信息;日志中不能存在明文敏感数据。
· 安全扫描测试:通过govet、ineffassign、goastscanner、golint等工具可以对源码进行扫描。
除了以上源码扫描工具,还有一些其他开源或商业扫描工具可以使用。如
Nessus(扫描安全漏洞)、Retina(扫描安全漏洞)、Bitdefender(病毒扫描)、AviraAntiVirServer(病毒扫描)、KasperskyEndpointSecurity(病毒扫描)、McAfeeVirusScanEnterprise(病毒扫描)、SymantecEndpointProtection(病毒扫描)、TrendMicroOfficeScan(病毒扫描)、Nmap(端口检查)。
模糊测试(Fuzztesting):针对容器引擎的特点进行fuzz建模,通过peach和Codenomicon工具可以实现容器引擎接口和api测试,通过测试工具将生成的随机数据发送给引擎进行系统验证。
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。