65
Inside Sqale’s Backend Sapporo Ruby Kaigi 2012 Gosuke Miyashita paperboy&co. Inc.

Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Embed Size (px)

Citation preview

Page 1: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Inside Sqale’s Backend

Sapporo Ruby Kaigi 2012Gosuke Miyashitapaperboy&co. Inc.

Page 2: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

A little bit about me

Page 3: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012
Page 4: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Technical Managerat

paperboy&co.

Page 5: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

https://github.com/mizzyhttp://mizzy.org/

@gosukenator

Page 6: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Inside Sqale’s Backend

Page 7: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

http://www.facebook.com/sqalejp

Page 8: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

WARNINGThere are little topics

about Ruby in this talk

Page 9: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

What is Sqale?

Page 10: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012
Page 11: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Cloud Application Platform like Heroku

Page 12: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Architecture Overview

Page 13: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

AWS

SSH Router

Containers

Web Proxyto Containers

Deploy Servers

File Repositories

SFTPGit over SSHSSH

HTTP/HTTPS

Page 14: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Containers

Page 15: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

AWS

SSH Router

Containers

Web Proxyto Containers

Deploy Servers

File Repositories

SFTPGit over SSHSSH

HTTP/HTTPS

Page 16: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Virtual Environments Assigned To Users

Page 17: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Similar to Dynos of Heroku

Page 18: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Containers made by LXC (Linux Containers)

Page 19: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

EC2 Instance (1 Virtual Machine)

Container for

user B

Container for

user A

Container for

user A

Container for

user B

Container for

user B

Container for

user D

Container for

user D

Container for

user C

Container for

user E

Container for

user E

Container for

user F

Container for

user F

Container for

user E

Container for

user F

Container for

user F

Page 20: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

NginxUnicorn

sshdsupervisrod

on each container

Page 21: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Amazon Linux+

Patched kernel(3.2.16)

Page 22: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

grsecurity kernel patchfor various restrictions

Page 23: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

original kernel patchesto restrict tcp port

bind and fork bomb

Page 24: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012
Page 25: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012
Page 26: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Anti fork bomb patch makes some changes to cgroup and fork process

Page 27: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Seepaperboy-sqale/sqale-patches

on GitHub

Page 28: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Web Proxy

Page 29: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

AWS

SSH Router

Containers

Web Proxyto Containers

Deploy Servers

File Repositories

SFTPGit over SSHSSH

HTTP/HTTPS

Page 30: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

nginx

Container for

user A

Container for

user B

Container for

user B

Container for

user C

Container for

user C

Container for

user C

ELB

nginx

HTTP/HTTPS

Page 31: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

nginxlua-nginx-module

redis2-nginx-module

Page 32: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Container for

i4pc-mizzy

Container for

i4pc-mizzy

Container for

lokka-mizzy

Container for

lokka-mizzy

nginx

http://lokka-mizzy.sqale.jp/

Redis

nginx port 8081 nginx port 8082 nginx port 8083 nginx port 8084

Which containers?

host001:8083, host001:8084

host001

or

Page 33: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

location / {set $container "";set $next_containers "";

error_page 502 = @failover;

rewrite_by_lua_file dynamic-proxy.lua;proxy_pass http://$container;

}

nginx.conf (excerpt)

Page 34: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

local reply = ngx.location.capture("/redis")if reply.status ~= ngx.HTTP_OK thenngx.exit(503)

end

local containers, type = parser.parse_reply(reply.body)

dynamic-proxy.lua (excerpt)

Page 35: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

while #containers > 0 dotmp = table.remove(

containers,math.random(#containers))

if ngx.shared.downed_containers:get(tmp) thenngx.log(ngx.DEBUG, tmp .. " is down")

elsecontainer = tmpbreak

endend

dynamic-proxy.lua (excerpt)

Page 36: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

ngx.var.container = containerngx.var.next_containers= luabins.save(containers)

dynamic-proxy.lua (excerpt)

Page 37: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

location / {set $container "";set $next_containers "";

error_page 502 = @failover;

rewrite_by_lua_file dynamic-proxy.lua;proxy_pass http://$container;

}

nginx.conf (again)

Page 38: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

location @failover {error_page 502 = @failover;

rewrite_by_lua_file failover.lua;proxy_pass http://$container;

}

nginx.conf (excerpt)

Page 39: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

failover.lua (excerpt)

local downed_container = ngx.var.containerif downed_container thenngx.shared.downed_containers:set(downed_container,1,sqale.NEGATIVE_CACHE_SECONDS

)end

Page 40: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

failover.lua (excerpt)

while #containers > 0 dotmp = table.remove(

containers,math.random(#containers))

if ngx.shared.downed_containers:get(tmp) thenngx.log(ngx.DEBUG, tmp .. " is down")

elsecontainer = tmpbreak

endend

Page 41: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

if not container thenngx.exit(503)

end

ngx.var.container = containerngx.var.next_containers= luabins.save(containers)

failover.lua (excerpt)

Page 42: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

location @failover {error_page 502 = @failover;

rewrite_by_lua_file failover.lua;proxy_pass http://$container;

}

nginx.conf (agin)

Page 43: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Seehttp://bit.ly/UHbHIb

by @hiboma

Page 44: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

SSH Router

Page 45: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

AWS

SSH Router

Containers

Web Proxyto Containers

Deploy Servers

File Repositories

SFTPGit over SSHSSH

HTTP/HTTPS

Page 46: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

SSH Router

File Repositories(Git Server)

Git SSH Login

File Repositories(File Server)

Containers

SFTP

Page 47: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

How implement this routing?

Page 48: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

OpenSSH with script authentication patch

Page 49: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012
Page 50: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Seemizzy/openssh-script-auth

on GitHub

Page 51: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Change routes by SSH_ORIGNAL_COMMAND

Page 52: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012
Page 53: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

In case of SSH_ORIGINAL_COMMAND

is “git-*”

Page 54: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

SSH Router

File Repository(Git Server)

git push(ssh [email protected] git-recieve-pack‘/mizzy/lokka.git’)

MySQL

Run AuthorizedKeysScript

Verify the public keyand get the user’s gitserver

command=“ssh [email protected]‘/var/repos/mizzy/lokka.git’”

Page 55: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

In case of SSH_ORIGINAL_COMMAND

is “sftp-server”

Page 56: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

SSH Router

File Repository

(File Server)

sftp [email protected](ssh [email protected] sftp-server)

MySQL

File Repository(Git Server)

git push

Run AuthorizedKeysScript

Verify the public keyand get the user’s file server

command=“ssh [email protected]

Page 57: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

In case of SSH_ORIGINAL_COMMAND

is empty

Page 58: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

SSH Router

Container

ssh [email protected]

MySQL

Run AuthorizedKeysScript

Verify the public keyand get the user’s cotainers list

command=“ssh sqale@ users001.sqale.lan -p 8081”

Display the user’s containers list and wait the user’s selection

Page 59: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012
Page 60: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Deploy Servers

Page 61: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

AWS

SSH Router

Containers

Web Proxyto Containers

Deploy Servers

File Repositories

SFTPGit over SSHSSH

HTTP/HTTPS

Page 62: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Please ask to@kyanny

Page 63: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Other

Page 64: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

About Sqale’s Server Build Automation

http://bit.ly/NBbj9Fby @lamanotrama

Page 65: Inside Sqale's Backend at Sapporo Ruby Kaigi 2012

Thanks