Cutting through the fog of cloud

Post on 26-Jan-2015

110 views 2 download

description

In this presentation, I am going to briefly talk about 'what cloud is' and highlight the various types of cloud (IaaS, PaaS, SaaS). The bulk of the talk will be about using the fog gem using IaaS. I will discuss fog concepts (collections, models, requests, services, providers) and supporting these with actual examples using fog

Transcript of Cutting through the fog of cloud

Cutting Through The Fog Of Cloud

Kyle RamesDeveloper Advocate@krames

Agenda

• Cloud 101

• Working in the Clouds

What is Cloud?

Software as a Service SaaS

Platform as a Service PaaS

Infrastructure as a Service IaaS

Types of Cloud

SaaS

PaaS

IaaS

When I say Cloud,you think...

When I say Cloud,you think...

Agenda

• Cloud 101

• Working in the Clouds

source: https://www.ruby-toolbox.com/projects/fog

Fog Providers>>  Fog.providers.keys

=>  [:atmos,  :aws,  :baremetalcloud,  :bluebox,:brightbox,  :clodo,  :cloudsigma,  :cloudstack,  :digitalocean,  :dnsimple,  :dnsmadeeasy,  :dreamhost,  :dynect,  :ecloud,  :glesys,  :gogrid,  :google,  :hp,  :ibm,  :internetarchive,  :joyent,  :libvirt,  :linode,  :local,  :ninefold,  :openstack,  :openvz,  :ovirt,  :rackspace,  :riakcs,  :serverlove,  :stormondemand,  :vcloud,  :vmfusion,  :voxel,  :vsphere,  :xenserver,  :zerigo]  

Rackspace Services>>  Fog.services.select  {|k,v|          v.include?(:rackspace)      }.keys

=>  [:storage,  :cdn,  :compute,  :dns,  :block_storage,  :compute_v2,  :load_balancers,  :identity,  :databases]

Load Balancer

VMVM

DNSbespin-mining.com

VMVM

Create Compute Service>>  service  =  Fog::Compute.new  {                              :provider  =>  'rackspace',                              :version  =>  :v2,                            :rackspace_username  =>  USERNAME,                            :rackspace_api_key  =>  API_KEY,                            :rackspace_region  =>  :ord

Required Server Parameters

Get List of Images>>  images  =  service.images

=>  <Fog::Compute::RackspaceV2::Images  [            <Fog::Compute::RackspaceV2::Image                id="ccaf99bc-­‐472a-­‐46ea-­‐a125-­‐d3ecfca66695",                name="FreeBSD  9.1",                ...>,            <Fog::Compute::RackspaceV2::Image                id="16e6c0ae-­‐f881-­‐4180-­‐95b0-­‐3450fe3f8e96",                name="Red  Hat  Enterprise  Linux  6.4",                ...>,          ...        ]>

Get Ubuntu Image>>  image  =  images.find  do  |img|            img.name  =~  /Ubuntu/      end  =>  <Fog::Compute::RackspaceV2::Image        id="23cebbc9-­‐3219-­‐4a27-­‐9210-­‐d63e1af7181b",        name="Ubuntu  13.04  (Raring  Ringtail)",        ...      >  

TK-421

Create Server>>  tk_421  =  service.servers.create  {                                                      :image_id  =>  image.id,                                                        :flavor_id  =>  flavor.id,                                                        :name  =>  'TK-­‐421'}

=>  <Fog::Compute::RackspaceV2::Server        id="308e5fd5-­‐ff50-­‐42bd-­‐911c-­‐b91a9180673d",        name="TK-­‐421",        created=nil,        updated=nil,        host_id=nil,        state=nil,        progress=nil,        ...>

Update Server Object>>  tk_421.reload

=>  <Fog::Compute::RackspaceV2::Server        id="308e5fd5-­‐ff50-­‐42bd-­‐911c-­‐b91a9180673d",        name="TK-­‐421",        created="2013-­‐07-­‐03T18:08:40Z",        updated="2013-­‐07-­‐03T18:08:43Z",        host_id="",        state="BUILD",        progress=0,      ...>

Server Attributes>>  tk_421.attributes

=>  {:image_id=>"23cebbc9-­‐3219-­‐4a27-­‐9210-­‐d63e1af7181b",  :flavor_id=>"2",  :name=>"TK-­‐421",  :disk_config=>"AUTO",  :id=>"308e5fd5-­‐ff50-­‐42bd-­‐911c-­‐b91a9180673d"  :state=>"BUILD",  :progress=>0,  ...}

Fog Meta Magic>>  tk_421.state=>  "BUILD"  

>>  tk_421.progress=>  0  

Is it ready?>>  tk_421.reload

>>  tk_421.state=>  "BUILD"    

>>  tk_421.progress=>  17  

Waiting for TK-421>>  tk_421.wait_for  {  ready?  }

=>  {:duration=>197.0}  

Login>>  tk_421.username=>  “root”

>>  tk_421.password=>  “r3b3lz-­‐st1nk42”

Bootstrap

1. Creates server

2. Waits for server to finish building

3. Create ROOT_USER/.ssh/authorized_keys

4. Lock password for root user

5. Create ROOT_USER/attributes.json file

6. Create ROOT_USER/metadata.json file

Bootstrap>>  tk_422  =  service.servers.bootstrap  {              :image_id  =>  image.id,                :flavor_id  =>  flavor.id,                :name  =>  'TK-­‐422',            :public_key_path  =>  '~/.ssh/fog_rsa.pub',              :private_key_path  =>  '~/.ssh/fog_rsa'      }

SCP / SSH>>  tk_422.scp  'setup.sh',  '/root/setup.sh'

>>  results  =  tk_422.ssh  ‘sh  /root/setup.sh’

>>  results.first.stdout=>  "Setting  up  VM\r\n"  

We have only scratched the surface!

Remember?

service.images

Collection

Array

Fog::Collection

Fog::Compute::RackspaceV2::Images

Collection Methodsall fetch every object of that type from the

provider.

get fetch a single object by its identity from the provider.

create initialize a new record locally and a remote resource with the provider.

new initialize a new record locally, but do not create a remote resource with the provider.

Collections

>>  service.collections

[:servers,  :flavors,  :images,  :attachments,  :networks]

Model

Fog::Model

Fog::Compute::RackspaceV2:Image

Model Methodsattributes Returns a hash containing the list of model

attributes and values.

save Saves object. (not all object support update)

reload Updates object with latest state from service.

ready? Returns true if object is in a ready state and able to perform actions.

wait_for Periodically reloads model yielding to block.

Model Layer

VMVM

Load Balancer

VMVM

Create Load Balancer Service

>>  lb_service  =          Fog::Rackspace::LoadBalancers.new  {                      :rackspace_username  =>  USERNAME,                    :rackspace_api_key  =>  API_KEY,                    :rackspace_region  =>  :ord            }

Load Balancer Collections

>>  lb_service.collections

=>  [:load_balancers,  :nodes,  :virtual_ips,          :access_rules]  

Creating a Load Balancer

lb  =  lb_service.load_balancers.

Creating a Load Balancer

lb  =  lb_service.load_balancers.create      :name  =>  'bob-­‐the-­‐balancer',    :protocol  =>  'HTTP',      :port  =>  80,      :virtual_ips  =>  [{:type  =>  'PUBLIC'}],      :nodes  =>  [{                            :address  =>  tk_421.ipv4_address,                              :port  =>  80,                              :condition  =>  'ENABLED'                        }]

Add Additional Nodelb.nodes.

Add Additional Nodelb.nodes.create  {:address  =>  tk_422.ipv4_address,      :port  =>  80,      :condition  =>  'ENABLED'}

IP Address>>  vip  =  lb.virtual_ips.find  do  |ip|                      ip.ip_version  ==  "IPV4"                  end

>>  vip.address=>  "166.78.41.240"  

Continuous Deployment[tk_602,  tk_603].each  do  |server|      lb.nodes.create(:address  =>  server.ipv4_address,          :port  =>  80,          :condition  =>  'ENABLED')end

existing_nodes.each  do  |node|      node.condition  =  'DRAINING'    node.saveend

Request Layer

Request Layer

• Mirrors REST interface

• Most efficient way to access cloud

• Not portable between providers

• Preference model layer!

Requests>>  service.requests

[:copy_object,  :delete_container,  :delete_object,  :get_container,  :get_containers,  :get_object,

...]

Load Balancer

VMVM

Load Balancer

VMVM

DNSbespin-mining.com

Create DNS Service>>  service  =  Fog::DNS.new  {                              :provider    =>  'rackspace',                                :rackspace_username  =>  USERNAME,                              :rackspace_api_key    =>  API_KEY                          }

DNS Requests>>  dns_service.requests

=>  [:callback,  :list_domains,  :list_domain_details,  :modify_domain,  :create_domains,  :remove_domain,  :remove_domains,  :list_subdomains,  :list_records,  :list_record_details,  :modify_record,  :remove_record,  :remove_records,  :add_records]  

List Domains>>  r  =  service.list_domains

#<Excon::Response:0x007fdf1ea0f7d0  @data={:body=>{"domains"=>[{"name"=>"bespin-­‐mining.com",  "id"=>3753036,  "accountId"=>772045,  "emailAddress"=>"darth@empire.com",  "updated"=>"2013-­‐06-­‐17T15:52:29.000+0000",  "created"=>"2013-­‐06-­‐17T15:52:29.000+0000"},..]}}  @headers={"Content-­‐Type"=>"application/json",  "Via"=>"1.1  Repose  (Repose/2.6.11)",  "x-­‐api-­‐version"=>"1.0.25",  "Content-­‐Length"=>"1509",  "Date"=>"Fri,  05  Jul  2013  18:43:12  GMT",  "Server"=>"Jetty(8.0.y.z-­‐SNAPSHOT)"},  @status=200,  @remote_ip="50.56.3.32">  

List Domains>>  r  =  service.list_domains

#<Excon::Response:0x007fdf1ea0f7d0  @data={:body=>{"domains"=>[{"name"=>"bespin-­‐mining.com",  "id"=>3753036,  "accountId"=>772045,  "emailAddress"=>"darth@empire.com",  "updated"=>"2013-­‐06-­‐17T15:52:29.000+0000",  "created"=>"2013-­‐06-­‐17T15:52:29.000+0000"},..]}}  @headers={"Content-­‐Type"=>"application/json",  "Via"=>"1.1  Repose  (Repose/2.6.11)",  "x-­‐api-­‐version"=>"1.0.25",  "Content-­‐Length"=>"1509",  "Date"=>"Fri,  05  Jul  2013  18:43:12  GMT",  "Server"=>"Jetty(8.0.y.z-­‐SNAPSHOT)"},  @status=200,  @remote_ip="50.56.3.32">  

List Domains>>  r  =  service.list_domains

#<Excon::Response:0x007fdf1ea0f7d0  @data={:body=>{"domains"=>[{"name"=>"bespin-­‐mining.com",  "id"=>3753036,  "accountId"=>772045,  "emailAddress"=>"darth@empire.com",  "updated"=>"2013-­‐06-­‐17T15:52:29.000+0000",  "created"=>"2013-­‐06-­‐17T15:52:29.000+0000"},..]}}  @headers={"Content-­‐Type"=>"application/json",  "Via"=>"1.1  Repose  (Repose/2.6.11)",  "x-­‐api-­‐version"=>"1.0.25",  "Content-­‐Length"=>"1509",  "Date"=>"Fri,  05  Jul  2013  18:43:12  GMT",  "Server"=>"Jetty(8.0.y.z-­‐SNAPSHOT)"},  @status=200,  @remote_ip="50.56.3.32">  

List Domains>>  r  =  service.list_domains

#<Excon::Response:0x007fdf1ea0f7d0  @data={:body=>{"domains"=>[{"name"=>"bespin-­‐mining.com",  "id"=>3753036,  "accountId"=>772045,  "emailAddress"=>"darth@empire.com",  "updated"=>"2013-­‐06-­‐17T15:52:29.000+0000",  "created"=>"2013-­‐06-­‐17T15:52:29.000+0000"},..]}}  @headers={"Content-­‐Type"=>"application/json",  "Via"=>"1.1  Repose  (Repose/2.6.11)",  "x-­‐api-­‐version"=>"1.0.25",  "Content-­‐Length"=>"1509",  "Date"=>"Fri,  05  Jul  2013  18:43:12  GMT",  "Server"=>"Jetty(8.0.y.z-­‐SNAPSHOT)"},  @status=200,  @remote_ip="50.56.3.32">  

Excon::Response>>  domain  =  r.body["domains"].find  do  |h|      h["name"]  ==  "bespin-­‐mining.com"end

=>  {"name"=>"bespin-­‐mining.com",  "id"=>3753036,  "accountId"=>772045,  "emailAddress"=>"darth@empire.com",  "updated"=>"2013-­‐07-­‐05T19:07:42.000+0000",  "created"=>"2013-­‐06-­‐17T15:52:29.000+0000"}  

>>  r.status=>      200

Adding A Record>>  vip  =  lb.virtual_ips.find  {|ip|                      ip.ip_version  ==  "IPV4"                  }

>>  service.add_records  domain[“id”],  [{  :name  =>  'bespin-­‐mining.com',    :type  =>  'A',    :data  =>  vip.address,    :ttl  =>  600}]

Load Balancer

VMVM

DNSbespin-mining.com

Fog deep dive

Retrieve Image

service.images.get  "23cebbc9-­‐3219-­‐4a27-­‐9210-­‐d63e1af7181b"

module  Fog    module  Compute        class  RackspaceV2

           class  Images  <  Fog::Collection

def  get(image_id)                    data  =  service.get_image(image_id).body['image']                    new(data)                rescue  Fog::Compute::RackspaceV2::NotFound                    nil                end

           end

       end    endend

module  Fog    module  Compute        class  RackspaceV2

           class  Images  <  Fog::Collection

def  get(image_id)                    data  =  service.get_image(image_id).body['image']                    new(data)                rescue  Fog::Compute::RackspaceV2::NotFound                    nil                end

           end

       end    endend

module  Fog    module  Compute        class  RackspaceV2

           class  Real              def  get_image(image_id)                  request(                    :expects  =>  [200,  203],                    :method  =>  'GET',                    :path  =>  "images/#{image_id}"                  )                end

       end    endend

module  Fog    module  Compute        class  RackspaceV2

           class  Real              def  get_image(image_id)                  request(                    :expects  =>  [200,  203],                    :method  =>  'GET',                    :path  =>  "images/#{image_id}"                  )                end

       end    endend

module  Fog    module  Compute        class  RackspaceV2

           class  Real              def  get_image(image_id)                  request(                    :expects  =>  [200,  203],                    :method  =>  'GET',                    :path  =>  "images/#{image_id}"                  )                end

       end    endend

module  Fog    module  Compute        class  RackspaceV2

           class  Real              def  get_image(image_id)                  request(                    :expects  =>  [200,  203],                    :method  =>  'GET',                    :path  =>  "images/#{image_id}"                  )                end

       end    endend

GET https://ord.servers.api.rackspacecloud.com:443/v2/5555/images/23cebbc9-3219-4a27-9210-d63e1af7181b HTTP/1.1Content-Type: application/jsonAccept: application/jsonX-Auth-Token: abc41dc54e594e9c8fb73b89b1b79142Host: ord.servers.api.rackspacecloud.com:443

GET https://ord.servers.api.rackspacecloud.com:443/v2/5555/images/23cebbc9-3219-4a27-9210-d63e1af7181b HTTP/1.1Content-Type: application/jsonAccept: application/jsonX-Auth-Token: abc41dc54e594e9c8fb73b89b1b79142Host: ord.servers.api.rackspacecloud.com:443

GET https://ord.servers.api.rackspacecloud.com:443/v2/5555/images/23cebbc9-3219-4a27-9210-d63e1af7181b HTTP/1.1Content-Type: application/jsonAccept: application/jsonX-Auth-Token: abc41dc54e594e9c8fb73b89b1b79142Host: ord.servers.api.rackspacecloud.com:443

GET https://ord.servers.api.rackspacecloud.com:443/v2/5555/images/23cebbc9-3219-4a27-9210-d63e1af7181b HTTP/1.1Content-Type: application/jsonAccept: application/jsonX-Auth-Token: abc41dc54e594e9c8fb73b89b1b79142Host: ord.servers.api.rackspacecloud.com:443

GET https://ord.servers.api.rackspacecloud.com:443/v2/5555/images/23cebbc9-3219-4a27-9210-d63e1af7181b HTTP/1.1Content-Type: application/jsonAccept: application/jsonX-Auth-Token: abc41dc54e594e9c8fb73b89b1b79142Host: ord.servers.api.rackspacecloud.com:443

GET https://ord.servers.api.rackspacecloud.com:443/v2/5555/images/23cebbc9-3219-4a27-9210-d63e1af7181b HTTP/1.1Content-Type: application/jsonAccept: application/jsonX-Auth-Token: abc41dc54e594e9c8fb73b89b1b79142Host: ord.servers.api.rackspacecloud.com:443

EXCON_DEBUG=true

Fog.mock!

Testing

RACKSPACE® HOSTING | WWW.RACKSPACE.COM

http://developer.rackspace.com/#rubysdk-support@rackspace.com

@krames

Questions?

Imagestule fog, marya, CC BY-SA 2.0

Clouds, Daniel Boyd, CC BY 2.0

Metroid II: Return of Samus, Michel Ngilen, CC BY-SA 2.0

Lego Mindstorms Kit, Marlon J. Manrique, CC BY 2.0

CD, Visual Pharm, CC BY-SA 2.0

Public Bikes, Richard Masoner / Cyclelicious, CC BY 2.0

PRIVATE, Rupert Ganzer, CC BY 2.0

Hybrid

Sorry We Are Not Open, Alan Levine, CC BY 2.0

We are, e1ther, CC BY 2.0