Posts Tagged ‘netscaler’

NetScaler fun with OpenStack keys and userdata

April 17, 2016

One of the things that’s been bugging me about NetScaler and OpenStack is the lack of basic integration. Its management network is configured via DHCP on first boot, or via config drive and userdata if DHCP is not available, but it doesn’t import SSH keys or runs userdata scripts for its initial configuration.

Thankfully, the above limitation maybe easily alleviated using the nsbefore.sh and nsafter.sh boot-time configuration backdoors. Here is a sample nsbefore.sh, based on the OpenStack docs, for VPX that can handle import of SSH keys:

root@ns# cat /nsconfig/nsbefore.sh
#!/usr/bin/bash
# Fetch public key using HTTP
ATTEMPTS=10
FAILED=0
while [ ! -f /nsconfig/ssh/authorized_keys ]; do
  curl -f http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key > /tmp/metadata-key 2>/dev/null
  if [ $? -eq 0 ]; then
    cat /tmp/metadata-key >> /nsconfig/ssh/authorized_keys
    chmod 0600 /nsconfig/ssh/authorized_keys
    rm -f /tmp/metadata-key
    echo "Successfully retrieved public key from instance metadata"
    echo "*****************"
    echo "AUTHORIZED KEYS"
    echo "*****************"
    cat /nsconfig/ssh/authorized_keys
    echo "*****************"
  else
    FAILED=`expr $FAILED + 1`
    if [ $FAILED -ge $ATTEMPTS ]; then
      echo "Failed to retrieve public key from instance metadata after $FAILED attempts, quitting"
      break
    fi
    echo "Could not retrieve public key from instance metadata (attempt #$FAILED/$ATTEMPTS), retrying in 5 seconds..."
    ifconfig 0/1
    sleep 5
  fi
done

Courtesy of the RedHat documentation a simple nsafter.sh that can retrieve and run a userdata is the following:

#!/usr/bin/bash

# Fetch userdata using HTTP
ATTEMPTS=10
FAILED=0
while [ ! -f /nsconfig/userdata ]; do
  curl -f http://169.254.169.254/openstack/2012-08-10/user_data > /tmp/userdata 2>/dev/null
  if [ $? -eq 0 ]; then
    cat /tmp/userdata >> /nsconfig/userdata
    chmod 0700 /nsconfig/userdata
    rm -f /tmp/userdata
    echo "Successfully retrieved userdata"
    echo "*****************"
    echo "USERDATA"
    echo "*****************"
    cat /nsconfig/userdata
    echo "*****************"
    /nsconfig/userdata
  else
    FAILED=`expr $FAILED + 1`
    if [ $FAILED -ge $ATTEMPTS ]; then
      echo "Failed to retrieve public key from instance metadata after $FAILED attempts, quitting"
      break
    fi
    echo "Could not retrieve public key from instance metadata (attempt #$FAILED/$ATTEMPTS), retrying in 5 seconds..."
    sleep 5
  fi
done

Simple enough. Now to put these to the test:

  1. Create a simple HEAT template
  2. # more template
    ################################################################################
    heat_template_version: 2015-10-15
    
    ################################################################################
    
    description: >
      Simple template to deploy a NetScaler with floating IP
    
    ################################################################################
    
    resources:
      testvpx:
        type: OS::Nova::Server
        properties:
          key_name: mysshkey
          image: NS_userdata
          flavor: m1.vpx
          networks:
            - network: private_network
          user_data_format: "RAW"
          user_data:
            get_file: provision.sh
    
      testvpx_floating_ip:
        type: OS::Neutron::FloatingIP
        properties:
          floating_network: external_network
    
      testvpx_float_association:
        type: OS::Neutron::FloatingIPAssociation
        properties:
          floatingip_id: { get_resource: testvpx_floating_ip }
          port_id: {get_attr: [testvpx, addresses, private_network, 0, port]}
    
  3. Import in Glance a NetScaler image with the above changes for nsbefore.sh and nsafter.sh; name it NS_userdata
  4. Create a simple test provisioning script
  5. # cat provision.sh
    #!/usr/bin/bash
    
    echo foo
    touch /var/tmp/foobar
    echo bar >> /var/tmp/foobar
    
    nscli -U :nsroot:nsroot add ns ip 172.16.30.40 255.255.255.0
    
  6. Create a stack and identify the NetScaler floating IP address
  7. # heat stack-create -f template vpx__userdata
    +--------------------------------------+------------------+--------------------+---------------------+--------------+
    | id                                   | stack_name       | stack_status       | creation_time       | updated_time |
    +--------------------------------------+------------------+--------------------+---------------------+--------------+
    | 540cb3d2-3b21-443c-a43b-10c745d28498 | vpx__userdata    | CREATE_IN_PROGRESS | 2016-04-17T16:49:49 | None         |
    +--------------------------------------+------------------+--------------------+---------------------+--------------+
    # # nova list | grep testvpx
    | 77388ebc-97e8-4a74-b863-40e822cb88c7 | vpx__userdata-testvpx-t3r3avxl7unc        | ACTIVE | -          | Running     | private_network=192.168.100.200, 10.78.16.139
    

This should be it. In order to verify everything went smoothly SSH into the instance using your private SSH key and run “sh ns ip” to verify that the provisioning script properly executed.

# ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i privatekey.pem nsroot@10.78.16.139
Warning: Permanently added '10.78.16.139' (RSA) to the list of known hosts.
###############################################################################
#                                                                             #
#        WARNING: Access to this system is for authorized users only          #
#         Disconnect IMMEDIATELY if you are not an authorized user!           #
#                                                                             #
###############################################################################

Last login: Sun Apr 17 16:51:06 2016 from 10.78.16.59
 Done
> sh ns ip
        Ipaddress        Traffic Domain  Type             Mode     Arp      Icmp     Vserver  State
        ---------        --------------  ----             ----     ---      ----     -------  ------
1)      192.168.100.200  0               NetScaler IP     Active   Enabled  Enabled  NA       Enabled
2)      172.16.30.40     0               SNIP             Active   Enabled  Enabled  NA       Enabled
Advertisements

Netscaler VPX: DHCP support

February 4, 2015

This is a quick recipe for enabling DHCP for your Netscaler VPX on KVM:

  1. Boot the KVM VPX instance per the instructions on the citrix site.
  2. Create /nsconfig/nsbefore.sh

  3. #!/bin/sh

    mkdir /var/db # to store lease files
    mkdir /var/empty
    /sbin/dhclient -l /var/db/dhclient.leases.1 0/1

  4. Create /nsconfig/nsafter.sh

  5. #!/bin/sh

    ADDR=`grep fixed-address /var/db/dhclient.leases.1 | awk '{print $NF}' | sed -e 's/;//' | uniq | tail -1`
    SUBNET=`grep subnet-mask /var/db/dhclient.leases.1 | awk '{print $NF}' | sed -e 's/;//' | uniq | tail -1`
    GATEWAY=`grep routers /var/db/dhclient.leases.1 | awk '{print $NF}' | sed -e 's/;//' | uniq | tail -1`

    grep "$ADDR" /nsconfig/ns.conf
    if [ $? != 0 ]; then
    nscli -U :nsroot:nsroot "set ns config -IPAddress $ADDR -netmask $SUBNET"
    nscli -U :nsroot:nsroot "savec"
    sleep 5
    yes | nscli -U :nsroot:nsroot "reboot"
    fi

    grep "$GATEWAY" /nsconfig/ns.conf

    if [ $? != 0 ]; then
    nscli -U :nsroot:nsroot "add route 0.0.0.0 0.0.0.0 $GATEWAY"
    nscli -U :nsroot:nsroot "savec"
    fi

  6. Power off your Netscaler VPX and save the disk image as a DHCP-enabled template.

Netscaler 10.x, XenServer 6.2 and Cloudstack

November 1, 2013

Quick tech note. After my Cloudstack testbed upgrade my Netscaler VMs no longer booted. The issue was similar to the one described in CTX135226 but affected both Netscaler 9.3 and 10.1 VMs.

After wasting a few good hours it turns out that this is caused by the presence of a DVD drive in the VM. The mere presence of a DVD drive, even if no ISO is loaded, somehow messes up with the Netscaler boot process under XenServer 6.2. The workaround is trivial:

  1. 1. Spot the DVD drive (hdd) using the vbd-list command

  2. # xe vbd-list vm-name-label=NetScaler\ Virtual\ Appliance
    uuid ( RO) : 5e218b95-68e9-37b2-860f-8b97678e2c02
    vm-uuid ( RO): ab229b8f-2b18-4931-b80b-30ab8265b843
    vm-name-label ( RO): NetScaler Virtual Appliance
    vdi-uuid ( RO): 5bcf6d76-1d2f-411a-9dd7-469aad0f86ae
    empty ( RO): false
    device ( RO): hdd

    uuid ( RO) : 9d6ff62c-93fa-3af5-b4b5-c5c66a0556e4
    vm-uuid ( RO): ab229b8f-2b18-4931-b80b-30ab8265b843
    vm-name-label ( RO): NetScaler Virtual Appliance
    vdi-uuid ( RO): 7b1fa1ff-7388-4e5a-8c67-00e4d943a470
    empty ( RO): false
    device ( RO): hda

  3. Destroy it

  4. # xe vbd-destroy uuid=5e218b95-68e9-37b2-860f-8b97678e2c02

  5. 3. Power on the Netscaler VM again; this time it should work like a charm

This is good enough if you have access to the XenServer running the VM. Not as good of a workaround for a Cloudstack environment which requires you to jump a few extra hoops. Specifically, if you are using XenServer you can update the StartAnswer method to selectively invoke the createVbd function in CitrixResourceBase.java: if the guest OS type evaluate the guest OS type matches “Other install media” and the disk type is ISO skip VBD creation. Here is the relevant sample code snippet:


public StartAnswer execute(StartCommand cmd) {
...
String guestOsTypeName = getGuestOsType(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD);
for (DiskTO disk : vmSpec.getDisks()) {
if (type == Volume.Type.ISO && gguestOsTypeName.toLowerCase().contains("other install media")) {
s_logger.debug("mperedim: skipping VBD creation");
} else {
createVbd(conn, disk, vmName, vm, vmSpec.getBootloader());
}
}
...

One can improve this workaround by mapping Netscaler VPXs to a dedicated OS template, so that DVD drives are still created for other VMs that get mapped to the “Other install media” XS template.