Functional Hostnames and Why they are Bad

Puppet
PuppetPuppet
Puppet Camp
 April 9th 2013
What’s in a name?

Andrew Fong and Gary Josack
     fong@dropbox.com
     gary@dropbox.com
About Dropbox

•  Thousands of instances/servers
•  Mostly Python Stack
•  EC2 and Large Self Datacenters
•  Over a billion file syncs per day
•  Thousands of MySQL Shards
•  4 SREs and 1 DBA
A story of a startup...




 Hostapuppet.com
Chapter One


•  1 or 2 teams

•  Couple of hosts

•  Webserver and a database

•  Maybe one ops guy
What Ops People Like


•  Simplicity

•  Repeatability

•  Assurances that things remain consistent

•  Puppet / Configuration management
Config Management

node 'www1.example.com' {
    include common
    include apache
    include squid
  }
node 'db1.example.com' {
    include common
    include mysql
  }
My First Puppet Config

Node ‘mickey.hostapuppet.com’ {
      include common
      include webserver
      include sudoers
}
Node ‘donald.hostapuppet.com’{
      include common
      include db
      include sudoers
}
Sudoers Module

…
file { "/etc/sudoers":
           owner => root,
           group => root,
           mode => "440",
           source => "puppet:///modules/sudo/sudoers",
  }
…
Sudoers File itself

Host_Alias DONALD=donald.hostapuppet.com
Host_Alias MICKEY=mickey.hostapuppet.com


db_guy DONALD=(all) NOPASSWD: ALL
ops_guy MICKEY=(all) NOPASSWD: ALL
Chapter Two: A growing service

•  A few teams
•  2 or 3 services
•  multiple types of hosts
  –  Web
  –  API
  –  DB
Hostnames


•  sjc-web[1-N]

•  sjc-db[1-N]

•  sjc-api[1-N]
Host Regex

$hosttype = inline_template('<%=
hostname.sub(/w+-([a-z]+)d*/){$1} %>’)
Hosttypes
   $hosttype = inline_template('<%= hostname.sub(/w+-([a-z]+)d*/){$1} %>’)



if $hosttype == ‘web’ {                  if $hosttype == ‘api’ {
        include sudoers                           include sudoers
        include web                               include api
                                         }
}

If $hosttype == ‘db’ {
        include sudoers
        include db
}
Back to sudoers

…
file { "/etc/sudoers":
           owner => root,
           group => root,
           mode => "440",
           source => "puppet:///modules/sudo/sudoers",
  }
…
Sudoers File itself

Host_Alias      WEB=sjc-web*
Host_Alias      DB=sjc-db*
Host_Alias      API=sjc-api*


database_guy DB=(all) NOPASSWD: ALL
ops_guy WEB=(all) NOPASSWD: ALL
api_team API=(all) NOPASSWD: ALL
Hypergrowth
           Users (millions)
120

100

 80

 60

 40

 20

  0
      0      2                  3   5
             Users (millions)
Chapter 3: An Expanding
            Infrastructure

•  Lots of new hires!

•  A bunch more developers

•  Some PMs

•  Some Designers
All Kinds Of Problems…

•  Boxes of same hardware class running
 different services

•  Boxes serving more than one role
 (remember sudoers?)

•  Deploying or moving hosts quickly
Renaming a host

•  Update dns

•  Update dhcpd.conf

•  Push both

•  Update puppet configs

•  Update code
OMG I JUST RENAME HOSTS!
Sudoers File From Chapter Two…

Host_Alias   WEB= sjc-web*
Host_Alias   API=sjc-api*
Host_Alias   DB=sjc-db*

database_guy DB=(all) NOPASSWD: ALL
ops_guy WEB=(all) NOPASSWD: ALL
api_team API(all) NOPASSWD: ALL
Sudoers File in Chapter 3

Host_Alias   WEB= sjc-web*
Host_Alias   API=sjc-api*,sjc-web550,sjc-
web551,sjc-web552,sjc-web553
Host_Alias   DB=sjc-db*

database_guy DB=(all) NOPASSWD: ALL
ops_guy WEB=(all) NOPASSWD: ALL
api_team API(all) NOPASSWD: ALL
Dropbox

•  We did all that.

•  We’re still paying the taxes for doing
  that.

•  But there is a light at the end of the
  tunnel…
ABSTRACT THE
    SERVICE
FROM THE HOST!
So what does that mean?


• Make hosts role agnostic


• Do not require invasive changes


• Simple interfaces
Making hosts role agnostic


• Positional


• Serial Numbers


• Anything that doesn't change
The Dropbox Plan

• Positional names

• Custom Machine Database

• External Node Classifier

• Transitioning Puppet configs

• Naming service(s) for convenient names
Service/Machine Management
             Database
• Universal Source of Truth

• Manage roles / attributes

• Generated configs
  - Gmond,   Nagios, etc
What exactly is the ENC

• External Node Classifier

• Inject variables (and other) from external
process

• YAML Output
Part 2: External Node Encoders
Sudoers++

• Move from monolithic to modular
• Includes! (Weird caveats)
• Just use ALL for Host_Lists
Sudoers at Dropbox
Part 3: Helper Functions
Sudoers with tags
Sudoers with tags
Provisioning

• Preload MDB, DNS, DHCPD, etc.
  - Set   it and forget it

• Have spares ready for any roles

• Assigning a role is one command

• No more renames!
Dynamic Naming w/ PowerDNS
Dynamic Naming w/ PowerDNS
Zookeeper

• ZKNS included with the Vitess project
• ZK is in use at various different companies
(YouTube, Twitter, AirBnB)
Q&A

 FAQ #1: Are you hiring?
λ 

   - Yes! Come talk to us. :)
1 of 41

More Related Content

What's hot(20)

Introduction to AnsibleIntroduction to Ansible
Introduction to Ansible
Knoldus Inc.24.1K views
Node.js - A Quick Tour IINode.js - A Quick Tour II
Node.js - A Quick Tour II
Felix Geisendörfer4.8K views
Mysqlnd uhMysqlnd uh
Mysqlnd uh
natmchugh654 views
Docker up and runningDocker up and running
Docker up and running
Victor S. Recio8.4K views
docker build with Ansibledocker build with Ansible
docker build with Ansible
Bas Meijer2.1K views
ChefChef
Chef
Will Sterling3.6K views
AnsibleAnsible
Ansible
Michal Haták442 views
Debugging and Testing ES SystemsDebugging and Testing ES Systems
Debugging and Testing ES Systems
Chris Birchall6.8K views
Ansible 101Ansible 101
Ansible 101
Gena Mykhailiuta1.4K views
Python Deployment with FabricPython Deployment with Fabric
Python Deployment with Fabric
andymccurdy34K views
Learning Puppet basic thing Learning Puppet basic thing
Learning Puppet basic thing
DaeHyung Lee1.2K views
Docker & CoreOS at Utah GophersDocker & CoreOS at Utah Gophers
Docker & CoreOS at Utah Gophers
Josh Braegger693 views
Ansible on aws - Pop-up Loft Tel AvivAnsible on aws - Pop-up Loft Tel Aviv
Ansible on aws - Pop-up Loft Tel Aviv
Amazon Web Services1.8K views
PDXPortland - Dockerize DjangoPDXPortland - Dockerize Django
PDXPortland - Dockerize Django
Hannes Hapke1.2K views

Similar to Functional Hostnames and Why they are Bad(20)

Automating Complex Setups with PuppetAutomating Complex Setups with Puppet
Automating Complex Setups with Puppet
Kris Buytaert1.2K views
Deploying to Ubuntu on LinodeDeploying to Ubuntu on Linode
Deploying to Ubuntu on Linode
WO Community1.5K views
20090514 Introducing Puppet To Sasag20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag
garrett honeycutt1.1K views
Introduction to NodeJS with LOLCatsIntroduction to NodeJS with LOLCats
Introduction to NodeJS with LOLCats
Derek Anderson1.2K views
#WeSpeakLinux Session#WeSpeakLinux Session
#WeSpeakLinux Session
Kellyn Pot'Vin-Gorman594 views
Chapter-11.pdfChapter-11.pdf
Chapter-11.pdf
AlphonsePja2 views
Puppet and Apache CloudStackPuppet and Apache CloudStack
Puppet and Apache CloudStack
Puppet4.2K views
Managing Infrastructure as CodeManaging Infrastructure as Code
Managing Infrastructure as Code
Allan Shone691 views
A tour of AnsibleA tour of Ansible
A tour of Ansible
DevOps Ltd.588 views
PuppetpresoPuppetpreso
Puppetpreso
ke4qqq439 views
IT Automation with AnsibleIT Automation with Ansible
IT Automation with Ansible
Rayed Alrashed15.7K views
Puppet and CloudStackPuppet and CloudStack
Puppet and CloudStack
ke4qqq545 views
Introduction to AnsibleIntroduction to Ansible
Introduction to Ansible
Michael Bahr4.8K views

Functional Hostnames and Why they are Bad

  • 1. Puppet Camp April 9th 2013
  • 2. What’s in a name? Andrew Fong and Gary Josack fong@dropbox.com gary@dropbox.com
  • 3. About Dropbox •  Thousands of instances/servers •  Mostly Python Stack •  EC2 and Large Self Datacenters •  Over a billion file syncs per day •  Thousands of MySQL Shards •  4 SREs and 1 DBA
  • 4. A story of a startup... Hostapuppet.com
  • 5. Chapter One •  1 or 2 teams •  Couple of hosts •  Webserver and a database •  Maybe one ops guy
  • 6. What Ops People Like •  Simplicity •  Repeatability •  Assurances that things remain consistent •  Puppet / Configuration management
  • 7. Config Management node 'www1.example.com' { include common include apache include squid } node 'db1.example.com' { include common include mysql }
  • 8. My First Puppet Config Node ‘mickey.hostapuppet.com’ { include common include webserver include sudoers } Node ‘donald.hostapuppet.com’{ include common include db include sudoers }
  • 9. Sudoers Module … file { "/etc/sudoers": owner => root, group => root, mode => "440", source => "puppet:///modules/sudo/sudoers", } …
  • 10. Sudoers File itself Host_Alias DONALD=donald.hostapuppet.com Host_Alias MICKEY=mickey.hostapuppet.com db_guy DONALD=(all) NOPASSWD: ALL ops_guy MICKEY=(all) NOPASSWD: ALL
  • 11. Chapter Two: A growing service •  A few teams •  2 or 3 services •  multiple types of hosts –  Web –  API –  DB
  • 13. Host Regex $hosttype = inline_template('<%= hostname.sub(/w+-([a-z]+)d*/){$1} %>’)
  • 14. Hosttypes $hosttype = inline_template('<%= hostname.sub(/w+-([a-z]+)d*/){$1} %>’) if $hosttype == ‘web’ { if $hosttype == ‘api’ { include sudoers include sudoers include web include api } } If $hosttype == ‘db’ { include sudoers include db }
  • 15. Back to sudoers … file { "/etc/sudoers": owner => root, group => root, mode => "440", source => "puppet:///modules/sudo/sudoers", } …
  • 16. Sudoers File itself Host_Alias WEB=sjc-web* Host_Alias DB=sjc-db* Host_Alias API=sjc-api* database_guy DB=(all) NOPASSWD: ALL ops_guy WEB=(all) NOPASSWD: ALL api_team API=(all) NOPASSWD: ALL
  • 17. Hypergrowth Users (millions) 120 100 80 60 40 20 0 0 2 3 5 Users (millions)
  • 18. Chapter 3: An Expanding Infrastructure •  Lots of new hires! •  A bunch more developers •  Some PMs •  Some Designers
  • 19. All Kinds Of Problems… •  Boxes of same hardware class running different services •  Boxes serving more than one role (remember sudoers?) •  Deploying or moving hosts quickly
  • 20. Renaming a host •  Update dns •  Update dhcpd.conf •  Push both •  Update puppet configs •  Update code
  • 21. OMG I JUST RENAME HOSTS!
  • 22. Sudoers File From Chapter Two… Host_Alias WEB= sjc-web* Host_Alias API=sjc-api* Host_Alias DB=sjc-db* database_guy DB=(all) NOPASSWD: ALL ops_guy WEB=(all) NOPASSWD: ALL api_team API(all) NOPASSWD: ALL
  • 23. Sudoers File in Chapter 3 Host_Alias WEB= sjc-web* Host_Alias API=sjc-api*,sjc-web550,sjc- web551,sjc-web552,sjc-web553 Host_Alias DB=sjc-db* database_guy DB=(all) NOPASSWD: ALL ops_guy WEB=(all) NOPASSWD: ALL api_team API(all) NOPASSWD: ALL
  • 24. Dropbox •  We did all that. •  We’re still paying the taxes for doing that. •  But there is a light at the end of the tunnel…
  • 25. ABSTRACT THE SERVICE FROM THE HOST!
  • 26. So what does that mean? • Make hosts role agnostic • Do not require invasive changes • Simple interfaces
  • 27. Making hosts role agnostic • Positional • Serial Numbers • Anything that doesn't change
  • 28. The Dropbox Plan • Positional names • Custom Machine Database • External Node Classifier • Transitioning Puppet configs • Naming service(s) for convenient names
  • 29. Service/Machine Management Database • Universal Source of Truth • Manage roles / attributes • Generated configs - Gmond, Nagios, etc
  • 30. What exactly is the ENC • External Node Classifier • Inject variables (and other) from external process • YAML Output
  • 31. Part 2: External Node Encoders
  • 32. Sudoers++ • Move from monolithic to modular • Includes! (Weird caveats) • Just use ALL for Host_Lists
  • 34. Part 3: Helper Functions
  • 37. Provisioning • Preload MDB, DNS, DHCPD, etc. - Set it and forget it • Have spares ready for any roles • Assigning a role is one command • No more renames!
  • 38. Dynamic Naming w/ PowerDNS
  • 39. Dynamic Naming w/ PowerDNS
  • 40. Zookeeper • ZKNS included with the Vitess project • ZK is in use at various different companies (YouTube, Twitter, AirBnB)
  • 41. Q&A FAQ #1: Are you hiring? λ  - Yes! Come talk to us. :)