VMware Horizon Community
Najtsob
Enthusiast
Enthusiast

Replicating appstack between DCs

I was reading documentation about appstacks and non-attachable storage, but I still don't really know how to move appstack between DCs. If I have FC storage then I can not present a lun to both datacentres that are on different continents with only IP connectivity.
So I guess that you need some storage which support array level replication over IP so you basically have non-attachable storage LUN that is in each DC presented from local array.

Other two options that comes to mind are:

- use some SW like veeam and replicate appstack VMDKs. Can you even replicate VMDKs that are not part of a VM ?

- use some VM where you do NFS export which is then mounted on vsphere in both DCs. This is questionable how would NFS datastore work over something like 200ms latency.

Any better ideas ?

7 Replies
andiwe79
Enthusiast
Enthusiast

I did not try it yet but maybe this could help: App Volumes Backup Utility

Best regards

Andi

0 Kudos
techguy129
Expert
Expert

For backup purposes, we use NFS to copy the files between datastores. You can probably do the samething in your scenario.

Other possible solutions for you:

Take a look at Storage groups within App Volumes

App Volumes: Storage Migration for AppStacks - VMware Blogs

You can also manually copy them:

Manually Copying an App Volumes AppStack | VMware End-User Computing Blog

Najtsob
Enthusiast
Enthusiast

This looks more like one time migration, I need to regularly copy appstack from one DC to the next so we do not have to do packaging process twice.

Answer to this seems to be storage groups and non-attachable storage which server as a swing lun between DCs, as per vmware refrence arhitecture guide. Only problem is that this non-attachable datastore must be presented on both DCs which is only feasible if you have them relatively close and well connected.

0 Kudos
sjesse
Leadership
Leadership

IF you want try the follow powershell

Get-Module –ListAvailable VM* | Import-Module

function sendMail{

       param([string]$errorMessage)

     Write-Host "Sending Email"

     #SMTP server name

     $smtpServer = ""

     #Creating a Mail object

     $msg = new-object Net.Mail.MailMessage

     #Creating SMTP server object

     $smtp = new-object Net.Mail.SmtpClient($smtpServer)

     #Email structure

     $msg.From = ""

     $msg.To.Add("")

     $msg.subject = "Error Syncing Appvolumes"

     $msg.body = $errorMessage

     #Sending email

     $smtp.Send($msg)

}

function Recusive2VcenterDSCopy

{

    param([string]$ItemPath,

          [string]$TargetPath)

    $datastoreitems = Get-ChildItem -path $ItemPath

    foreach ($dsItem in $datastoreitems )

    {

        if($dsItem.ItemType -eq "Folder")

        {

            $foldername=$ItemPath+"\"+$dsItem.Name

            $targetfoldername=$TargetPath+"\"+$dsItem.Name

            $localname="C:\Scripts\appvolsync\"+$dsItem.Name

            Write-Host "Looking in " $foldername " for things to copy"

            if(!(Test-Path $TargetPath))

            {

            try{

                Copy-DatastoreItem -Item $foldername -Destination $localname -ErrorAction Stop

            }catch{

        switch -wildcard ($error[0].Exception.ToString().ToLower())

        {

        "*already exists*" {Write-Output "File Already Exists"}

        default {

                        sendMail($error[0].Exception.ToString().ToLower())

                    }

        }

            }

            try{

                Copy-DatastoreItem -Item $localname -Destination $TargetPath -ErrorAction Stop

            }catch{

        switch -wildcard ($error[0].Exception.ToString().ToLower())

        {

        "*already exists*" {Write-Output "File Already Exists"}

        default {

                        sendMail($error[0].Exception.ToString().ToLower())

                    }

        }

            }

            Remove-Item $localname -recurse

            }

           

            Recusive2VcenterDSCopy -ItemPath $foldername -TargetPath $targetfoldername

        }else{

            $foldername=$ItemPath+"\"+$dsItem.Name

            $targetfoldername=$TargetPath+"\"+$dsItem.Name

            $localname="C:\Scripts\appvolsync\"+$dsItem.Name

            $remoteFile=$TargetPath+"\"+$dsItem.Name

            if(!(Test-Path $remoteFile))

            {

            Write-Host $remoteFile "Does not Exist"

            try{

            Copy-DatastoreItem -Item $foldername -Destination C:\Scripts\appvolsync\ -ErrorAction Stop

            }catch{

        switch -wildcard ($error[0].Exception.ToString().ToLower())

        {

        "*already exists*" {Write-Output "File Already Exists"}

        default {

                        sendMail($error[0].Exception.ToString().ToLower())

                    }

        }

            }

            try{

            Copy-DatastoreItem -Item $localname -Destination $TargetPath -ErrorAction Stop

            }catch{

        switch -wildcard ($error[0].Exception.ToString().ToLower())

        {

        "*already exists*" {Write-Output "File Already Exists"}

        default {

                        sendMail($error[0].Exception.ToString().ToLower())

                    }

        }

            }

                        Remove-Item $localname -recurse

            }

        }

       

    }

}

$productionVCenter=Connect-VIServer -Server sourcevcenter

$recoveryVCenter=Connect-VIServer -Server destvcenter

Import-Csv "C:\scripts\appvolsync\appvolsynccfg.csv" -UseCulture | %{

    $productionDatastore=Get-Datastore -Server $productionVCenter -Name $_."PDC"

    $recoveryDatastore=Get-Datastore -Server $recoverVCenter -Name $_."SDC"

    if(!(Test-Path pds:\))

    {

        New-PSDrive -Location $productionDatastore -Name pds -PSProvider VimDatastore -Root "\"

    }

    if(!(Test-Path rds:\))

    {

        New-PSDrive -Location $recoveryDatastore -Name rds -PSProvider VimDatastore -Root "\"

    }

    Recusive2VcenterDSCopy -ItemPath "pds:\cloudvolumes" -TargetPath "rds:\cloudvolumes"

    remove-psdrive -name pds

    remove-psdrive -name rds

}

    sendMail("Completed Appvolumes Sync")

Disconnect-VIServer -Server $productionVCenter

Disconnect-VIServer -Server $recoveryVCenter

and then create a csv with the first column being the source datastore and the second one being the destination datastore. This will copy everything and not need the nfs datastores which we decided not to use. Its the only reliable way I could think of to replicate the VMs without using the storage groups like other people mentioned.

sjesse
Leadership
Leadership

To clarify a bit more basically it just downloads one file at a time and then uploads it in the target datastore in the destination datacenter. The only downfall is the appstacks become thin provisioned.

0 Kudos
Najtsob
Enthusiast
Enthusiast

After all we will probably go with array level replicated LUN. Scripted solutions are fine for a one time job or to do it from time to time, but we would need to move quite a lot of appstacks.

It would be really great if the App volume manager itself could do the replication/copying of the appstack without using datastore.

EDIT:

Is it possible to utilize vSphere Content Libraries to copy appstacks from one DC to another ?

0 Kudos
HussamRabaya
VMware Employee
VMware Employee

technically and some how  it do that within the same cluster but for a cross data centers you need away to make the App volume manager see the datastore and that why you need NFS or ISCSI in order to map data store from site to site

0 Kudos