MinIO s3-compatible block storage on Windows Server 2019 and rclone snapshots
14 Jun 2020Using the Windows MinIO binary, I deploy s3-compatible storage on my Windows servers. I use erasure coding, striped across 4 (or more) directly attached drives. I can then configure rclone to sync/snapshot data to the object store.
I’ll usually run additional MinIO instances on the same sets of drives for separate security domains/different FQDNs, pointing each instance to a different folder on the disks. The below is an example configuration, using the minio-00
folder on each disk.
Grab latest MinIO binary, install it as a Windows Service, and allow network access
The MinIO deployment script1 is modified slightly to do erasure coding across 4 drives, H:, I:, J: and K: in this example.
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
Set-Location -Path $PSScriptRoot
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri "https://github.com/winsw/winsw/releases/download/v2.8.0/WinSW.NET4.exe" -OutFile "minio-service.exe"
Invoke-WebRequest -Uri "https://dl.min.io/server/minio/release/windows-amd64/minio.exe" -OutFile "minio.exe"
$config = @'
<service>
<id>MinIO</id>
<name>MinIO</name>
<description>MinIO is a high performance object storage server</description>
<executable>minio.exe</executable>
<env name="MINIO_ACCESS_KEY" value="minio"/>
<env name="MINIO_SECRET_KEY" value="123minio123"/>
<arguments>server H:\minio-00 I:\minio-00 J:\minio-00 K:\minio-00</arguments>
<logmode>rotate</logmode>
</service>
'@
Set-Content "minio-service.xml" $config
Start-Process -WorkingDirectory $PSScriptRoot -FilePath "$($PSScriptRoot)\minio-service.exe" -ArgumentList "install" -NoNewWindow -PassThru -Wait
Write-Host "Installation done"
New-NetFirewallRule -Program "$($PSScriptRoot)\minio.exe" -Action Allow -Profile Domain, Private, Public -DisplayName "MinIO" -Description "MinIO Server" -Direction Inbound
Powershell script to do health check on MinIO
Next, we deploy a PowerShell script that can be run locally, does an HTTP health check on MinIO, and restarts it if necessary. I’ve included some logging options here.
checkminio.ps1
$logFile = "$(gc env:COMPUTERNAME).checkMinio-00.log"
$healthURL = "http://localhost:9000/minio/health/ready"
$desiredStatusCode = 200
function LogWrite {
Param (
[string]$logString
)
$Stamp = (Get-Date).toString("yyyyMMdd HH:mm:ss ")
$Line = "$Stamp $logString"
if ($logFile) {
Add-Content $logFile -Value $Line
}
Else {
Write-Output $Line
}
}
function Get-URLStatusCode {
param(
[string]$url
)
Return (Invoke-WebRequest $url | % {$_.StatusCode})
}
function Restart-Service {
param(
[string]$serviceName
)
Stop-Service $serviceName
Start-Service $serviceName
Start-Sleep -s 10
}
$currentStatus = Get-URLStatusCode($healthURL)
Start-Transcript -Append $logFile
if ($currentStatus -ne $desiredStatusCode) {
Write-Output "Returned $currentStatus"
Get-Process -Name "Minio" | fl *
Write-Output "Restarting service..."
Restart-Service "MinIO"
Write-Output "Restart command issued and waited 10s."
}
$currentStatus = Get-URLStatusCode($healthURL)
Write-Output "Returned $currentStatus"
Get-Process -Name "Minio" | ft
Stop-Transcript
Now, create a Scheduled Task to run this script every 15 minutes
Drop the following commands into a PowerShell session to set up the Scheduled Task.
$action = New-ScheduledTaskAction -Execute 'Powershell.exe' `
-Argument '-NoProfile -WindowStyle Hidden -File "$($PSScriptRoot)\checkMinio.ps1"'
$trigger = New-ScheduledTaskTrigger -Daily -At 12am
$task = Register-ScheduledTask -TaskName "CheckMinio-00" -Description "Check Minio localhost:9000 and restart" -Trigger $trigger -Action $action
$task.Triggers.Repetition.Duration = "P1D"
$task.Triggers.Repetition.Interval = "PT15M"
$task | Set-ScheduledTask
Publish and add end-to-end monitoring
I then usually deploy an nginx proxy in front, with a letsencrypt certificate at https://fqdn.server.example.org, and then add end-to-end monitoring hitting https://fqdn.server.example.org/minio/health/ready and alert if it doesn’t return status code 200. Be sure to change the firewall configuration as appropriate.
Set up rclone backups
I had a Debian VM that I wanted to sync/snapshot some data from. I configured rclone as follows:
$ cat .config/rclone/rclone.conf
[fqdn-example-00]
type = s3
provider = Minio
env_auth = false
access_key_id = minio
secret_access_key = 123minio123
endpoint = fqdn.server.example.org
acl = private
Once rclone was configured, I ran a backup using:
$ rclone sync -P path/to/mydata fqdn-example-00:/path/to/mybackup
To schedule this as a cronjob, remove the -P
(show progress) switch from the above command.
-
https://github.com/minio/minio-service/blob/master/windows/install-service.ps1 ↩