Openstack instance resize

Short version for demo environment:

Change the following values in nova.conf:

allow_resize_to_same_host=true
resize_confirm_window=5

Then, restart nova: openstack-service restart nova

Long version for multi compute node environment:

Add a bash to your nova users on each host:

usermod -s /bin/bash nova

Allow SSH without password between all your hosts under the “nova” user:

cat << EOF > ~/.ssh/config
Host *
    StrictHostKeyChecking no
    UserKnownHostsFile=/dev/null
EOF

When your migration is failing, you can reset the state of a instance using the following command:

nova reset-state --active

More details about the second procedure on this blog:
http://funcptr.net/2014/09/29/openstack-resizing-of-instances/

Cloud-init script examples for Cloudforms

Example #1 (tested on Openstack) – Simple script to register a VM to Satellite 6 and IdM. Also allow root login without key and setting password to “password123”

#cloud-config
# vim:syntax=yaml
debug: True
ssh_pwauth: True
disable_root: false
chpasswd:
  list: |
    root: password123
  expire: false
runcmd:
- sed -i'.orig' -e's/without-password/yes/' /etc/ssh/sshd_config
- service sshd restart
- yum -y localinstall http://satellite6.home.marcoberube.com/pub/katello-ca-consumer-latest.noarch.rpm >> /root/cloudinit.log
- subscription-manager register --org MarcoBerube --activationkey rhel7-basic >> /root/cloudinit.log
- yum -y install ipa-client >> /root/cloudinit.log
- ipa-client-install --enable-dns-updates --mkhomedir -p admin -w password123 --unattended >> /root/cloudinit.log
- yum -y install katello-agent >> /root/cloudinit.log
- yum -y update && yum clean all >> /root/cloudinit.log
- systemctl enable goferd.service >> /root/cloudinit.log
- yum -y install puppet >> /root/cloudinit.log
- echo server=satellite6.yourdomain.com >> /etc/puppet/puppet.conf
- systemctl enable puppet >> /root/cloudinit.log
- systemctl restart puppet >> /root/cloudinit.log
- reboot

Example #2 (tested on AWS) – This example shows how to pass arguments from Cloudforms to your cloud-init script dynamically.

#cloud-config
# MiqProvisionAmazon_Web.yaml
# CloudForms - Cloud-Init Script for Apache Installation on EC2
# For troubleshooting check: /var/lib/cloud/instance/user-data.txt & /var/log/boot.log

<%   # Set Global Variables   
    role                = evm[:role]   
    role                ||= evm[:ws_values][:role] rescue 'web'   
    instance_name       = evm[:vm_target_name]   
    key_pair            = evm[:keypair]   
    key_pair            ||= evm[:ws_values][:keypair] rescue nil %>

bootcmd:
  ## Turn off SELinux
  - setenforce 0

ssh_authorized_keys:
    <% if key_pair.nil? %>
  - echo "WARN --: Using default key pari"
    <% else %>
  - <%=key_pair%>
    <% end %>

runcmd:
  ## Setup motd and root authorized keys
  - echo Welcome to Red Hat CloudForms <%=role.titlecase%> Instance <%=instance_name%> > /etc/motd

  ## Turn off firewall
  - echo "CloudForms - Turning off firewall"
  - chkconfig iptables off  
  - service iptables stop

  ## Install Apache
  - echo "CloudForms - Installing apache"
  - yum -y install httpd wget
  - service httpd start
  - chkconfig httpd on

  ## Modify default apache homepage
  - echo "CloudForms - Modifyig default apache homepage"
  - sed -i 's/Red Hat Enterprise Linux.  Welcome to Red Hat CloudForms <%=role.titlecase%> Instance <%=instance_name%>/' /var/www/error/noindex.html

Installing Openstack offline

I recently needed to install Openstack in lab environments with very limited or no internet connectivity.  This is also a very fast way to install multiple nodes without having to download packages from the internet on each individual server.  So even if you have internet connection in your lab, it might be worth doing this to save time.   Once your repos are local, a packstack install is REALLY fast!!!

Here is how I did it:

1.  Download all the packages on a server with internet connectivity:

subscription-manager register
subscription-manager subscribe --pool=[your_pool_id]

(you can find your pool ID by running:   subscription-manager list –available –all)
Then, enable all the channels that you will want to download. For Red Hat Enterprise Linux Openstack 6 (Juno), you will need the following repos:

subscription-manager repos --enable rhel-7-server-rpms --enable rhel-7-server-openstack-6.0-rpms

Once you have all the channels you want enabled, sync these channels locally. In my example here, I will later provide my packages from this server over HTTP, so I will right away download my packages in my html folder under ./repos.

yum install yum-utils httpd
reposync --gpgcheck -lnm --repoid=rhel-7-server-rpms --download_path=/var/www/html/repos
reposync --gpgcheck -lnm --repoid=rhel-7-server-openstack-6.0-rpms --download_path=/var/www/html/repos

You could also backup these packages and move them to any other server to deliver them over HTTP from an internal web server. Once your packages are in the right location, create your repos using the following commands:

yum install createrepo

Copy your file in /var/www/html/repos (if you are moving them to a different server)

createrepo -v /var/www/html/repos/rhel-7-server-rpms
createrepo -v /var/www/html/repos/rhel-7-server-openstack-6.0-rpms

Finally, to use these repos from your servers on your internal network (without internet access), add the following configuration file: /etc/yum.repos.d/local.repo

[rhel-7-server-rpms]
name = Red Hat Enterprise Linux 7 Server (RPMs)
baseurl = http://--your_web_server_ip--/repos/rhel-7-server-rpms
enable = 1
gpgcheck = 0
sslverify = 0
[rhel-7-server-openstack-6.0-rpms]
name = Red Hat Enterprise Linux 7 Server (RPMs)
baseurl = http://--your_web_server_ip--/repos/rhel-7-server-openstack-6.0-rpms
enable = 1
gpgcheck = 0
sslverify = 0

Test this out:

yum repolist
yum update -y
reboot
yum install openstack-packstack
.....

Refer to my openstack installation procedure from here.

You are good to go.  Obviously, there is much better solutions than this available like Satellite or Red Hat Openstack installer. But I know that sometimes when playing in labs, your laptop or very secured area, having an easy offline option can be very helpful.

Changing VMWare adapter type based on Template OS

Here is how you can customize your network adapter type in VMWare based on what OS is getting provisioned. In this example, Windows templates requires VMXNET3 adapters while Linux VMs requires E1000 adapter.

# Get provisioning object
prov = $evm.root["miq_provision"]
vm_template = prov.vm_template

# Changing Adapter type based on Template OS
if vm_template.operating_system[:product_name].downcase.include?('windows')
   $evm.log("info", "WINDOWS DETECTED: SETTING UP NETWORK INTERFACE TO VMXNET3")
   prov.set_network_adapter(0, { :network => "VM Network", :devicetype => "VirtualVmxnet3", :is_dvs => false})
else
   $evm.log("info", "SETTING UP NETWORK INTERFACE TO E1000")
   prov.set_network_adapter(0, { :network => "VM Network", :devicetype => "VirtualE1000", :is_dvs => false})
end

Network performance while using VXLAN or GRE

 

While using VXLAN, a header is added to all packets sent by your instances.  This information is required by this protocol for VXLAN to do his magic.  Same thing applies to GRE.  This can cause fragmentation (poor network performance) as your packets will be bigger than the default MTU of 1500.

To fix that problem, you can make your instances default interface MTU setting to 1400 instead of 1500.  This way, VXLAN header will not cause fragmentation anymore.  Here is how to do that:

This is achieved by dhcp server sending out 1400 MTU to instances as a dhcp option.

* Create file /etc/neutron/dnsmasq-neutron.conf with below content in it.

dhcp-option-force=26,1400

* Edit /etc/neutron/dhcp_agent.ini and add below.

dnsmasq_config_file=/etc/neutron/dnsmasq-neutron.conf

* Then kill all existing dnsmasq processes and restart dhcp-agent. Or reboot the network node.

# service neutron-dhcp-agent restart

Spin-up a new instance or reboot an existing instance. Verify that your network interface MTU setting is now 1400.

How to add multiple external networks for floating ips in Openstack

Using these latest packages, it’s possible to create multiple provider external networks on the same l3-agent node. Please follow below steps.
Assuming communication to first external network is via eth0 and second external network via eth1, you should have two external bridges configured and interfaces added to them upfront.

 # ovs-vsctl add-br br-ex
 # ovs-vsctl add-port br-ex eth0
 # ovs-vsctl add-br br-ex1
 # ovs-vsctl add-port br-ex1 eth1

If there are more than two external networks, create additional bridges, then add port associated with that external network to the bridge. It’s also possible to use vlan tagged interfaces to connect multiple external networks like eth0.100, eth0.101, eth0.102 and etc.
Then configure two physical networks in /etc/neutron/plugin.ini and map bridges accordingly.

 network_vlan_ranges = physnet1,physnet2
 bridge_mappings = physnet1:br-ex,physnet2:br-ex1
 Set external_network_bridge = to an empty value in /etc/neutron/l3-agent.ini
 # Name of bridge used for external network traffic. This should be set to
 # empty value for the linux bridge
 external_network_bridge =

This is required to use provider external networks, not bridge based external network where we will add external_network_bridge = br-ex
Create multiple external networks as flat networks and associate them correctly the configured physical_network.

 # neutron net-create public01 --provider:network_type flat --provider:physical_network physnet1 --router:external=True
 # neutron net-create public02 --provider:network_type flat --provider:physical_network physnet2 --router:external=True

Create subnets appropriately for each external network.
You will be able to set any external network from above as gateway for a virtual router and assign floating ips from that network to instances from the private networks connected to that router.
Note that if ml2 is used, the above parameters are still valid for plugin.ini. Additionally, one need to configure below parameters as well while ml2 is used.

 type_drivers = flat  #add flat to the existing list.
 flat_networks = physnet1,physnet2

While using provider external networks, traffic to/from external network flows through br-int. br-int and br-ex will be connected using veth pair int-br-ex and phy-br-ex. br-int and br-ex1 will be connected using veth pair int-br-ex1 and phy-br-ex1. This will be automatically created by neutron-openvswitch-agent based on the bridge_mappings configured earlier.
Below diagram show packet flow for multiple external network via br-int on network node. Note I have excluded packet flow to private tenant networks using gre or vxlan or vlan from the diagram deliberately to make it simple.

openstack-ex-br

Modifying an instance network interface configuration

Here is how you can migrate an instance to a new network or add a secondary interface to an existing instance.

Find the instance name that you want to modify:

nova list

List all interfaces attached to an instance:

nova interface-list <server>

Detach an interface from your instance:

nova interface-detach <server> <port_id> 

Find the netowork ID of where you would like to attach your new interface:

nova net-list

Attach a new network interface to your network ID

nova interface-attach --net-id <net_id> <server>

Voila!

Allowing Root Login with Cloud-init

By default, a RHEL cloud image will not allow you to SSH as root on our host.  You must use your SSH key and login as cloud-user.  That said, you can easily change this behavior my passing the following cloud-init yaml file:

#cloud-config
# vim:syntax=yaml
debug: True
ssh_pwauth: True
disable_root: false
chpasswd:
  list: |
    root:password
    cloud-user:password
  expire: false
runcmd:
- sed -i'.orig' -e's/without-password/yes/' /etc/ssh/sshd_config
- service sshd restart