Summary: Initial commit for vpc multi-network public loadbalancer

Detail: Adjust vpc_loadbalance.sh to adjust firewall rules for multi-tier LB,
call /root/reconfigLB_vpc rather than /root/reconfigLB.sh (single isolatednet
script). Disable check that only allows one loadbalanced network offering
per VPC.

BUG-ID: CLOUDSTACK-2367
Signed-off-by: Marcus Sorensen <marcus@betterservers.com> 1367957466 -0600
This commit is contained in:
Marcus Sorensen 2013-05-07 14:22:21 -06:00
parent 732566e703
commit 269e87591e
3 changed files with 186 additions and 34 deletions

View File

@ -54,8 +54,8 @@ fw_remove() {
fw_backup() {
fw_remove_backup
sudo iptables -E load_balancer back_load_balancer 2> /dev/null
sudo iptables -E lb_stats back_lb_stats 2> /dev/null
iptables -S load_balancer | sed 's/load_balancer/back_load_balancer/g'|xargs -i /bin/bash -c "/sbin/iptables {} 2>/dev/null"
iptables -S lb_stats | sed 's/lb_stats/back_lb_stats/g'|xargs -i /bin/bash -c "/sbin/iptables {} 2>/dev/null"
}
fw_restore() {
@ -65,7 +65,6 @@ fw_restore() {
}
fw_chain_create () {
fw_backup
sudo iptables -N load_balancer 2> /dev/null
sudo iptables -A INPUT -p tcp -j load_balancer 2> /dev/null
sudo iptables -N lb_stats 2> /dev/null
@ -87,26 +86,45 @@ fw_entry() {
fi
local a=$(echo $added | cut -d, -f1- --output-delimiter=" ")
local r=$(echo $removed | cut -d, -f1- --output-delimiter=" ")
fw_chain_create
fw_backup
sudo iptables -L load_balancer >/dev/null 2>&1 || fw_chain_create
success=0
while [ 1 ]
do
for i in $a
do
local pubIp=$(echo $i | cut -d: -f1)
local dport=$(echo $i | cut -d: -f2)
sudo iptables -A load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null
success=$?
if [ $success -gt 0 ]
local dport=$(echo $i | cut -d: -f2)
if ! sudo iptables -C load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null
then
break
sudo iptables -A load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null
success=$?
if [ $success -gt 0 ]
then
break
fi
fi
done
for i in $r
do
local pubIp=$(echo $i | cut -d: -f1)
local dport=$(echo $i | cut -d: -f2)
if sudo iptables -C load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null
then
sudo iptables -D load_balancer -p tcp -d $pubIp --dport $dport -j ACL_INBOUND_$dev 2>/dev/null
success=$?
if [ $success -gt 0 ]
then
break
fi
fi
done
if [ "$stats" != "none" ]
then
local pubIp=$(echo $stats | cut -d: -f1)
local dport=$(echo $stats | cut -d: -f2)
local dport=$(echo $stats | cut -d: -f2)
local cidrs=$(echo $stats | cut -d: -f3 | sed 's/-/,/')
sudo iptables -F lb_stats
sudo iptables -A lb_stats -s $cidrs -p tcp -d $pubIp --dport $dport -j ACCEPT 2>/dev/null
success=$?
fi
@ -117,13 +135,14 @@ fw_entry() {
fw_restore
else
fw_remove_backup
fi
fi
return $success
}
#Hot reconfigure HA Proxy in the routing domain
reconfig_lb() {
/root/reconfigLB.sh
logger -t cloud "running reconfigLB.sh -d $1"
/root/reconfigLB_vpc -d $1
return $?
}
@ -131,12 +150,12 @@ reconfig_lb() {
restore_lb() {
logger -t cloud "Restoring HA Proxy to previous state"
# Copy the old version of haproxy.cfg into the file that reconfigLB.sh uses
cp /etc/haproxy/haproxy.cfg.old /etc/haproxy/haproxy.cfg.new
# cp /etc/haproxy/haproxy.cfg.old /etc/haproxy/haproxy.cfg.new
if [ $? -eq 0 ]
then
# Run reconfigLB.sh again
/root/reconfigLB.sh
/root/reconfigLB_vpc -R
fi
}
@ -166,6 +185,7 @@ do
esac
done
logger -t cloud "haproxy: i=$ip a=$addedIps d=$removedIps s=$statsIp"
dev=$(getEthByIp $ip)
@ -180,7 +200,7 @@ then
fi
# hot reconfigure haproxy
reconfig_lb
reconfig_lb $removedIps
if [ $? -gt 0 ]
then
@ -190,12 +210,12 @@ fi
# iptables entry to ensure that haproxy receives traffic
fw_entry $addedIps $removedIps $statsIp
result=$?
result=$?
if [ $result -gt 0 ]
then
logger -t cloud "Failed to apply firewall rules for load balancing, reverting HA Proxy config"
# Restore the LB
restore_lb
fi
unlock_exit $result $lock $locked

View File

@ -0,0 +1,148 @@
#!/usr/bin/perl
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# @VERSION@
use strict;
use Getopt::Std;
my $debug = 0;
my $opts = {};
getopts('d:R',$opts);
my @removedips = split(/,/,$opts->{d});
# remove trailing colons from ip/port entries, if exists
removecolon(\@removedips);
if($opts->{R}){
# restore .save file if -R was passed in
`mv -f /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.reverted`;
`mv /etc/haproxy/haproxy.cfg.save /etc/haproxy/haproxy.cfg`;
} else {
# merge passed config with current config
logger("reconfigLB got removedips=$opts->{d}");
`mv -f /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.save`;
open(FILE,">/etc/haproxy/haproxy.cfg");
print FILE generate_config();
close FILE;
}
# graceful restart
`mv /var/run/haproxy.pid /var/run/haproxy.pid.old`;
my $oldpid = `cat /var/run/haproxy.pid.old`;
`kill -TTOU $oldpid`;
sleep 2;
`haproxy -D -p /var/run/haproxy.pid -f /etc/haproxy/haproxy.cfg`;
if ($? == 0) {
logger("New haproxy instance successfully loaded, stopping previous one.");
`kill -KILL $oldpid`;
`rm -f /var/run/haproxy.pid.old`;
exit 0;
} else {
logger("New instance failed to start, resuming previous one.");
`kill -TTIN $oldpid`;
`rm -f /var/run/haproxy.pid`;
`mv /var/run/haproxy.pid.old /var/run/haproxy.pid`;
`mv -f /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.newfail`;
`mv /etc/haproxy/haproxy.cfg.save /etc/haproxy/haproxy.cfg`;
exit 1;
}
########### subs ###########
sub generate_config {
my $config;
open (NEWFILE, "/etc/haproxy/haproxy.cfg.new");
open (CURFILE, "/etc/haproxy/haproxy.cfg.save");
# read in new config
my $sections = {};
my $section;
while (my $line = <NEWFILE>) {
$section = $line if $line =~ /^\w/;
print "found line for section $section\n" if $debug;
push @{$sections->{$section}},$line;
}
close NEWFILE;
# fetch old config
my $oldsections = {};
my $oldsection;
while (my $line = <CURFILE>){
$oldsection = $line if $line =~ /^\w/;
# skip default, global, and stats lines, we always want the latest
next if $oldsection =~ /^global/;
next if $oldsection =~ /^default/;
next if $oldsection =~ /^listen\sstats/;
next if $oldsection =~ /^listen\scloud-default/;
# delete/skip it if it is on remove list
my $skip = 0;
foreach my $remip (@removedips) {
if($oldsection =~ /^listen/ && $oldsection =~ /$remip/){
$skip = 1;
print "skipping line for section $oldsection since it is on remove list\n" if $debug;
}
}
next if $skip;
push @{$oldsections->{$oldsection}},$line;
}
close CURFILE;
# print new config
print "############ printing new config:\n\n" if $debug;
foreach my $section (sort keys %{$sections}) {
foreach my $line(@{$sections->{$section}}) {
$config .= $line;
}
$config .= "\n";
}
# add in old config that we didn't get a new config for
print "############ printing existing config:\n\n" if $debug;
foreach my $oldsection (sort keys %{$oldsections}) {
next if exists $sections->{$oldsection};
foreach my $line(@{$oldsections->{$oldsection}}) {
$config .= $line;
}
$config .= "\n";
}
return $config;
}
sub logger {
my $msg = shift;
`logger -t cloud $msg`;
}
sub removecolon {
my $list = shift;
foreach(@{$list}){
$_ =~ s/:$//;
}
}

View File

@ -1037,22 +1037,6 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
pr + " is not supported by VPC " + vpc);
}
}
//4) Only one network in the VPC can support LB
if (_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.Lb)) {
List<? extends Network> networks = getVpcNetworks(vpc.getId());
for (Network network : networks) {
if (networkId != null && network.getId() == networkId.longValue()) {
//skip my own network
continue;
} else {
if (_ntwkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) {
throw new InvalidParameterValueException("LB service is already supported " +
"by network " + network + " in VPC " + vpc);
}
}
}
}
}
@Override