第1页
Enabling Microservices @Orbitz
Steve Hoffman @bacoboy Rick Fast @tortiepoint Senior Principal Engineers
第5页
Agenda
• Brief Architecture Overview/History • From Monolithic to Services to Microservices
with Docker • Automated Pipelines • Questions
第6页
2000
#dockercon
第7页
2000
#dockercon
Yes, we are STILL hiring!
@OrbitzTalent
第8页
2000
#dockercon
Web Layer Business Layer
第9页
2000
#dockercon
第10页
2000
#dockercon
第11页
2000
#dockercon
Business Layer
第12页
20030
#dockercon
Business Layer
第13页
2003
#dockercon
Business Layer
第14页
2003
#dockercon
Business Layer
第15页
20034
#dockercon
第16页
2004
#dockercon
第17页
201024
#dockercon
第18页
20125
• Multiple Brands • Websites • Webservices
• Multiple Backends • 500+ apps / thousands of instances • Deployments Daily (sometimes more)
#dockercon
第19页
Process Overkill
#dockercon
第20页
Different Provisioning Tools
DEV OPS Application != Platform
#dockercon
第21页
A New Experiment
• Microservices? • Decompose single “service” into the actual 40+ sub-services
- Any change to sub-service was a deployment of many
• Could it be a simple Spring Boot App in Docker (12 factor?) • Backward compatible with existing service infrastructure. • Code to Production w/o help from other Humans
#dockercon
第22页
The Docker Slave aka “The Rickbot”
App App App
#dockercon
第23页
10.10.10.10
10.10.10.10:31002
App App App
Register & Lookup
#dockercon
第24页
App App App
#dockercon
第25页
App App App
#dockercon
第26页
#dockercon
第27页
#dockercon
第28页
http://consul.io
#dockercon
第29页
10.10.10.10
10.10.10.10:51515
App App App
#dockercon
第30页
10.10.10.10
10.10.10.10:1337
App App App
#dockercon
第31页
Almost done…
#dockercon
App App App
第32页
#dockercon
App App App
第33页
VIP
https://github.com/QubitProducts/bamboo
App App App
#dockercon
第34页
App App App
#dockercon
第35页
App App App
#dockercon
第36页
#dockercon
App App App
第37页
A Little More Background
第38页
#dockercon
第39页
Module
Module Module
#dockercon
Module
第40页
Editorial Module
• A Continuously Deployed Microservice • www.orbitz.com
- (scroll down)
#dockercon
第41页
Orbitz
Content Orchestration
Service
Hotel Module
Search Module
Editorial Module
Content (Solr)
#dockercon
第42页
Hotel Team
Search Team
Content Team
Orbitz
Content Orchestration
Service
Hotel Module
Search Module
Editorial Module
Content (Solr)
#dockercon
第43页
Orbitz
Content Orchestration
Service
Hotel Module
Search Module
Editorial Module
Content (Solr)
#dockercon
第44页
Orbitz
#dockercon
Hotel Team
Content Orchestration
Service
Hotel Module
Search Module
Editorial Module
Search Team
Content (Solr)
Content Team
第45页
Pre-Continuous Delivery
1.2-BETA-20150401-113002
Build
Test
1.2-BETA-20150402-093002
Build
Test
And so on…
Discard Discard
#dockercon
第46页
Pre-Continuous Delivery
1.2-BETA-20150401-113002
Build
1.2-BETA-20150402-093002
Build
1.2
Build
Test Test Test
#dockercon
Discard Discard Deploy
第47页
Continuous Delivery with Jenkins, Docker, and Ansible (And then Marathon)
第48页
Yo
rfast-mbp:git rfast$ yo microservice
_-----_
| | .--------------------------.
|--(o)--| | Welcome to the kickass |
`---------´ |
Microservice
|
( _´U`_ ) |
generator!
|
/___A___\ '--------------------------'
|~|
__'.___.'__
´ ` |° ´ Y `
? Enter the name of your service. (E.G. "my-service")
#dockercon
第49页
Pull Request
Committer
#dockercon
第50页
Pull Request
Reviewer
Committer
#dockercon
第51页
Pull Request
Reviewer
Committer
#dockercon
第52页
Pull Request
Reviewer
Committer
#dockercon
第53页
Jenkins Pipeline
第54页
if(…) { x ++;
}
Merge
#dockercon
第55页
Pipeline (Simplified)
build unit test publish deploy staging
deploy dev
acceptance tests
deploy qa
open RFC
deploy prod
close RFC
#dockercon
第56页
Build
Merge
if(…) { x ++;
}
1.2
#dockercon
第57页
Build
Merge
if(…) { x ++;
}
1.2
editorial-module.jar
1.2.{BUILD_NUMBER}
./gradlew build
#dockercon
第58页
Build
Merge
if(…) { x ++;
}
1.2
editorial-module.jar
1.2.17
#dockercon
第59页
Build
Merge
if(…) { x ++;
}
1.2
editorial-module.jar
FROM orbitz/java-8 ADD build/editorial-module.jar /opt/orbitz CWD /opt/orbitz CMD java -jar editorial-module.jar
1.2.17
#dockercon
第60页
Build
Merge
if(…) { x ++;
}
1.2
editorial-module.jar orbitz/editorial-module:1.2.17
1.2.17
#dockercon
第61页
Build
orbitz/editorial-module:1.2.17
#dockercon
第62页
Deploy
git pull
#dockercon
- hosts: dev - tasks:
- name: find previous images docker_facts: image=orbitz/{{application}} register: previous
- name: deploy new image docker: image=orbitz/{{application}}:{{version}} …
- name: wait for service wait_for: port={{port}} …
- name: check health endpoint uri: url="http://{{fqdn}}:{{port}}/health" …
- name: kill old image docker: {{previous}}
playbook.yml (abridged)
第63页
- hosts: dev
host-001 host-002 host-003 host-004 host-005
#dockercon
第64页
Deploy
#dockercon
1.2.16
host-001
第65页
Deploy
#dockercon
1.2.16 1.2.17
host-001
第66页
Deploy
1.2.16 1.2.17
host-001
#dockercon
DATABASE_URL=jdbc://whatever/db/stuff CONSUL_HOST={{ansible_fqdn}} LOGSTASH_HOST={{ansible_fqdn}} GRAPHITE_HOST={{ansible_fqdn}}
第67页
Deploy
#dockercon
1.2.16 1.2.17
host-001
/health
第68页
Deploy
#dockercon
1.2.16 1.2.17
host-001
/health 200 OK
第69页
Deploy
#dockercon
1.2.16 1.2.17
host-001
第70页
Deploy
#dockercon
1.2.17
host-001
第71页
Deploy
1.2.17
#dockercon
host-001
1.2.16
host-002 And so on…
第72页
#dockercon
What’s next?
第73页
How to handle failure?
#dockercon
第74页
What happens when a VM is moved?
#dockercon
第75页
What if I need to add capacity?
#dockercon
第76页
Deploy (Second Attempt)
git pull
#dockercon
- hosts: dev - tasks:
- name: find previous images docker_facts: image=orbitz/{{application}} register: previous
- name: deploy new image docker: image=orbitz/{{application}}:{{version}} …
- name: wait for service wait_for: port={{port}} …
- name: check health endpoint uri: url="http://{{fqdn}}:{{port}}/health" …
- name: kill old image docker: {{previous}}
playbook.yml (abridged)
第77页
Deploy (Second Attempt)
- hosts: dev - tasks:
- name: find previous images docker_facts: image=orbitz/{{application}} register: previous
- name: deploy new image docker: image=orbitz/{{application}}:{{version}} …
- name: wait for service wait_for: port={{port}} …
- name: check health endpoint uri: url="http://{{fqdn}}:{{port}}/health" …
- name: kill old image
git pull
- hosts: localhost - tasks:
- name: marathon deploy marathon: image=orbitz/{{application}}:{{version}} instances=3
#dockercon
playbook.yml (abridged)
第78页
Deploy (Second Attempt)
#dockercon
New host setup
第79页
Deploy (Second Attempt)
Mesos Agent
#dockercon
1.2.16
New host setup
第80页
Deploy (Second Attempt)
- tasks: marathon: … playbook.yml
#dockercon
1.2.16
1.2.16
1.2.16
第81页
Deploy (Second Attempt)
- tasks: marathon: …
#dockercon
1.2.16
1.2.16
1.2.16
第82页
Deploy (Second Attempt)
- tasks: marathon: …
1.2.16
1.2.16
PUT /apps/editorial-module {
“image”: “orbitz/editorial-module:1.2.17” … }
#dockercon
1.2.16
第83页
Deploy (Second Attempt)
app = GET /v2/apps/editorial-module
- tasks: marathon: …
if not app then deploy_id = POST /v2/apps { “image”: “orbitz/editoria1.2l.1-6module:1.2.17”, “id”: “editorial-module” }
else deploy_id = PUT /v2/apps/editorial-module { “image”: “orbitz/editorial-module:1.2.17” }
end if
while GET /v2/deployments contains deploy_id
// still deploying
PUT /apps/editorial-emnod dule
{ // deploy complete
1.2.16
“image”: “orbitz/editorial-module:1.2.17” …
}
#dockercon
1.2.16
第84页
Deploy (Second Attempt)
- tasks: marathon: …
1.2.16
1.2.16
PUT /apps/editorial-module {
“image”: “orbitz/editorial-module:1.2.17” … }
#dockercon
1.2.16
第85页
Deploy (Second Attempt)
- tasks: marathon: …
#dockercon
1.2.16
1.2.16
1.2.16
第86页
Deploy (Second Attempt)
- tasks: marathon: …
#dockercon
1.2.16 1.2.17
1.2.16 1.2.17
1.2.16 1.2.17
第87页
Deploy (Second Attempt)
- tasks: marathon: …
/health
#dockercon
1.2.16 1.2.17
1.2.16 1.2.17
1.2.16 1.2.17
第88页
Deploy (Second Attempt)
- tasks: marathon: …
/health
#dockercon
1.2.16 1.2.17
200 OK
1.2.16 1.2.17
200 OK
1.2.16 1.2.17
200 OK
第89页
- tasks: marathon: …
#dockercon
1.2.17
1.2.17
1.2.17
第90页
1.2.17
1.2.17
And off to the next environment…
#dockercon
1.2.17
第91页
1.2.17
1.2.17
#dockercon
What if?
1.2.17
第92页
#dockercon
1.2.17
1.2.17
第93页
#dockercon
1.2.17
1.2.17
第94页
#dockercon
1.2.17
1.2.17
1.2.17
第95页
#dockercon
1.2.17
200 OK1.2.17
1.2.17
/health
第96页
#dockercon
1.2.17
1.2.17
1.2.17
第97页
Smoke/Acceptance Testing
#dockercon
1.2.17 1.2.17 1.2.17
第98页
Paper Trail
#dockercon
tickets commit(s)
create
第99页
Paper Trail
#dockercon
fail! close/fail
第100页
Paper Trail
#dockercon
ok close
第101页
Code
Review & Push
Build Unit Test
Deploy Dev
Acceptance Test
Pre-Production Production
Deploy Prod Close RFC
Deploy Staging
Open RFC
第102页
What’s inside the containers?
• Spring Boot
• Dropwizard Metrics (formerly Coda Hale, Yammer)
• Consul Registration/Discovery
• Logstash + Logback
OrbitzWorldwide/consul-client
• Swagger
• Hystrix
• Retrofit + Consul
#dockercon
第103页
“Why didn’t you use {{.x}}?”
–You
#dockercon
第104页
Keeping an eye on…
#dockercon
Kubernetes
Amazon Elastic Container
Service
Docker Swarm
第105页
Summary
• Create a shared platform for docker deployments using shared and app-specific “localhost” helpers — this was ours, yours SHOULD look different — adapt to change, don’t fight it.
• Take people out of the release process
- Docker - repeatable applications - Chef - repeatable infrastructure — Environment aware - Jenkins - repeatable releases
• Delineate configuration concerns:
- Known at Compile time — Bake into Docker image - Known at Boot time — Bake into Playbook/Launcher - parameter to Docker run - Changes Anytime — Externalize (consul K/V, etcd, zookeeper)
#dockercon
第106页
Thanks!
Steve Hoffman @bacoboy
Rick Fast @tortiepoint