Top Banner
Building Efficient Parallel Testing Platforms with Docker Laura Frank @rhein_wein Software En g ineer @codeship [email protected]
67

Building Efficient Parallel Testing Platforms with Docker

Jan 20, 2017

Download

Technology

Laura Frank
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Building Efficient Parallel Testing Platforms with Docker

Building Efficient Parallel Testing Platforms with Docker

Laura Frank @rhein_wein Software Engineer @codeship

[email protected]

Page 2: Building Efficient Parallel Testing Platforms with Docker
Page 3: Building Efficient Parallel Testing Platforms with Docker

Automated builds take too long.

PROBLEM

Page 4: Building Efficient Parallel Testing Platforms with Docker

laurel comics

Page 5: Building Efficient Parallel Testing Platforms with Docker

Optimize automated tests by running them in parallel.

PROPOSED SOLUTION

Page 6: Building Efficient Parallel Testing Platforms with Docker

You’ll quickly reach the limit of how much you can optimize a test itself.

PROPOSED SOLUTION

Page 7: Building Efficient Parallel Testing Platforms with Docker

Instead, let’s build a more performant system.

PROPOSED SOLUTION

Page 8: Building Efficient Parallel Testing Platforms with Docker

And let’s do it with containers 💃

PROPOSED SOLUTION

Page 9: Building Efficient Parallel Testing Platforms with Docker

Create a customizable, flexible test environment that enables us to run

tests in parallel.

GOAL

Page 10: Building Efficient Parallel Testing Platforms with Docker

codeship.com/resources

• The why and how of parallel testing • DIY with LXC

• Using Docker and the Docker ecosystem

Agenda

Page 11: Building Efficient Parallel Testing Platforms with Docker

Parallel Testing

Page 12: Building Efficient Parallel Testing Platforms with Docker

Spend less time waiting around for your automated testing steps and deployments to finish.

• Ship newest code to production faster • Be alerted quickly when tests fail

Why?

If you’re still not sure why testing is important… let’s have a different conversation. 😊

Page 13: Building Efficient Parallel Testing Platforms with Docker

Developers should have full autonomy over testing environments, and the way tests are executed.

• Move testing commands to separate pipelines • Designate commands to be run serially or in parallel • Declare specific dependencies for each service

Why?

Page 14: Building Efficient Parallel Testing Platforms with Docker

• For local testing, e.g. unit and integration tests run by a development team

• On internal CI/CD systems • As part of a hosted CI/CD solution (like Codeship)

Where?

Page 15: Building Efficient Parallel Testing Platforms with Docker

• Split up testing tasks • Give developer full control of dependencies per task • Use containers to run multiple tests at once

How?

Page 16: Building Efficient Parallel Testing Platforms with Docker
Page 17: Building Efficient Parallel Testing Platforms with Docker

Run tasks across multiple processors in parallel

computing environments

TASK PARALLELISM

Page 18: Building Efficient Parallel Testing Platforms with Docker

Distributed Task Parallelism

A distributed system of containerized computing environments takes the place

of a single multiprocessor machine

A container is a process, not a small VM

Page 19: Building Efficient Parallel Testing Platforms with Docker

Why not VMs?

• Isolation of running builds on infrastructure • Challenges with dependency management • No clean interface for imposing resource limits • Infrastructure is underutilized which makes it

expensive • People use containers!

Page 20: Building Efficient Parallel Testing Platforms with Docker

Containers, duh!

• Impose resource limits and increase virtualization density

• Run customer code in isolation

• Provide consistent build environment across many build runs

• Run testing tasks in parallel 👍

Page 21: Building Efficient Parallel Testing Platforms with Docker

DIY with LXC

Page 22: Building Efficient Parallel Testing Platforms with Docker

Codeship has been powered by containers since the

very beginning

Page 23: Building Efficient Parallel Testing Platforms with Docker

codeship.com/resources

Codeship’s LXC-based Platform

40K builds per day 8M builds per year

Page 24: Building Efficient Parallel Testing Platforms with Docker

Architecture

• Universal container with provided dependencies • Fixed amount of available containers per VM • Implement parallel testing pattern using

pipelines with ParallelCI • Users can have N pipelines running in isolation

during a build

Page 25: Building Efficient Parallel Testing Platforms with Docker

User Commands

Universal Container

Pipeline

Heroku

Deployment Provider

Capistrano

AppEngine

Elastic Beanstalk

etc…

User Commands

Universal Container

Pipeline

User Commands

Universal Container

Pipeline

High-level Build Workflow

test pipelines deploy pipeline

Page 26: Building Efficient Parallel Testing Platforms with Docker

commit deploy

Not just a test runner, but a complete system

Page 27: Building Efficient Parallel Testing Platforms with Docker

build worker

build dispatcher

account/project service

infrastructure service

new code!

Page 28: Building Efficient Parallel Testing Platforms with Docker

build worker

build dispatcher• receives webhooks • transforms payload (keep the good bits) • send payload to account/project service

• read config and start workload • sends updates upstream

account/project service• receives payload • identifies build configuration • sends config to build machines

infrastructure service• keep track of infra utilization • upscale/downscale

Page 29: Building Efficient Parallel Testing Platforms with Docker

worker

Compute Instance

container container

container container

container container

container container

container container

worker

Compute Instance

container container

container container

container container

container container

container container

worker

Compute Instance

container container

container container

container container

container container

container container

Page 30: Building Efficient Parallel Testing Platforms with Docker

worker

Compute Instance

container container

container container

container container

container container

container container

worker

Compute Instance

container container

container container

container container

container container

container container

worker

Compute Instance

container container

container container

container container

container container

container container

Page 31: Building Efficient Parallel Testing Platforms with Docker

Good Stuff

• Extremely simple implementation (no extra scheduler) • Just Works™ • Pretty okay virtualization density • No allocation time for builds — slots are always open

Page 32: Building Efficient Parallel Testing Platforms with Docker

Not So Good Stuff

• Parity between dev and test • Can’t really debug locally • No useable interface between user and container • All pipelines run all services and dependencies

Page 33: Building Efficient Parallel Testing Platforms with Docker

We weren’t able to provide the best, most efficient product to our

customers (or ourselves)

Page 34: Building Efficient Parallel Testing Platforms with Docker

Parallel Testing with Docker 👌

Page 35: Building Efficient Parallel Testing Platforms with Docker

Create a customizable, flexible test environment that enables us to run

tests in parallel

GOAL

Page 36: Building Efficient Parallel Testing Platforms with Docker

Big Wins with Docker

Even before 1.0, Docker was a clear choice

• Support and tooling • Standardization • Community of motivated developers

Page 37: Building Efficient Parallel Testing Platforms with Docker

Using Docker allowed us to build a much more flexible testing

platform than with LXC alone

Page 38: Building Efficient Parallel Testing Platforms with Docker

A Docker-based Testing Platform

• Different enough from the LXC-based platform to be a new tool

• Development started in 2014, beta in 2015 • Official launch February 2016 • Written in golfing (LXC-based platform is in Ruby)

Page 39: Building Efficient Parallel Testing Platforms with Docker
Page 40: Building Efficient Parallel Testing Platforms with Docker

Managing containers with Docker allowed us to improve our

parallel testing workflow

Page 41: Building Efficient Parallel Testing Platforms with Docker

A New Parallel Workflow

• Introducing services adds additional layer of flexibility • Loosen coupling between steps and services — execute

N steps against M services • Parallel and serial steps can be grouped and ordered in

any way

Page 42: Building Efficient Parallel Testing Platforms with Docker

Services

• Pull image from any registry or build from Dockerfile • Optimize service for testing tasks • Fully customizable by the user

Page 43: Building Efficient Parallel Testing Platforms with Docker

Steps

• Each step is executed in an independent environment • Has own set of containers (services)

• Can be nested in serial and parallel groups

Page 44: Building Efficient Parallel Testing Platforms with Docker

Steps

• Two functions • Run: execute a command against a service • Push: push image to registry

• Tag matching (simple string or regex) to run steps on certain branches or tagged releases

Page 45: Building Efficient Parallel Testing Platforms with Docker

T1 T1 T1

User Commands

Universal Container

Pipeline

User Commands

Universal Container

Pipeline

User Commands

Universal Container

Pipeline

High-Level Build Workflow: The “Old” Way

Page 46: Building Efficient Parallel Testing Platforms with Docker

Step

post

gres

redi

s

command

web

Step

command

ruby

T1 T2 T3

Step

post

gres

redi

s

command

web

Step

post

gres

redi

s

command

web

High-Level Build Workflow: The New Way

Page 47: Building Efficient Parallel Testing Platforms with Docker

build worker

build dispatcheraccount/project service

build orchestrator

new code!

SQS queue

Page 48: Building Efficient Parallel Testing Platforms with Docker

build worker

build dispatcher• receives webhooks • transforms payload (keep the good bits)

• send payload to central service

• run build steps and services via Docker • sends updates upstream

account/project service• identifies build configuration

build orchestrator• build machine allocation and provisioning • handles logs • starts build and sends config to build

machines

SQS queue

Page 49: Building Efficient Parallel Testing Platforms with Docker

Compute Instance

build processor

Step

cont

aine

r

cont

aine

r

cont

aine

r

Step

cont

aine

r

cont

aine

r

cont

aine

r

Stepco

ntai

ner

cont

aine

r

cont

aine

r

Page 50: Building Efficient Parallel Testing Platforms with Docker

Compute Instance

build processor

Step

cont

aine

r

cont

aine

r

cont

aine

r

Step

cont

aine

r

cont

aine

r

cont

aine

r

Stepco

ntai

ner

cont

aine

r

cont

aine

r

Page 51: Building Efficient Parallel Testing Platforms with Docker

Docker Workflow Tools

• Docker Compose: service and step definition syntax • Docker Registry: storage for images; previously used

for remote caching • Docker for Mac and Windows: give users ability to

reproduce CI environments locally

Page 52: Building Efficient Parallel Testing Platforms with Docker

services.ymldb: image: postgres:9.5

app: encrypted_dockercfg_path: dockercfg.encrypted build: image: user/some-image dockerfile: Dockerfile.test cached: true links: - db

deploy: encrypted_dockercfg_path: dockercfg.encrypted build: dockerfile: Dockerfile.deploy

Page 53: Building Efficient Parallel Testing Platforms with Docker

- type: serial steps: - type: parallel steps: - name: rspec service: app command: bin/ci spec - name: rubocop service: app command: rubocop - name: haml-lint service: app command: haml-lint app/views - name: rails_best_practices service: app command: bin/railsbp - service: deploy type: push image_name: rheinwein/notes-app tag: ^master$ registry: https://index.docker.io/v1/ encrypted_dockercfg_path: dockercfg.encrypted

1

2

steps.yml

Page 54: Building Efficient Parallel Testing Platforms with Docker

Docker for Mac and Windows

• All users can test locally • Jet CLI is available at bit.ly/codeship-jet-tool • Free, and you don’t need a Codeship account • Big advantage over the LXC implementation

Page 55: Building Efficient Parallel Testing Platforms with Docker

codeship.com/resources

Your push or deploy step should never be part of a parallel step group

PRO TIP

Page 56: Building Efficient Parallel Testing Platforms with Docker

Technical Difficulties

Page 57: Building Efficient Parallel Testing Platforms with Docker

Infrastructure

• Build allocation • Customers can choose specs for their build machines • Machine provisioning used to be part of the build process • Now we pool build machines • Allocation time is ~1 second!

Page 58: Building Efficient Parallel Testing Platforms with Docker

Performance

• Image Caching • Old way: rely on the registry for caching • A pull gave us access to each parent layer; rebuilding the image

used the local cache • 1.10 content addressable breaking change

Page 59: Building Efficient Parallel Testing Platforms with Docker

Performance

• Image Caching • Great news: 1.11 restored parent/child relationship when you

save the images via docker save • 1.13 will include --cache-from flag

• Double-edged sword of relying on external tools ¯\_( )_/¯

Page 60: Building Efficient Parallel Testing Platforms with Docker

What’s Missing?

Page 61: Building Efficient Parallel Testing Platforms with Docker

libcompose

• Currently use APIs directly for container-level operations (Jet was also born before Fig was popular)

• Minimal change for our users and builds, but much easier for our engineers

• Work is underway 🐳

Page 62: Building Efficient Parallel Testing Platforms with Docker

Compose V2 syntax

• Will come with libcompose

Page 63: Building Efficient Parallel Testing Platforms with Docker

Swarm!

• Jet was born pre-Swarm • We manage build machines on AWS via our

own service • Previous concerns about security — single tenancy • Swarm (and services like Carina) are

promising for the future

Page 64: Building Efficient Parallel Testing Platforms with Docker

Swarm!

• Instead of using a single machine per build, we should schedule containers across a cluster

• Use the best parts of the LXC platform, but with Docker behind it

Page 65: Building Efficient Parallel Testing Platforms with Docker

codeship.com/resources

You can create a highly efficient parallel testing platform with LXC

alone, but using Docker tools makes it more flexible

TL;DR

Page 66: Building Efficient Parallel Testing Platforms with Docker

Wednesday — October 5th How Secure is your Container? A Docker Engine Security Update - Phil Estes Docker Orchestration: Beyond the Basics - Aaron Lehmann When the Going gets Tough, get TUF Going - Riyaz Faizullabhoy and Lily Guo

Thursday — October 6th Orchestrating Linux Containers while Tolerating Failures - Drew Erny Unikernels: When you Should and When you Shouldn’t - Amir Chaudhry Berlin Docker Meetup

Page 67: Building Efficient Parallel Testing Platforms with Docker

thanks!