High-Available File Share in Windows Azure using DFS

Windows Azure Storage provides a scalable, reliable and highly available service to manage relational as well as unstructured data in the cloud. In order to access your data you can either leverage the Storage REST API directly or use one of the available abstractions on top of it (e.g. the Management Portal, PowerShell Cmdlets, .NET Libraries, 3rd Party Tools, etc.). Windows Azure Blob Storage can be used to store binary data. Many existing applications have requirements in terms of accessing data on network shares using the SMB protocol in Windows. When migrating these applications to Windows Azure one option is to change the file access code to the native REST interface of Blob Storage. However, often the effort for changing an application is too high and customers are looking for a ‘lift & shift’ migration without having to change any of their code.

In order to achieve this in Windows Azure, the first solution coming to mind is running a dedicated Windows Server IaaS Virtual Machine (VM) configured with File Services to provide an SMB share to the application. The VM can mount one or more Data Disks and format them as NTFS drives. Windows Azure Data Disks are implemented as standard Windows VHD-Files stored in Windows Azure Blob Storage. Thus, a file server could host up to 16 TB of data when using spanned volumes. See http://msdn.microsoft.com/library/dn197896.aspx for information about how many data disks can be mounted to the different VM sizes in Windows Azure.

One caveat of this approach is that today there is no official SLA for single instance VMs in Windows Azure. If the hardware of the underlying physical server fails, or if the Hyper-V host gets patched and needs to be rebooted, the VM will go down as well which will affect availability of the file server and probably also the application. The recommended solution for achieving high availability in Windows Azure IaaS is running at least two VMs in an Availability Set. Placing instances in an Availability Set will put the machines into different fault and update domains, preventing them to go down at the same time. See http://www.windowsazure.com/en-us/manage/windows/common-tasks/manage-vm-availability/ for details about the concept of Availability Sets in Windows Azure. Using this approach, the platform will make sure that there will be always at least one VM serving file requests from a client.

So, how can we create a multi-instance file server environment that can function in the scenario above? Additionally, we have to consider that there is no concept of shared disk storage for read/write access with Windows Azure Data Disks, i.e. it is not possible to mount the same disk to more than one server. What we rather need is a ‘distributed’ file server architecture, consisting of multiple VMs having their own attached disks allowing for synchronization of data stored on these disks. Well, this is exactly what the Distributed File System (DFS) in Windows Server is all about. DFS basically consists of two major technologies: DFS Namespaces enable you to group shared folders on different file servers into a common namespace, so clients can access the distributed data using a common name and do not have to be aware of the actual location of the data. DFS Replication allows to keep folder content on different servers in sync using an efficient replication mechanism (Remote Differential Compression). Combining both technologies will allow us to implement a highly available file sharing architecture in Windows Azure.

The only thing to keep in mind with DFS is that the client connectivity design is not made for instant failover, rather for high availability and close targeting. You have to be aware that a DFS client will face a short time of share unavailability in case its current DFS instance goes down. The issue here is not even DFS but rather SMB trying to reconnect to the same instance (which makes perfectly sense in the case of temporary network outage). Tests with the setup described in this document showed a maximum of 90 seconds ‘failover’ time to the redundant instance with an average around 60 seconds. If you consider having an ‘outage’ of each instance once a month (i.e. two times 60 seconds), the resulting downtime would still completely be within the regular Windows Azure SLA limits for Compute (99.95%).

This document describes a deployment of a highly available file share environment based on DFS in Windows Azure. It does so with a walkthrough for the Windows Azure Portal and another walkthrough using PowerShell.

High-Level Design

The picture below shows the general architecture of the solution:

DFS High-Level Design

  • The DFS infrastructure is set up in a Windows Azure Virtual Network (VNET). All clients that want to access DFS file shares have to be deployed within this Virtual Network as well.
  • DFS requires Active Directory. In order to keep the footprint of the solution small DFS and Domain Services will be installed on the same instances.
  • Both DC instances are running DNS and will be configured as DNS servers in the VNET configuration.
  • In order to comply with the Windows Azure SLA the setup consists of two VMs within a single Availability Set.
  • DFS Replication is set up between the 2 instances in the Availability Set in order to be able to cope with one machine being unavailable (due to failure or host upgrade).
  • Both instances are configured as DFS Namespace servers in order to keep the namespace available in case of single instance unavailability.
  • We will set up a sample DFS folder that will target a file share on each of the instances. Shares will be hosted on a separate Data Disk on each server.
  • The clients of the DFS shares can be domain-joined as well as outside the domain.
  • Clients can be IaaS VMs or PaaS web or worker roles.

Walkthrough using the Portal

This section describes a step-by-step walkthrough in terms of how to set up a reliable, highly available SMB file share in Windows Azure based on DFS. You might have to adapt some of the DNS names below, as they might already be taken by somebody else.

If you prefer to work in PowerShell: I will post a second walkthrough using PowerShell Cmdlets on this blog soon.

Register DNS Servers

First, we need to register two DNS servers to handle name resolution within the virtual network. These DNS servers will be available for all machines deployed to the VNET. As the domain controllers (also hosting DNS) will be located in a dedicated subnet we can predict their IP addresses. The first IP address in a subnet will usually be xxx.xxx.xxx.4, the second will be xxx.xxx.xxx.5, and so on.

Note: this is not a guaranteed behavior and might change in the future. In any case, check the IP addresses of the two DNS servers after they have been created later on in the tutorial.

(1) In the Windows Azure Portal select New – Network Services – Virtual Network – Register DNS Server and use the following values:

  • Name: dns01
  • DNS Server IP Address: 10.1.1.4

(2) Select New – Network Services – Virtual Network – Register DNS Server again and use the following values in order to create the second DNS server:

  • Name: dns02
  • DNS Server IP Address: 10.1.1.5

image

Create a Virtual Network

In the next step we will create the Virtual Network for our DFS environment.

(1) Select New – Network Services – Virtual Network – Custom Create and use the following values:

  • Name: dfsvnet
  • Affinity Group: Create a new Affinity Group
  • Region: <pick a region of your choice>
  • Affinity Group Name: dfsag

image

(2) In Step 2 of the wizard, select the DNS servers (dns01 and dns02) created before. In this tutorial we will not create a VPN tunnel, so do not enable site-to-site or point-to-site connectivity.

image

(3) In step 3, specify the following values for the VNET address space and subnets:

  • Address Space: 10.0.0.0/8
  • Subnet 1:
  • Name: dfs
  • Starting IP/CIDR: 10.1.1.0/29
  • Subnet 2:
  • Name: main
  • Starting IP/CIDR: 10.2.1.0/16

image

(4) Finish the wizard and wait for the creation of the Virtual Network.

Create a Storage Account within the Affinity Group

Create a new storage account:

(1) Select New – Data Services – Storage – Quick Create and use the following values:

  • Name: hadfsstorage
  • Affinity Group: dfsag

Create the First VM

Now we will create the first VM that serves as domain controller, DNS server, DFS Namespace Server and DFS Replication Node. We will use the Windows Server 2012 R2 image from the gallery.

(1) Select New – Compute – Virtual Machine – From Gallery and use the following values:

  • Platform Image: Windows Server 2012 R2 Datacenter
  • Virtual Machine Name: dfs01
  • Size: Medium
  • New User Name: dfs
  • New Password/Confirm: _DFS0n@zure#

image

(2) In the Virtual Machine Configuration step, specify the following values:

  • Cloud Service: Create a new cloud service
  • Cloud Service DNS Name: dfsdemo.cloudapp.net
  • Virtual Network: dfsvnet
  • Subnet dfs (10.1.1.0/29)
  • Storage Account: hadfsstorage
  • Availability Set: Create an availability set
  • Availability Set Name: dfsavset

image

(3) Leave the default endpoints for RDP and Remote PowerShell, finish the wizard. Wait for the machine to get to the Running state.

(4) Make sure this VM has the IP address 10.1.1.4.

Attach a Data Disk to the First VM

Now we will attach an empty disk to the VM in order to

  • host the Active Directory database files and
  • host an example file share for DFS

Of course you can also attach a separate disk for the DFS data, but for the sake of simplicity we will use just one disk.

(1) In the Windows Azure Portal open the dashboard page of the dfs01 VM.

(2) Select Attach – Attach empty disk from the command bar.

(3) Specify a size of 5GB and create the disk.

(4) Connect to the VM dfs01 using RDP.

(5) Open Disk Management and Initialize the new disk.

(6) Create a simple volume. Make sure to perform a quick format. The new volume should have the F: drive letter.

Make the First VM a Domain Controller

The process of installing Active Directory in a Windows Azure VM has been described here at length, so this walkthrough will just mention the major steps to get there.

(1) Connect to the VM dfs01 using RDP.

(2) Install Active Directory Domain Services via the Server Manager (Add Roles and Features).

(3) Promote the server to a domain controller (leave all defaults unless noted below and ignore the warnings):

  • Deployment operation: Add a new forest
  • Root Domain Name: dfsdemo.com
  • DSRM Password: _DFS0n@zure#
  • Location of
    • AD DS database: F:\NTDS
    • Log files: F:\NTDS
    • SYSVOL: F:\SYSVOL

(4) The VM will reboot at the end of the installation.

Create the Second VM

Now we will create the second VM that also serves as a redundant domain controller, DNS server, DFS Namespace Server and DFS Replication Node. Use the same procedure as for the first machine with the following differences (the other values being identical):

  • Virtual Machine Name: dfs02
  • Cloud Service: dfsdemo (same as for dfs01)
  • Availability Set: dfsavset

It is very important to deploy this VM into the dfs subnet of the dfsvnet virtual network and into the same availability set as dfs01!

image

Attach a Data Disk to the Second VM

Attach an empty disk to the dfs02 VM the same as you did for dfs01 above.

Make the Second VM a Domain Controller and Join Domain

Now, we will join the dfsdemo domain and create a second domain controller as a backup for dfs01.

(1) Connect to the VM dfs01 using RDP.

(2) Install Active Directory Domain Services via the Server Manager (Add Roles and Features).

(3) Promote the server to a domain controller (leave all defaults unless noted below and ignore the warnings):

  • Deployment operation: Add a domain controller to an existing domain
  • Domain: dfsdemo.com
  • Credentials: dfsdemo\dfs
  • Site name: Default-First-Site-Name
  • DSRM Password: _DFS0n@zure#
  • Replicate from: dfs01.dfsdemo.com
  • Location of
    • AD DS database: F:\NTDS
    • Log files: F:\NTDS
    • SYSVOL: F:\SYSVOL

(4) The VM will reboot at the end of the installation.

Validation

Make sure the two VMs just created have the correct IP addresses. In order to do that open the dashboard of the dfsvnet virtual network and check if both machines dfs01 and dfs02 are listed with the correct IP addresses that you also specified as DNS servers in the VNET.

image

Also, you might want to check if both servers are listed as domain controllers in the Active Directory Users and Computers management snap-in.

Install DFS on the First VM

Now we are going to install DFS on the first VM and prepare it to host a file share.

(1) Connect to the VM dfs01 using RDP.

(2) Open the Add Roles and Features Wizard and select DFS Namespaces and DFS Replication from File and Storage Services.

image

(3) Finish installing the DFS roles.

(4) Create a domain user in Active Directory Users and Computers.

  • User logon name: dfsuser
  • Password: _DFS0n@zure#

(5) Create a directory called Shared on the F: drive.

(6) Create a share on this directory and give Read/Write access to the dfsuser user account.

image

(7) In case you are planning to expose DFS file shares to non domain-joined clients you have to configure DFS to use FQDN (fully qualified domain names) for referrals. If clients will be located within the same domain, the default NetBIOS names are sufficient. This setting has to be configured on the DFS server level and can only be defined via PowerShell. Open a PowerShell console and execute the following commands:

Set-DfsnServerConfiguration –ComputerName “dfs01” –UseFqdn $true
Stop-Service dfs; Start-Service dfs

Install DFS on the Second VM

Follow the same steps as in the previous chapter within an RDP session of dfs02, i.e. install DFS and create s share on the F: drive. Use the same user domain account dfsuser as above.

If you have configured dfs01 for FQDN referrals in the previous chapter, do the same for dfs02 like this:

Set-DfsnServerConfiguration –ComputerName “dfs02” –UseFqdn $true
Stop-Service dfs; Start-Service dfs

Configure DFS on the First VM

Now we will configure DFS on the first node dfs01.

(1) Open the DFS Management tool.

(2) From the Actions menu select New Namespace.

  • Namespace Server: dfs01
  • Namespace Name: dfsns
  • Namespace Type: Domain-based namespace

(3) Finish the wizard in order to create the namespace.

(4) Select the new namespace dfsdemo.com\dfsns.

(5) From the Actions menu select Add Namespace Server.

  • Namespace Server: dfs02

image

(6) Select the namespace dfsdemo.com\dfsns.

(7) From the Actions menu select New Folder.

  • Name: dfsshare
  • Add Folder Target: \\dfs01.dfsdemo.com\Shared
  • Add Folder Target: \\dfs02.dfsdemo.com\Shared

image

(8) When being asked if you want to create a replication group click Yes. Accept all defaults unless noted below:

  • Replication Group Name: dfsdemo.com\dfsns\dfsshare
  • Replicated Folder Name: dfsshare
  • Replication Eligibility:

image

  • Primary Member: dfs01
  • Topology: Full Mesh
  • Replication Group Schedule and Bandwidth: Replicate continuously, Full Bandwidth

(9) After the replication group has been created, the warning below is displayed. As the default replication schedule in Active Directory is 3 hours it might take some time for the configuration to be complete.

image

Check DFS Setup

After having set up the DFS environment let’s check if everything is configured properly.

(1) Connect to dfs01 via RDP.

(2) Open the DFS Management tool.

(3) Select the folder dfsshare.

(4) Check that there are two folder targets for dfsshare and that (in case you configured them with FQDNs) the value for their path is specified properly:

image

(5) Select the Replication tab.

(6) Make sure that there are two entries for the Replicated Folders as shown below. Also check the Replication Status.

image

(7) Select the replication group dfsdemo.com\dfsns\dfsshare.

(8) Make sure there are two replicated folders on the Membership tab.

image

(9) Select the Connections tab.

(10) Make sure there are two sending members configured as shown below:

image

(11) Select the Replicated Folders tab.

(12) Make sure dfsshare is shown as a replicated folder and its status is Published to Namespace:

image

(13) If everything is configured as shown above, we’re good to test our high available file share!

Check DFS Replication

Now let’s see if DFS replication works as designed. For this we will create a file in the shared folder within each of the DFS servers and check if these files are going to be replicated to the replication partner.

(1) Connect to dfs01 via RDP.

(2) Create a file FromDFS01.txt in the F:\Shared folder.

image

(3) Connect to dfs02 via RDP.

(4) Check if the file FromDFS01.txt has been replicated to the F:\Shared directory. If the file isn’t there, initial replication might not have been executed yet. It might take some time for the DCs to fully replicate their configuration (default replication interval in AD is 180 minutes).

  • Create a DFS Replication Health Report on dfs01 by right-clicking the dfsdemo.com\dfsns\dfsshare replication group and selecting Create Diagnostic Report. Accept all defaults and check the resulting report for a message ‘This member is waiting for initial replication for replicated folder dfsshare’.
  • In case initial replication has not yet been done, reboot both VMs dfs01 and dfs02 and see if that triggers replication (usually it should).
  • If the file still does not show up on dfs02 just wait. You might find some additional troubleshooting hints at http://support.microsoft.com/kb/975440/en-us.

(5) In dfs02, create a file FromDFS02.txt in the F:\Shared folder.

image

(6) Check if the file FromDFS02.txt has been replicated to the F:\Shared directory on dfs01.

Create a Client VM

In order to be able to test availability of our DFS file share we will create a client VM that will not be part of the dfsdemo.com domain. Note that domain-joining clients are also possible. Especially if you are planning to use the share from Platform-as-a-Service solutions (web or worker roles) typically those VMs would not be part of the domain. Still, the VM has to be deployed into the virtual network dfsvnet in order to be able to access the share.

(1) Select New – Compute – Virtual Machine – From Gallery and use the following values:

  • Platform Image: Windows Server 2012 Datacenter
  • Virtual Machine Name: dfsclient
  • Size: Small
  • New User Name: dfs
  • New Password/Confirm: _DFS0n@zure#

image

(2) In the Virtual Machine Configuration step, specify the following values:

  • Cloud Service: Create a new cloud service
  • Cloud Service DNS Name: dfsclient.cloudapp.net
  • Virtual Network: dfsvnet
  • Subnet main (10.2.1.0/16)
  • Storage Account: hadfsstorage
  • Availability Set: (None)

(3) Leave the default endpoints for RDP and Remote PowerShell, finish the wizard. Wait for the machine to get to the Running state.

Test DFS share availability

Now we have all pieces in place in order to test high availability of the DFS share. We will access the share from the dfsclient VM. In order to check the ongoing availability of the share we will access the share content from a PowerShell script using a loop:

(1) Connect to dfsclient via RDP.

(2) Open the Windows PowerShell ISE environment.

(3) Create a new PowerShell script and save it as CheckShare.ps1.

(4) Insert the following script into the new file:

while($true)
{
Get-ChildItem -path
\\dfsdemo.com\dfsns\dfsshare

(Get-Date).DateTime
sleep -Seconds 1
}

(5) Run the script and check its output. It will list the share content once every second combined with the current date & time.

image

(6) If you like you can create new files on the DFS share from the client and check if they are replicated to both dfs01 and dfs02.

(7) Now we will simulate an outage of the first DFS instance. Go to the Windows Azure Management Portal, select the dfs01 VM and click on Shutdown in the command bar.

  • This should make the dfs02 instance take over all requests for the DFS share.
  • Observe the output of the PowerShell script on dfsclient.
  • Eventually the script will stop to output the share content every second for a short period of time as shown below and then continue.

image

(8) Start the VM dfs01 up again from the Management Portal and wait for it to come up.

(9) Now do the same for dfs02, i.e. shut it down via the Portal.

  • This should make the dfs01 instance take over all requests for the DFS share.
  • Observe the output of the PowerShell script on dfsclient.
  • The behavior should be similar as described above.

That’s it. We just built a high available file share in Windows Azure that can be used by clients within or outside the domain, and running in PaaS or IaaS workloads. You can deploy more servers and add namespaces and replication groups or attach additional disks in order to increase capacity of your shares. Depending on your requirements and on the load you are planning to impose on the DFS file server group, you might also be able to scale down your environment to run both instances as Extra Small VMs, which brings your cost down to less than $30 a month.

Leave a Reply

Your email address will not be published. Required fields are marked *