Programming proxies to do what we need so we don't have to talk to the network guys again

22
PROGRAMMING PROXIES TO DO WHAT WE NEED SO WE DON'T HAVE TO TALK TO THE NETWORK GUYS AGAIN @lmacvittie from @f5networks at #gluecon Lori MacVittie Sr. Product Manager, Emerging Technologies F5 Networks

description

Programmable proxies enable devops patterns and introduce flexibility into the network.

Transcript of Programming proxies to do what we need so we don't have to talk to the network guys again

Page 1: Programming proxies to do what we need so we don't have to talk to the network guys again

PROGRAMMING PROXIES TO DO WHAT WE NEED SO WE DON'T HAVE TO

TALK TO THE NETWORK GUYS AGAIN

@lmacvittie from @f5networks at #gluecon

Lori MacVittie

Sr. Product Manager, Emerging TechnologiesF5 Networks

Page 2: Programming proxies to do what we need so we don't have to talk to the network guys again

Deployment patterns

WHY WOULD YOU NEED TO TALK TO

THE NETWORK GUYS ANYWAY?

@lmacvittie #gluecon

Page 3: Programming proxies to do what we need so we don't have to talk to the network guys again

DEPLOYMENT PATTERNS USE LAYER 7 ROUTING

Canary Deployments Blue/Green Deployments

A/B Testing

v.1

v.2v.3

API Management

Redirection Replication (Dark Architecture)

@lmacvittie #gluecon

Page 4: Programming proxies to do what we need so we don't have to talk to the network guys again

ROUTING IS A NETWORK THING

Router Switch FirewallDDoS Protection

Load Balancing

DNS

CORE NETWORK (SHARED)

THE NETWORK GUYS ARE GENERALLY RESPONSIBLE FOR LAYER 7 ROUTING

@lmacvittie #gluecon

Page 5: Programming proxies to do what we need so we don't have to talk to the network guys again

THEY DON’T WANT YOU TOUCHING THEIR TOYS

@lmacvittie #gluecon

Page 6: Programming proxies to do what we need so we don't have to talk to the network guys again

proxiesSO WHAT DO YOU

DO?

@lmacvittie #gluecon

Page 7: Programming proxies to do what we need so we don't have to talk to the network guys again

Go forward and backwards.

PROXIES

A Reverse Proxy sits between the user and an application and can do things like caching, load balancing, and security on behalf of the app.

A Forward Proxy sits between the user and an application and does things like caching and stopping you from using Facebook at work.

Today we’re (mostly) talking about the Reverse kind of Proxy. @lmacvittie #gluecon

Page 8: Programming proxies to do what we need so we don't have to talk to the network guys again

Proxies are appl ication-aware with network chops. They are fl uent in both the language of appl ications and networks.

PROXIES

THIS IS WHERE NETWORK STUFFS LIVE

THIS IS WHERE PROXIES LIVE

THIS IS WHERE APPLICATIONS LIVE

DATA

NETWORK

TRANSPORT

SESSION

PRESENTATION

APPLICATION

MAC ADDRESS

IP ADDRESS

TCP

SOCKS

SSL

HTTP / SPDY

L2-3 SERVICES

L4-7 SERVICES

HTML JSON XMLCSS

@lmacvittie #gluecon

Page 9: Programming proxies to do what we need so we don't have to talk to the network guys again

WEB SERVER

PROXY MODEL

VERSUS

PROGRAMMABL

E PROXY MODEL

Proxy

Code

Config

Web Server Proxy Model

Application Stuffs

Network Stuffs

Programmable Proxy Model

Proxy

Code

Config

Application Stuffs

Network Stuffs

@lmacvittie #gluecon

Page 10: Programming proxies to do what we need so we don't have to talk to the network guys again

A programmable proxy is a proxy that lets you wr i te code that interacts wi th both appl icat ion and network stuff s l ike load balanc ing and appl icat ion (L7) rout ing and databases.

PROGRAMMABL

E PROXIES var onRequest = function(request, response, next ) { var cookie = new Cookies( request, response ); var bugz_login = cookie.get("Bugzilla_login");

if( !logged_in || !bugz_login ) { vs_a.newRequest(request, response, next); return; } connection.query('SELECT opt_in from abtest where userid=' + bugz_login, function(err, rows, fields) { if (err) throw err; var opt_in = rows[0].opt_in; if( !opt_in ) { vs_a.newRequest(request, response, next); return; } else { vs_b.newRequest(request, response, next); return; } });

Bugzilla

Bugzilla-A

Bugzilla-B

APPLICATION STUFFS

NETWORKSTUFFS

@lmacvittie #gluecon

Page 11: Programming proxies to do what we need so we don't have to talk to the network guys again

Deployment patterns with programmable proxies

EXAMPLES

@lmacvittie #gluecon

Page 12: Programming proxies to do what we need so we don't have to talk to the network guys again

A/B TESTING

Devices

Internet

Service Pool A

Service Pool B

serverGroupA

serverGroupB

vs1

vs2

• Transparently direct users to either version “A” or version “B”• Increase or decrease traffic to each version in an instant• Customize the selection criteria to your needs with a short Node.js

script• Use resources like databases or web APIs as part of the decision@lmacvittie #gluecon

MySQL Database

Page 13: Programming proxies to do what we need so we don't have to talk to the network guys again

var assert = require('assert');var os = require('os');var http = require('http');var fpm = require('lrs/forwardProxyModule');var vsm = require('lrs/virtualServerModule');var mysql = require('mysql');var Cookies = require('cookies');

var proxyhost = os.hostname();var vs = vsm.find('Bugzilla');var vs_a = vsm.find('Bugzilla-A');var vs_b = vsm.find('Bugzilla-B');var logged_in = false;

// Log to a databasevar connection = mysql.createConnection({ host : '192.168.22.22', user : ‘xxxx', password : ‘yyyyyyyyy', database : 'abtesting'});

var onRequest = function(request, response, next ) { var cookie = new Cookies( request, response ); var bugz_login = cookie.get("Bugzilla_login");

if( !logged_in || !bugz_login ) { // Default action: Send to A vs_a.newRequest(request, response, next); return; }

// Add the user to the database automatically if they don't already exist connection.query('INSERT INTO abtest (userid, ip) select * FROM (SELECT ' + bugz_login + ', "' + request.connection.remoteAddress + '") as tmp \ WHERE NOT EXISTS(SELECT userid from abtest where userid=' + bugz_login + ')', function(err, rows, fields) { if (err) throw err;

// Use the database to decide which server to send this request to connection.query('SELECT opt_in from abtest where userid=' + bugz_login, function(err, rows, fields) { if (err) throw err; var opt_in = rows[0].opt_in; if( !opt_in ) { vs_a.newRequest(request, response, next); return; } else { vs_b.newRequest(request, response, next); return; } }); });}; // onRequestvar onExist = function(vs) { if(vs.id == 'Bugzilla') { vs.on('request', onRequest); connection.connect(); logged_in = true; setInterval(keepAlive, 60000); }};vsm.on('exist', 'Bugzilla', onExist);

Page 14: Programming proxies to do what we need so we don't have to talk to the network guys again

URI MANAGEMENT (REDIRECTION)

Devices

Internet

• Manage hundreds of redirects/rewrites (www.example.com/app2 www.example.com/app/v2)

• Update redirects without incurring potential outages • Turn over management to the business folks because updating http

conf files every other day isn’t exactly the job you signed up for @lmacvittie #gluecon

serverGroupA

serverGroupB

vs1

vs2

Page 15: Programming proxies to do what we need so we don't have to talk to the network guys again

TRAFFIC REPLICATION

Devices

Internet

Production

Staging

serverGroupA

serverGroupB

LB

LB

• Selected requests are replicated to both environments

• Selection criteria can be custom logic or network or application variables

@lmacvittie #gluecon

Page 16: Programming proxies to do what we need so we don't have to talk to the network guys again

TRAFFIC REPLICATION

Devices

Internet

Production

Staging

serverGroupA

serverGroupB

LB

LB

• Production response flows back to user immediately

• Staging response is blocked from clients

• Custom code can compare production and staging response, report errors, slowness, etc. and can log for later analysis @lmacvittie #gluecon

Page 17: Programming proxies to do what we need so we don't have to talk to the network guys again

function forwardRequest(request, response, next) {"use strict";

var vsm = require('lrs/virtualServerModule');var http = require('http');var mgmt = require('lrs/managementRest');

function ReplicateTraffic(scenarioName, primaryVSName, secondaryPort) {    var self = this;    self.scenarioName = scenarioName;    self.primaryVS = primaryVSName;    self.port = secondaryPort;        //We need a secondary port that we expect is a loopback virtual IP that     //goes to the secondary virtual server          vsm.on('exist', primaryVSName, function(vs) {        vs.on('request', function(req, res, next) {             self.replicate(req, res, next);        });        });}

ReplicateTraffic.prototype.cloneReq = function(req) {    var newReq = http.request({ host: "127.0.0.1",                                port: this.port,                                method: req.method,                                path: req.url,                                headers: req.headers},                               function() {});    return newReq;}ReplicateTraffic.prototype.replicate = function(req, res, next) {    if(req.method == 'GET' || req.method == 'HEAD') {         // Only do GET and HEAD        var newReq = this.cloneReq(req);        // I want to do vsB.newRequest(newReq) but cannot         // so I loop it through a dummy vip in cloneReq        newReq.on('response', function(res) { console.log('saw B resp'); });        newReq.end();    }    next();}

var repl = new ReplicateTraffic("xxx",                                 'vsAandB',                                 15000);

Page 18: Programming proxies to do what we need so we don't have to talk to the network guys again

Network stuff s belong in the network.

WHEN SHOULD I USE A PROGRAMMABLE

PROXY?

@lmacvittie #gluecon

Page 19: Programming proxies to do what we need so we don't have to talk to the network guys again

How to choose between proxy and app

NETWORK STUFFS

• chooses an application instance based on HTTP header • Content-type, URI, device (user-agent), API

version, HTTP CRUD operation, etc… • chooses an application instance based on payload

• Value of a key in a JSON payload, XML element value, HTML form data, etc…

• would force you to use an HTTP redirect • Changing URLs• Deprecated API calls

• is enforcing a quota (rate limiting) to avoid overwhelming applications

• needs to do a network thing (e.g. app routing, load balancing, service chaining) that requires application data from an external source (database, API call, etc…)

Put the logic in a proxy if the logic ….

@lmacvittie #gluecon

Page 20: Programming proxies to do what we need so we don't have to talk to the network guys again

Use programmable prox ies to implement deployment patterns that requ ire more log ic than bas ic condi t iona ls or data f rom externa l sources

DEVOPS PATTERNS

@lmacvittie #gluecon

Canary Deployments

Blue/Green Deployments

A/B Testing

v.1

v.2v.3

API Management

Redirection

Replication (Dark Architecture)

Page 21: Programming proxies to do what we need so we don't have to talk to the network guys again

I f you can code it , you can do it (probably)

PROGRAMMABL

E PROXIES

More things you can do with a programmable proxy

Application

security

Broker authenticatio

n

Identity devices and

users

v1.04API version matching

Rate Limiting / API quota

enforcement

@lmacvittie #gluecon