OpenStack Cloud Computing Cookbook
http://www.openstackcookbook.com/
Installing Rackspace Private Cloud using Chef Cookbooks
Posted by on February 4, 2014
What It Does
In this recipe we show you how to install Rackspace Private Cloud on 3 servers: 2 Controllers in HA and a Compute host.
Getting Ready
You will need
- a Chef server installed and configured
- 3 Servers (virtual or physical) running Ubuntu 12.04
Ensure you are on a client or server that has the Chef Client, knife, installed and configured to use your Chef Server.
How to do it…
#!/usr/bin/env bash
set -e
set -v
set -u
# This is a crude script which will deploy an openstack HA environment
# YOU have to populate the IP addresses for Controller 1 and 2 as well as
# The IP addresses for your compute nodes. Additionally you will need to
# Populate the VIP_PREFIX with the first three octets of your VIP addresses.
# You should run this script on the node that will become controller 1.
# Rabbit Password
RMQ_PW="Passw0rd"
# Rabbit IP address, this should be the host ip which is on
# the same network used by your management network
RMQ_IP="10.51.50.1"
# Set the cookbook version that we will upload to chef
COOKBOOK_VERSION="v4.2.1"
# SET THE NODE IP ADDRESSES
CONTROLLER1="10.51.50.1"
CONTROLLER2="10.51.50.2"
# ADD ALL OF THE COMPUTE NODE IP ADDRESSES, SPACE SEPERATED.
COMPUTE_NODES="10.51.50.3 10.51.50.4"
# This is the VIP prefix, IE the beginning of your IP addresses for all your VIPS.
# Note, This makes a lot of assumptions for your VIPS.
# The environment use .154, .155, .156 for your HA VIPS.
VIP_PREFIX="10.51.50"
# Make the system key used for bootstrapping self and others.
if [ ! -f "/root/.ssh/id_rsa" ];then
ssh-keygen -t rsa -f /root/.ssh/id_rsa -N ''
pushd /root/.ssh/
cat id_rsa.pub | tee -a authorized_keys
popd
fi
for node in ${CONTROLLER1} ${CONTROLLER2} ${COMPUTE_NODES};do
ssh-copy-id ${node}
done
apt-get update
apt-get install -y python-dev python-pip git erlang erlang-nox erlang-dev curl lvm2
pip install git+https://github.com/cloudnull/mungerator
RABBIT_URL="http://www.rabbitmq.com"
function rabbit_setup() {
if [ ! "$(rabbitmqctl list_vhosts | grep -w '/chef')" ];then
rabbitmqctl add_vhost /chef
fi
if [ "$(rabbitmqctl list_users | grep -w 'chef')" ];then
rabbitmqctl delete_user chef
fi
rabbitmqctl add_user chef "${RMQ_PW}"
rabbitmqctl set_permissions -p /chef chef '.*' '.*' '.*'
}
function install_apt_packages() {
RABBITMQ_KEY="${RABBIT_URL}/rabbitmq-signing-key-public.asc"
wget -O /tmp/rabbitmq.asc ${RABBITMQ_KEY};
apt-key add /tmp/rabbitmq.asc
RABBITMQ="${RABBIT_URL}/releases/rabbitmq-server/v3.1.5/rabbitmq-server_3.1.5-1_all.deb"
wget -O /tmp/rabbitmq.deb ${RABBITMQ}
dpkg -i /tmp/rabbitmq.deb
rabbit_setup
CHEF="https://www.opscode.com/chef/download-server?p=ubuntu&pv=12.04&m=x86_64"
CHEF_SERVER_PACKAGE_URL=${CHEF}
wget -O /tmp/chef_server.deb ${CHEF_SERVER_PACKAGE_URL}
dpkg -i /tmp/chef_server.deb
}
function CREATE_SWAP() {
cat > /tmp/swap.sh <<EOF
#!/usr/bin/env bash
if [ ! "\$(swapon -s | grep -v Filename)" ];then
SWAPFILE="/SwapFile"
if [ -f "\${SWAPFILE}" ];then
swapoff -a
rm \${SWAPFILE}
fi
dd if=/dev/zero of=\${SWAPFILE} bs=1M count=1024
chmod 600 \${SWAPFILE}
mkswap \${SWAPFILE}
swapon \${SWAPFILE}
fi
EOF
cat > /tmp/swappiness.sh <<EOF
#!/usr/bin/env bash
SWAPPINESS=\$(sysctl -a | grep vm.swappiness | awk -F' = ' '{print \$2}')
if [ "\${SWAPPINESS}" != 60 ];then
sysctl vm.swappiness=60
fi
EOF
if [ ! "$(swapon -s | grep -v Filename)" ];then
chmod +x /tmp/swap.sh
chmod +x /tmp/swappiness.sh
/tmp/swap.sh && /tmp/swappiness.sh
fi
}
CREATE_SWAP
install_apt_packages
mkdir -p /etc/chef-server
cat > /etc/chef-server/chef-server.rb <<EOF
erchef["s3_url_ttl"] = 3600
nginx["ssl_port"] = 4000
nginx["non_ssl_port"] = 4080
nginx["enable_non_ssl"] = true
rabbitmq["enable"] = false
rabbitmq["password"] = "${RMQ_PW}"
rabbitmq["vip"] = "${RMQ_IP}"
rabbitmq['node_ip_address'] = "${RMQ_IP}"
chef_server_webui["web_ui_admin_default_password"] = "THISisAdefaultPASSWORD"
bookshelf["url"] = "https://#{node['ipaddress']}:4000"
EOF
chef-server-ctl reconfigure
sysctl net.ipv4.conf.default.rp_filter=0 | tee -a /etc/sysctl.conf
sysctl net.ipv4.conf.all.rp_filter=0 | tee -a /etc/sysctl.conf
sysctl net.ipv4.ip_forward=1 | tee -a /etc/sysctl.conf
bash <(wget -O - http://opscode.com/chef/install.sh)
SYS_IP=$(ohai ipaddress | awk '/^ / {gsub(/ *\"/, ""); print; exit}')
export CHEF_SERVER_URL=https://${SYS_IP}:4000
# Configure Knife
mkdir -p /root/.chef
cat > /root/.chef/knife.rb <<EOF
log_level :info
log_location STDOUT
node_name 'admin'
client_key '/etc/chef-server/admin.pem'
validation_client_name 'chef-validator'
validation_key '/etc/chef-server/chef-validator.pem'
chef_server_url "https://${SYS_IP}:4000"
cache_options( :path => '/root/.chef/checksums' )
cookbook_path [ '/opt/chef-cookbooks/cookbooks' ]
EOF
if [ ! -d "/opt/" ];then
mkdir -p /opt/
fi
if [ -d "/opt/chef-cookbooks" ];then
rm -rf /opt/chef-cookbooks
fi
git clone https://github.com/rcbops/chef-cookbooks.git /opt/chef-cookbooks
pushd /opt/chef-cookbooks
git checkout ${COOKBOOK_VERSION}
git submodule init
git submodule sync
git submodule update
# Get add-on Cookbooks
knife cookbook site download -f /tmp/cron.tar.gz cron 1.2.6
tar xf /tmp/cron.tar.gz -C /opt/chef-cookbooks/cookbooks
knife cookbook site download -f /tmp/chef-client.tar.gz chef-client 3.0.6
tar xf /tmp/chef-client.tar.gz -C /opt/chef-cookbooks/cookbooks
# Upload all of the RCBOPS Cookbooks
knife cookbook upload -o /opt/chef-cookbooks/cookbooks -a
popd
# Save the erlang cookie
if [ ! -f "/var/lib/rabbitmq/.erlang.cookie" ];then
ERLANG_COOKIE="ANYSTRINGWILLDOJUSTFINE"
else
ERLANG_COOKIE="$(cat /var/lib/rabbitmq/.erlang.cookie)"
fi
# DROP THE BASE ENVIRONMENT FILE
cat > /opt/base.env.json <<EOF
{
"name": "RCBOPS_Openstack_Environment",
"description": "Environment for Openstack Private Cloud",
"cookbook_versions": {
},
"json_class": "Chef::Environment",
"chef_type": "environment",
"default_attributes": {
},
"override_attributes": {
"monitoring": {
"procmon_provider": "monit",
"metric_provider": "collectd"
},
"enable_monit": true,
"osops_networks": {
"management": "${VIP_PREFIX}.0/24",
"swift": "${VIP_PREFIX}.0/24",
"public": "${VIP_PREFIX}.0/24",
"nova": "${VIP_PREFIX}.0/24"
},
"rabbitmq": {
"cluster": true,
"erlang_cookie": "${ERLANG_COOKIE}"
},
"nova": {
"config": {
"use_single_default_gateway": false,
"ram_allocation_ratio": 1.0,
"disk_allocation_ratio": 1.0,
"cpu_allocation_ratio": 2.0,
"resume_guests_state_on_host_boot": false
},
"network": {
"provider": "neutron"
},
"scheduler": {
"default_filters": [
"AvailabilityZoneFilter",
"ComputeFilter",
"RetryFilter"
]
},
"libvirt": {
"vncserver_listen": "0.0.0.0",
"virt_type": "qemu"
}
},
"keystone": {
"pki": {
"enabled": false
},
"admin_user": "admin",
"tenants": [
"service",
"admin",
"demo",
"demo2"
],
"users": {
"admin": {
"password": "secrete",
"roles": {
"admin": [
"admin"
]
}
},
"demo": {
"password": "secrete",
"default_tenant": "demo",
"roles": {
"Member": [
"demo2",
"demo"
]
}
},
"demo2": {
"password": "secrete",
"default_tenant": "demo2",
"roles": {
"Member": [
"demo2",
"demo"
]
}
}
}
},
"neutron": {
"ovs": {
"network_type": "gre",
"provider_networks": [
{
"bridge": "br-eth2",
"vlans": "1024:1024",
"label": "ph-eth2"
}
]
}
},
"mysql": {
"tunable": {
"log_queries_not_using_index": false
},
"allow_remote_root": true,
"root_network_acl": "127.0.0.1"
},
"vips": {
"horizon-dash": "${VIP_PREFIX}.156",
"keystone-service-api": "${VIP_PREFIX}.156",
"nova-xvpvnc-proxy": "${VIP_PREFIX}.156",
"nova-api": "${VIP_PREFIX}.156",
"cinder-api": "${VIP_PREFIX}.156",
"nova-ec2-public": "${VIP_PREFIX}.156",
"config": {
"${VIP_PREFIX}.156": {
"vrid": 12,
"network": "public"
},
"${VIP_PREFIX}.154": {
"vrid": 10,
"network": "public"
},
"${VIP_PREFIX}.155": {
"vrid": 11,
"network": "public"
}
},
"rabbitmq-queue": "${VIP_PREFIX}.155",
"nova-novnc-proxy": "${VIP_PREFIX}.156",
"mysql-db": "${VIP_PREFIX}.154",
"glance-api": "${VIP_PREFIX}.156",
"keystone-internal-api": "${VIP_PREFIX}.156",
"horizon-dash_ssl": "${VIP_PREFIX}.156",
"glance-registry": "${VIP_PREFIX}.156",
"neutron-api": "${VIP_PREFIX}.156",
"ceilometer-api": "${VIP_PREFIX}.156",
"ceilometer-central-agent": "${VIP_PREFIX}.156",
"heat-api": "${VIP_PREFIX}.156",
"heat-api-cfn": "${VIP_PREFIX}.156",
"heat-api-cloudwatch": "${VIP_PREFIX}.156",
"keystone-admin-api": "${VIP_PREFIX}.156"
},
"glance": {
"images": [
],
"image": {
},
"image_upload": false
},
"osops": {
"do_package_upgrades": false,
"apply_patches": false
},
"developer_mode": false
}
}
EOF
# Upload all of the RCBOPS Roles
knife role from file /opt/chef-cookbooks/roles/*.rb
knife environment from file /opt/base.env.json
# Build all the things
knife bootstrap -E RCBOPS_Openstack_Environment -r role[ha-controller1],role[single-network-node] ${CONTROLLER1}
knife bootstrap -E RCBOPS_Openstack_Environment -r role[ha-controller2],role[single-network-node] ${CONTROLLER2}
for node in ${COMPUTE_NODES};do
knife bootstrap -E RCBOPS_Openstack_Environment -r role[single-compute] ${node}
done