Search This Blog

Thursday, March 29, 2012

Rackspace uses anycast network for its DNS servers


From the DNS FAQ on the Rackspace Knowladge site cloud_dns_faq we can read out that:

What type of DNS network does Rackspace use?


Rackspace leverages a globally distributed anycast network. Currently we have DNS servers located in Texas, Virginia, Chicago, Hong Kong, and London. Using anycast, we broadcast the IP addresses for ns.rackspace.com and ns2.rackspace.com from each location. All DNS queries will generally go to the geographically closest nameservers, giving you faster results no matter where your queries originate. Additionally, all of our DNS servers are monitored 24/7 and if an entire datacenter were to fail, or even if all of the DNS servers within a specific datacenter were to fail, the DNS queries will automatically start going to the next best location.



View Rackspace anycast DNS locations in a larger map

References
http://www.rackspace.com/knowledge_center/cloud_dns_faq


Wednesday, March 28, 2012

Network data analize for a scenario with two Cloud Server behind a Rackspace Cloud Load Balancer

In this post we are going to take a look at the Rackspace Cloud Load Balancer (CLB) again but this time we aim to analyze a scenario with persistence issues and 2 pool member. Particularly, we want to find out and understand how the session persistence works on CLB. The simple diagram bellow shows our small test cloud topology. We have 3 Cloud Servers (CS) (1 client + 2 pool members) and one load balancer (LB). Our LB is using Round Robin algorithm to distribute the load amount the pool members. The pool members are defined using the internal IP addresses: 10.177.132.15  and 10.177.133.12.



Test scenario #1 without session persistence
  1. The client sends 1st HTTP request to LB1.
  2. The LB1 sends the req to first pool member according to round robin state.
  3. The pool member replays with HTTP 200.
  4. LB1 sends the replay back to the client.
  5. The client sends 2th HTTP request to LB1.
  6. The LB1 sends the req to another pool member.
  7. The pool member replays with HTTP 200.
  8. LB1 sends the replay back to the client.
Because we don't have access to the LB1 we are going to collect concurrent tcpdumps from all CS. We are using the curl to simulate HTTP requests on the client.

# run on client
tcpdump -nn -s0 -i any -w /var/tmp/client.pcap  port 80

# run on server1
tcpdump -nn -s0 -i any -w /var/tmp/server-urado1.pcap  port 80

# run on server2
tcpdump -nn -s0 -i any -w /var/tmp/server-urado2.pcap  port 80

# run on client to simulate HTTP requests
curl -v http://31.222.175.142

The first dumps and data from the test can be seen and found bellow [1].

[root@crado1 tmp]# tshark  -n -r client.pcap
  1   0.000000 31.222.191.246 -> 31.222.175.142 TCP 60925 > 80 [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=25369178 TSER=0 WS=4
  2   0.000513 31.222.175.142 -> 31.222.191.246 TCP 80 > 60925 [SYN, ACK] Seq=0 Ack=1 Win=17896 Len=0 MSS=8960 TSV=1091232983 TSER=25369178 WS=9
  3   0.000541 31.222.191.246 -> 31.222.175.142 TCP 60925 > 80 [ACK] Seq=1 Ack=1 Win=5840 Len=0 TSV=25369178 TSER=1091232983
  4   0.000609 31.222.191.246 -> 31.222.175.142 HTTP GET / HTTP/1.1
  5   0.000841 31.222.175.142 -> 31.222.191.246 TCP 80 > 60925 [ACK] Seq=1 Ack=159 Win=19456 Len=0 TSV=1091232983 TSER=25369178
  6   0.008348 31.222.175.142 -> 31.222.191.246 HTTP HTTP/1.1 200 OK  (text/html)
  7   0.008369 31.222.191.246 -> 31.222.175.142 TCP 60925 > 80 [ACK] Seq=159 Ack=301 Win=6912 Len=0 TSV=25369180 TSER=1091232983
  8   0.008651 31.222.191.246 -> 31.222.175.142 TCP 60925 > 80 [FIN, ACK] Seq=159 Ack=301 Win=6912 Len=0 TSV=25369180 TSER=1091232983
  9   0.008841 31.222.175.142 -> 31.222.191.246 TCP 80 > 60925 [FIN, ACK] Seq=301 Ack=160 Win=19456 Len=0 TSV=1091232983 TSER=25369180
 10   0.008855 31.222.191.246 -> 31.222.175.142 TCP 60925 > 80 [ACK] Seq=160 Ack=302 Win=6912 Len=0 TSV=25369180 TSER=1091232983
 11   2.182732 31.222.191.246 -> 31.222.175.142 TCP 60926 > 80 [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=25369723 TSER=0 WS=4
 12   2.183220 31.222.175.142 -> 31.222.191.246 TCP 80 > 60926 [SYN, ACK] Seq=0 Ack=1 Win=17896 Len=0 MSS=8960 TSV=1091233201 TSER=25369723 WS=9
 13   2.183240 31.222.191.246 -> 31.222.175.142 TCP 60926 > 80 [ACK] Seq=1 Ack=1 Win=5840 Len=0 TSV=25369723 TSER=1091233201
 14   2.183496 31.222.191.246 -> 31.222.175.142 HTTP GET / HTTP/1.1
 15   2.183658 31.222.175.142 -> 31.222.191.246 TCP 80 > 60926 [ACK] Seq=1 Ack=159 Win=19456 Len=0 TSV=1091233201 TSER=25369724
 16   2.186699 31.222.175.142 -> 31.222.191.246 HTTP HTTP/1.1 200 OK  (text/html)
 17   2.186717 31.222.191.246 -> 31.222.175.142 TCP 60926 > 80 [ACK] Seq=159 Ack=301 Win=6912 Len=0 TSV=25369724 TSER=1091233201
 18   2.188335 31.222.191.246 -> 31.222.175.142 TCP 60926 > 80 [FIN, ACK] Seq=159 Ack=301 Win=6912 Len=0 TSV=25369725 TSER=1091233201
 19   2.188756 31.222.175.142 -> 31.222.191.246 TCP 80 > 60926 [FIN, ACK] Seq=301 Ack=160 Win=19456 Len=0 TSV=1091233201 TSER=25369725
 20   2.188771 31.222.191.246 -> 31.222.175.142 TCP 60926 > 80 [ACK] Seq=160 Ack=302 Win=6912 Len=0 TSV=25369725 TSER=1091233201

We can see that from the client point of view the data comes always from the some IP address. The 2 pool members that we have are not visible.

The dumps bellow show as well that the responses came from different servers. We can confirm as well that neither the req or replay had a cookies header that was passed to the client.

root@urado1:/var/tmp# tshark -n -r server-urado1.pcap -V http
    GET / HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n]
            [Message: GET / HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: GET
        Request URI: /
        Request Version: HTTP/1.1
    User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5\r\n
    X-Forwarded-For: 31.222.191.246\r\n
    Accept: */*\r\n
    X-Forwarded-Proto: http\r\n
    Host: 31.222.175.142\r\n
    X-Cluster-Client-Ip: 31.222.191.246\r\n
    \r\n

    HTTP/1.1 200 OK\r\n
        [Expert Info (Chat/Sequence): HTTP/1.1 200 OK\r\n]
            [Message: HTTP/1.1 200 OK\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Version: HTTP/1.1
        Status Code: 200
        Response Phrase: OK
    Date: Tue, 27 Mar 2012 22:37:17 GMT\r\n
    Server: Apache/2.2.20 (Ubuntu)\r\n
    Last-Modified: Mon, 26 Mar 2012 21:29:38 GMT\r\n
    ETag: "7c030-2c-4bc2c1245f480"\r\n
    Accept-Ranges: bytes\r\n
    Content-Length: 44\r\n
        [Content length: 44]
    Vary: Accept-Encoding\r\n
    Content-Type: text/html\r\n
    \r\n
Line-based text data: text/html
    It works! urado1\n
    \n            


root@urado2:/var/tmp# tshark -n -r server-urado2.pcap -V http
    GET / HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n]
            [Message: GET / HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: GET
        Request URI: /
        Request Version: HTTP/1.1
    User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5\r\n
    X-Forwarded-For: 31.222.191.246\r\n
    Accept: */*\r\n
    X-Forwarded-Proto: http\r\n
    Host: 31.222.175.142\r\n
    X-Cluster-Client-Ip: 31.222.191.246\r\n
    \r\n

    HTTP/1.1 200 OK\r\n
        [Expert Info (Chat/Sequence): HTTP/1.1 200 OK\r\n]
            [Message: HTTP/1.1 200 OK\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Version: HTTP/1.1
        Status Code: 200
        Response Phrase: OK
    Date: Tue, 27 Mar 2012 22:37:21 GMT\r\n
    Server: Apache/2.2.20 (Ubuntu)\r\n
    Last-Modified: Mon, 26 Mar 2012 21:30:02 GMT\r\n
    ETag: "5c033-2c-4bc2c13b42a80"\r\n
    Accept-Ranges: bytes\r\n
    Content-Length: 44\r\n
        [Content length: 44]
    Vary: Accept-Encoding\r\n
    Content-Type: text/html\r\n
    \r\n
Line-based text data: text/html
    It works! urado2\n
    \n

Test scenario #2 with session persistence enabled on LB1

The test steps are the same as the one before. The only difference is a configuration change on LB1, where we enable persistence feature. The new tcpdumps were taken as before and can be downloaded from [2]. The easy way to see the differences without repeating ourselves again is to take a look at the curl output. We see directly there all our requests and replays with the HTML payload from the servers.

First GET request without Cookie header. In the response we see this time that the LB is sending one cookie we didn't see before.

[root@crado1 ~]# curl -v http://31.222.175.142
* About to connect() to 31.222.175.142 port 80
*   Trying 31.222.175.142... connected
* Connected to 31.222.175.142 (31.222.175.142) port 80
> GET / HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: 31.222.175.142
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache/2.2.20 (Ubuntu)
< Vary: Accept-Encoding
< Content-Type: text/html
< Date: Tue, 27 Mar 2012 22:57:56 GMT
< Accept-Ranges: bytes
< ETag: "7c030-2c-4bc2c1245f480"
< Set-Cookie: X-Mapping-fjhppofk=AEC8609A6667F8E6AC1B323F80BDF8C9; path=/
< Last-Modified: Mon, 26 Mar 2012 21:29:38 GMT
< Content-Length: 44
It works! urado1

* Connection #0 to host 31.222.175.142 left intact
* Closing connection #0

Another similar request. The response contains again Cookie header but with different value. The HTML payload from the 2 requests show that these are data from CS1 and CS2.

[root@crado1 ~]# curl -v http://31.222.175.142
* About to connect() to 31.222.175.142 port 80
*   Trying 31.222.175.142... connected
* Connected to 31.222.175.142 (31.222.175.142) port 80
> GET / HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: 31.222.175.142
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache/2.2.20 (Ubuntu)
< Vary: Accept-Encoding
< Content-Type: text/html
< Date: Tue, 27 Mar 2012 22:58:04 GMT
< Accept-Ranges: bytes
< ETag: "5c033-2c-4bc2c13b42a80"
< Set-Cookie: X-Mapping-fjhppofk=0459144121542E9668F8271676341C7B; path=/
< Last-Modified: Mon, 26 Mar 2012 21:30:02 GMT
< Content-Length: 44
It works! urado2

* Connection #0 to host 31.222.175.142 left intact
* Closing connection #0

We sent another request but this time the client supply the Cookie header provided before. We use the value returned for the Server2. Base on the HTML payload we see that the response comes from previously selected pool member. The LB doesn't provide another cookie as it was before.

[root@crado1 ~]# curl -v -H 'Cookie: X-Mapping-fjhppofk=0459144121542E9668F8271676341C7B' 31.222.175.142 
* About to connect() to 31.222.175.142 port 80
*   Trying 31.222.175.142... connected
* Connected to 31.222.175.142 (31.222.175.142) port 80
> GET / HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: 31.222.175.142
> Accept: */*
> Cookie: X-Mapping-fjhppofk=0459144121542E9668F8271676341C7B
>
< HTTP/1.1 200 OK
< Date: Tue, 27 Mar 2012 22:58:35 GMT
< Server: Apache/2.2.20 (Ubuntu)
< Last-Modified: Mon, 26 Mar 2012 21:30:02 GMT
< ETag: "5c033-2c-4bc2c13b42a80"
< Accept-Ranges: bytes
< Content-Length: 44
< Vary: Accept-Encoding
< Content-Type: text/html
It works! urado2

* Connection #0 to host 31.222.175.142 left intact
* Closing connection #0

The some request sent again returns the some result - as expected.

[root@crado1 ~]# curl -v -H 'Cookie: X-Mapping-fjhppofk=0459144121542E9668F8271676341C7B' 31.222.175.142                 
* About to connect() to 31.222.175.142 port 80
*   Trying 31.222.175.142... connected
* Connected to 31.222.175.142 (31.222.175.142) port 80
> GET / HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: 31.222.175.142
> Accept: */*
> Cookie: X-Mapping-fjhppofk=0459144121542E9668F8271676341C7B
>
< HTTP/1.1 200 OK
< Date: Tue, 27 Mar 2012 22:58:52 GMT
< Server: Apache/2.2.20 (Ubuntu)
< Last-Modified: Mon, 26 Mar 2012 21:30:02 GMT
< ETag: "5c033-2c-4bc2c13b42a80"
< Accept-Ranges: bytes
< Content-Length: 44
< Vary: Accept-Encoding
< Content-Type: text/html
It works! urado2

* Connection #0 to host 31.222.175.142 left intact
* Closing connection #0

Summary
The session persistence on the Rackspace Cloud Load Balancer uses HTTP cookie header. The load balancer when it returns the response back to the client it rewrites the IP addresses and inserts a new HTTP Cookie header. As long as the client obeys the Cookie value in his subsequent request it will be load balanced to the some pool member.

References
[1] persistence disabled
[2] persistence enabled

Tuesday, March 27, 2012

Network data analize for simple scenario with Rackspace Cloud Load Balancer (CLB)

A load balancer becomes de facto a standard for many distributed deployments. You are going to need it even if you don't know it yet.

Let's take a look at the Rackspace Cloud Load Balancer (CLB) feature [1] and dig a litter bit more how it actually works. We are going to base our analysis on the diagram below. As the scenario is very simple to set up and configure I'm leaving it for the reader alone.




Test scenario
  1. The client sends HTTP request to LB1.
  2. The LB1 load balance it to his only one pool member.
  3. The pool member replays with HTTP 200.
  4. LB1 sends the replay back to the client.

As we don't have access to the LB1 itself it is hard to say what is really happening there. The only way at the moment is to take concurrent tcpdumps on the client and server. To simulate the client requests we are going to use the curl. All commands look like that:

# run on client
tcpdump -nn -s0 -i any -w /var/tmp/client.pcap  port 80

# run on server
tcpdump -nn -s0 -i any -w /var/tmp/server-urado1.pcap  port 80

# run on client on a separate session for example
curl -v http://31.222.175.142

The data from the captured tcpdump can be seen below. The original files can be found here [2].

[root@crado1 tmp]# tshark  -n -r client.pcap
  1   0.000000 31.222.191.246 -> 31.222.175.142 TCP 47267 > 80 [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=3064226 TSER=0 WS=4
  2   0.000324 31.222.175.142 -> 31.222.191.246 TCP 80 > 47267 [SYN, ACK] Seq=0 Ack=1 Win=17896 Len=0 MSS=8960 TSV=1082311203 TSER=3064226 WS=9
  3   0.000344 31.222.191.246 -> 31.222.175.142 TCP 47267 > 80 [ACK] Seq=1 Ack=1 Win=5840 Len=0 TSV=3064226 TSER=1082311203
  4   0.000441 31.222.191.246 -> 31.222.175.142 HTTP GET / HTTP/1.1
  5   0.000565 31.222.175.142 -> 31.222.191.246 TCP 80 > 47267 [ACK] Seq=1 Ack=159 Win=19456 Len=0 TSV=1082311203 TSER=3064226
  6   0.018854 31.222.175.142 -> 31.222.191.246 HTTP HTTP/1.1 200 OK  (text/html)
  7   0.018873 31.222.191.246 -> 31.222.175.142 TCP 47267 > 80 [ACK] Seq=159 Ack=301 Win=6912 Len=0 TSV=3064231 TSER=1082311205
  8   0.019107 31.222.191.246 -> 31.222.175.142 TCP 47267 > 80 [FIN, ACK] Seq=159 Ack=301 Win=6912 Len=0 TSV=3064231 TSER=1082311205
  9   0.019323 31.222.175.142 -> 31.222.191.246 TCP 80 > 47267 [FIN, ACK] Seq=301 Ack=160 Win=19456 Len=0 TSV=1082311205 TSER=3064231
 10   0.019337 31.222.191.246 -> 31.222.175.142 TCP 47267 > 80 [ACK] Seq=160 Ack=302 Win=6912 Len=0 TSV=3064231 TSER=1082311205

root@urado1:~/tmp# tshark -n -r server-urado1.pcap
  1   0.000000 10.190.254.7 -> 10.177.132.15 TCP 76 40293 > 80 [SYN] Seq=0 Win=17920 Len=0 MSS=8960 SACK_PERM=1 TSval=1082311203 TSecr=0 WS=512
  2   0.000061 10.177.132.15 -> 10.190.254.7 TCP 76 80 > 40293 [SYN, ACK] Seq=0 Ack=1 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=117399288 TSecr=1082311203 WS=4
  3   0.000382 10.190.254.7 -> 10.177.132.15 TCP 68 40293 > 80 [ACK] Seq=1 Ack=1 Win=17920 Len=0 TSval=1082311203 TSecr=117399288
  4   0.000390 10.190.254.7 -> 10.177.132.15 HTTP 321 GET / HTTP/1.1
  5   0.000422 10.177.132.15 -> 10.190.254.7 TCP 68 80 > 40293 [ACK] Seq=1 Ack=254 Win=15552 Len=0 TSval=117399288 TSecr=1082311203
  6   0.017298 10.177.132.15 -> 10.190.254.7 HTTP 368 HTTP/1.1 200 OK  (text/html)
  7   0.017790 10.190.254.7 -> 10.177.132.15 TCP 68 40293 > 80 [ACK] Seq=254 Ack=301 Win=19456 Len=0 TSval=1082311205 TSecr=117399293
  8   5.032706 10.177.132.15 -> 10.190.254.7 TCP 68 80 > 40293 [FIN, ACK] Seq=301 Ack=254 Win=15552 Len=0 TSval=117400546 TSecr=1082311205
  9   5.063446 10.190.254.7 -> 10.177.132.15 TCP 68 40293 > 80 [ACK] Seq=254 Ack=302 Win=19456 Len=0 TSval=1082311710 TSecr=117400546

Analysis

Base on the tcpdumps from the server we can clearly see that the LB1 is changing the original source ip address. It means that our server can't directly relay on the original IP of the client. 

Looking further at the payload we can see that as the traffic is sent from LB to the pool member the load balancer inserts additional headers into the original GET request.

[root@crado1 tmp]# tshark -n -r client.pcap -V http
    GET / HTTP/1.1\r\n
        Request Method: GET
        Request URI: /
        Request Version: HTTP/1.1
    User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5\r\n
    Host: 31.222.175.142\r\n
    Accept: */*\r\n
    \r\n

    HTTP/1.1 200 OK\r\n
        Request Version: HTTP/1.1
        Response Code: 200
    Date: Mon, 26 Mar 2012 21:50:16 GMT\r\n
    Server: Apache/2.2.20 (Ubuntu)\r\n
    Last-Modified: Mon, 26 Mar 2012 21:29:38 GMT\r\n
    ETag: "7c030-2c-4bc2c1245f480"\r\n
    Accept-Ranges: bytes\r\n
    Content-Length: 44\r\n
        [Content length: 44]
    Vary: Accept-Encoding\r\n
    Content-Type: text/html\r\n
    \r\n
Line-based text data: text/html
    <html><body>It works! urado1\n
    </body></html>\n

root@urado1:~/tmp# tshark -n -r server-urado1.pcap -V http
    GET / HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n]
            [Message: GET / HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: GET
        Request URI: /
        Request Version: HTTP/1.1
    User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5\r\n
    X-Forwarded-For: 31.222.191.246\r\n
    Accept: */*\r\n
    X-Forwarded-Proto: http\r\n
    Host: 31.222.175.142\r\n
    X-Cluster-Client-Ip: 31.222.191.246\r\n
    \r\n
    [Full request URI: http://31.222.175.142/]

    HTTP/1.1 200 OK\r\n
        [Expert Info (Chat/Sequence): HTTP/1.1 200 OK\r\n]
            [Message: HTTP/1.1 200 OK\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Version: HTTP/1.1
        Status Code: 200
        Response Phrase: OK
    Date: Mon, 26 Mar 2012 21:50:16 GMT\r\n
    Server: Apache/2.2.20 (Ubuntu)\r\n
    Last-Modified: Mon, 26 Mar 2012 21:29:38 GMT\r\n
    ETag: "7c030-2c-4bc2c1245f480"\r\n
    Accept-Ranges: bytes\r\n
    Content-Length: 44\r\n
        [Content length: 44]
    Vary: Accept-Encoding\r\n
    Content-Type: text/html\r\n
    \r\n
Line-based text data: text/html
    It works! urado1\n
    \n

Summary

As the load balancer manipulates the IP addresses on the client and server site it still provides a method to identify the original source ip address of the client. There will be inserted a HTTP header X-Forwarded-For with the value of the original client IP address.


Tuesday, March 20, 2012

Working for the best in the industry

Technology leaders

I have recently start doing more analysis and  research of the market trends. It is extraordinary good feeling to know that you can volunteer for a work at the best companies worldwide ;). First it was F5 Networks and now with Rackspace. The blend of Load balancing, Cloud and Linux technologies is going to be the future foundation for next generation data center solution architectures.



References

www.f5.com
www.rackspace.com
www.openstack.org
http://www.diigo.com/user/rtomaszewski/magic_quadrants%20f5

Monday, March 19, 2012

Gartner Magic Quadrant analysis of cloud market trends and Rackspace profile.


Rackspace is leader in managed hosting and very strong player with big potential in cloud business worldwide. It has been openly recognized by Gartner, the information technology research and advisory firm.


Managed Hosting (evaluates and includes cloud )

Rackspace as a worldwide company has been recognized in 2012 by the Gartner as a leader in Managed Hosting business. This only show and prove that the company is fully prepared and ready to host and server for even Enterprise level customers.



Public Cloud Infrastructure as a Service and
Web Hosting and Hosted Cloud System Infrastructure Services 

With all the efforts done over the last years in promoting and developing the cloud platform Openstack the company has win as well a very strong position in the Cloud market. As before Gartner had recognized and valued it in 2009 and 2011.

 

References

http://www.openstack.org/
http://www.diigo.com/user/rtomaszewski/magic_quadrants%20cloud