OpenStack: Octavia LoadBalancer (LBaaS)

Create Amphora image
sudo apt install -y python-pip git qemu qemu-utils debootstrap kpartx
sudo pip install diskimage-builder
git clone https://review.openstack.org/p/openstack/octavia
cd octavia
sudo ./diskimage-create/diskimage-create.sh -d bionic -t raw
chmod a+r ./amphora-x64-haproxy.raw

Upload Amphora image
#openstack image create --container-format bare --disk-format qcow2 --private --file amphora-x64-haproxy.qcow2 --tag amphora amphora
openstack image create --container-format bare --disk-format raw --public --file amphora-x64-haproxy.raw --tag amphora amphora --os-cloud=dev-admin
openstack image set --protected amphora --os-cloud=dev-admin
openstack image list --long

Configure OpenStack
OCTAVIA_KEYSTONE_PASSWORD=$(cat /etc/kolla/passwords.yml | grep octavia_keystone_password | cut -d":" -f2)
echo ${OCTAVIA_KEYSTONE_PASSWORD}
#openstack flavor create --id octavia --disk 20 --private --ram 512 --vcpus 1 octavia --os-cloud=dev-admin
openstack flavor create --disk 20 --public --ram 512 --vcpus 1 octavia --os-cloud=dev-admin
openstack --os-username octavia --os-password ${OCTAVIA_KEYSTONE_PASSWORD} keypair create --public-key ~/.ssh/id_rsa.pub octavia_ssh_key --os-cloud=dev-admin
openstack security group create --description 'used by Octavia amphora instance' octavia --os-cloud=dev-admin
openstack security group rule create --protocol icmp octavia --os-cloud=dev-admin
openstack security group rule create --protocol tcp --dst-port 5555 --egress octavia --os-cloud=dev-admin
openstack security group rule create --protocol tcp --dst-port 9443 --ingress octavia --os-cloud=dev-admin

Deploy Octavia (with kolla-ansible
openstack image create amphora --file /root/amphora-x64-haproxy.raw --disk-format raw --min-disk 0 --min-ram 0 --private --protected --tag amphora --property os_distro=ubuntu --property os_admin_user=ubuntu --property os_version="18.04"
octavia_amp_boot_network_list="$(openstack network create lb-mgmt-net -f value -c id)"
octavia_subnet="$(openstack subnet create lb-mgmt-subnet1 --network lb-mgmt-net --subnet-range 172.16.0.0/12 --allocation-pool start=172.16.100.1,end=172.31.200.200 -f value -c id)"
octavia_amp_flavor_id="$(openstack flavor create --disk 20 --private --ram 4096 --vcpus 2 octavia -f value -c id)"
octavia_amp_secgroup_list="$(openstack security group create octavia -f value -c id)"
openstack security group rule create --protocol icmp $octavia_amp_secgroup_list
openstack security group rule create --protocol tcp --dst-port 5555 --egress $octavia_amp_secgroup_list
openstack security group rule create --protocol tcp --dst-port 9443 --ingress $octavia_amp_secgroup_list
openstack role add --user admin --domain Default admin
nova keypair-add --pub-key=/root/.ssh/id_rsa.pub --user $(openstack user show octavia --domain Default -f value -c id) octavia_ssh_key
echo "octavia_amp_boot_network_list: ${octavia_amp_boot_network_list}" >> /etc/kolla/globals.yml
echo "octavia_amp_secgroup_list: ${octavia_amp_secgroup_list}" >> /etc/kolla/globals.yml
echo "octavia_amp_flavor_id: ${octavia_amp_flavor_id}" >> /etc/kolla/globals.yml
# sed -i "s|^octavia_amp_boot_network_list: .*|octavia_amp_boot_network_list: ${octavia_amp_boot_network_list}|g" /etc/kolla/globals.yml
# sed -i "s|^octavia_amp_secgroup_list: .*|octavia_amp_secgroup_list: ${octavia_amp_secgroup_list}|g" /etc/kolla/globals.yml
# sed -i "s|^octavia_amp_flavor_id: .*|octavia_amp_flavor_id: ${octavia_amp_flavor_id}|g" /etc/kolla/globals.yml
cd /opt/kolla-ansible/tools
./kolla-ansible -i ../ansible/inventory/all-in-one deploy -t octavia

# debug
docker restart octavia_api octavia_health_manager octavia_housekeeping octavia_worker

Create LoadBalancer

LB=foo-lb1
SUBNET=foo-subnet
VM_IPS="10.0.1.11 10.0.1.12"

openstack loadbalancer create --name ${LB} --vip-subnet-id ${SUBNET}
while !

; do sleep 10; done
# openstack loadbalancer list
 
openstack loadbalancer listener create --name ${LB}-listener --protocol HTTP --protocol-port 80 ${LB}
 
openstack loadbalancer pool create --name ${LB}-pool --lb-algorithm ROUND_ROBIN --listener ${LB}-listener --protocol HTTP
while ! [ "$(openstack loadbalancer pool show ${LB}-pool -c provisioning_status -f value)" == "ACTIVE" ]; do sleep 10; done
 
for VM_IP in ${VM_IPS}; do
    openstack loadbalancer member create --subnet-id ${SUBNET} --address ${VM_IP} --protocol-port 80 ${LB}-pool
done
 
LB_PORT_ID=$(openstack loadbalancer show ${LB} -c vip_port_id -f value)
FLOATING_IP=$(openstack floating ip create public -c floating_ip_address -f value)
echo ${FLOATING_IP}
 
openstack floating ip set --port ${LB_PORT_ID} ${FLOATING_IP}
 
<strong>Create SSL LoadBalancer</strong>
LB_BACKEND_IP_1=10.0.1.11
LB_BACKEND_IP_2=10.0.1.12
 
#
# Convert certificates
#
# Convert first Let's Encrypt certificate to p12
openssl pkcs12 -export -out cert1.p12 -inkey privkey1.pem -in cert1.pem -certfile chain1.pem -passout "pass:"
openstack secret store --name=cert1 -t "application/octet-stream" -e base64 --payload="$(base64 [geshifilter- cert1.p12)"
 
# Convert second Let's Encrypt certificate to p12
openssl pkcs12 -export -out cert2.p12 -inkey privkey1.pem -in cert1.pem -certfile chain1.pem -passout "pass:"
openstack secret store --name=cert2 -t 'application/octet-stream' -e base64 --payload="$(base64 < cert2.p12)"
 
 
#
# Configure LB
#
# Create LoadBalancer
#openstack loadbalancer create --name lb1 --vip-subnet-id foo-subnet
LB_PORT_ID=$(openstack loadbalancer create --name lb1 --vip-subnet-id foo-subnet -c vip_port_id -f value)
while ! [ "$(openstack loadbalancer show lb1 -c provisioning_status -f value)" == "ACTIVE" ]; do sleep 1; done
 
# Add floating IP
#LB_PORT_ID=$(openstack loadbalancer show lb1 -c vip_port_id -f value)
FLOATING_IP=$(openstack floating ip create public -c floating_ip_address -f value --floating-ip-address 10.1.2.3)
openstack floating ip set --port ${LB_PORT_ID} ${FLOATING_IP}
 
 
#
# Configure HTTP
#
# Create HTTP listener
openstack loadbalancer listener create --name http-listener --protocol HTTP --protocol-port 80 lb1
 
# Create pool and add member
openstack loadbalancer pool create --name http-pool --lb-algorithm ROUND_ROBIN --listener http-listener --protocol HTTP
openstack loadbalancer member create http-pool --address ${LB_BACKEND_IP_1} --protocol-port 80 # --subnet-id foo-subnet
openstack loadbalancer member create http-pool --address ${LB_BACKEND_IP_2} --protocol-port 80
 
 
#
# Configure HTTPS
#
# Create HTTPS listener
openstack loadbalancer listener create --name https-listener --protocol-port 443 --protocol TERMINATED_HTTPS  \
  --default-tls-container=$(openstack secret list | awk '/ cert1 / {print $2}') \
  --sni-container-refs $(openstack secret list | awk '/ cert1 / {print $2}') $(openstack secret list | awk '/ cert2 / {print $2}') -- lb1
 
# Create pool and add member
openstack loadbalancer pool create --name https-pool --lb-algorithm ROUND_ROBIN --listener https-listener --protocol HTTP
openstack loadbalancer member create https-pool --address ${LB_BACKEND_IP_1} --protocol-port 80
openstack loadbalancer member create https-pool --address ${LB_BACKEND_IP_2} --protocol-port 80
 
 
#
# Test
#
curl -I http://10.1.2.3
curl -I https://10.1.2.3
 
 
#
# Debug
#
openstack secret list
openstack loadbalancer list
openstack loadbalancer listener list --loadbalancer lb1
openstack loadbalancer member list http-pool
openstack loadbalancer amphora list
 
 
 
<strong]Links&lt;/strong&gt;&#10;https://docs.openstack.org/python-octaviaclient/latest/cli/index.html&#10;https://docs.openstack.org/mitaka/networking-guide/config-lbaas.html&#10;https://docs.openstack.org/octavia/latest/user/guides/basic-cookbook.html&#10;https://shreddedbacon.com/post/openstack-kolla/&#10;https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/13/html/networking_guide/sec-octavia

[/geshifilter-]