遠隔でMongoDBサーバのバックアップを取る2

 前回に構築したMongoDBサーバの自動遠隔バックアップシステムを削除し、新しくバックアップシステムを組んだ。今回はMongoDBサーバでバックアップコマンドを実行し、それをAzure Blob StorageにPythonでアップするという流れ。

backup.sh

#!/bin/sh
cd /home/h/backup
mongodump --host foo -u bar -p boo
tar zcvf dump.tar.gz dump
python3.5 /home/h/up.py
rm -rf *


up.py

from azure.storage.blob import BlockBlobService
import datetime

account = "xxx"
key = "yyy"
block_blob_service = BlockBlobService(account_name=account, account_key=key)
filename = datetime.datetime.now().strftime("%Y%m%d")
block_blob_service.create_blob_from_path("mongo", filename, "dump.tar.gz")



comment: 0

Azure Storageエミュレータのエミュレータを作ってみた

 開発環境で使うAzureのストレージエミュレータが、ローカルでしか使えなかったので、NginXでリバプロ対応する方法を書いた。
AzureStorageのエミュレータに外部(Dockerコンテナ)からコンニチワ
なんでローカルではなく外部から使いたかったかというと、アプリをDockerコンテナにするから、ストレージ部分はアプリをステートレスにするためにコンテナの外に締め出したかった。それが開発環境でも。

 NginXで、Windowsで動いてるエミュレータへリバプロを立てるより、そもそもエミュレータがこれまた一つのDockerコンテナアプリで動いてるほうが便利じゃね?と思った。思ったのち、「エミュレータはSQLServerで作ってあるよん」て情報を思い出したので、じゃあぼくはとASP.NET Core MVC + MongoDBで作ってみた。まだ簡単なPUTとGETの機能のみだが、公式のエミュレータ接続ライブラリでAPIを使って接続できるようになっている。
Sokyu: Azure Storage(Blob) Emulator
 データを格納するためのMongoDBをこのエミュレータと接続できるように置いた状態で、このエミュレータの接続設定をそいつへ向けて起動すれば動作する。そういうわけで、今のところ外部ストレージとしてMongoDBが必要。


 ためしにエミュレータを起動した状態で、C#の公式のライブラリでJPEGのPUTとGETを一つやってみる。
 まずPUTから。muscles.jpgというファイルを用意してPUTで投げる。
using Microsoft.WindowsAzure.Storage;

using Microsoft.WindowsAzure.Storage.Blob;

using System;
using System.IO;
using System.Threading.Tasks;

namespace PlayAzureStorage
{
class Program
{
private static async Task FuncAsync()
{
var accountName = "devstoreaccount1";
var key = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
var connectionString = $"AccountName={accountName};"
+ $"AccountKey={key};"
+ $"BlobEndpoint=http://192.168.11.17:32782/devstoreaccount1;";

var account = CloudStorageAccount.Parse(connectionString);
Console.WriteLine("connect: " + account.BlobStorageUri);
var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("test");

var name = "muscles.jpg";
using (var stream = File.OpenRead(name))
{
var blockBlob = container.GetBlockBlobReference(name);
await blockBlob.UploadFromStreamAsync(stream);
Console.WriteLine("Uploaded.");
}
}

static void Main(string[] args)
{
FuncAsync().Wait();
}
}
}

問題なく動作していれば上記はエラーなく終了する。
 続いてGETで、今保存したmuscles.jpgを読みだしてみる。アクセス権限の機能はまだ実装していなので、ブラウザでお目当てのファイルのパスへアクセスすれば読み出せる。

comment: 0

AzureFileStorageのエミュレータにlocalhostじゃないIPを使ってコンニチワ

'17/9/21追記
IPを使っても、結局エミュレータにアクセスするマシンを仮想化で外に置いたら、エミュレータが使えなくなった。だから外の環境からエミュレータを使うのは無理かも。
********


Azure Storage Emulatorにコンテナ内からつなごうとして、結局リバースプロキシを立てた話

 少し前に、開発に使うAzureのストレージエミュレータがローカルからしか使えん、けどアプリはDockerコンテナにしたいから、Fiddlerでリバースプロキシするってのを書いた。書いておいて、やっぱFiddlerを開発の度に立ち上げるのもアレだなーと思ったので、一般的なサーバソフトで、まずはNginXで同じことをやってみることにした。今回は.NET CoreでC#によるエミュレータへの書き込み、ブラウザで書き込んだファイルの読み出しまでやる。

 .NET CoreのC#で、Azureのストレージエミュレータにアクセスして、適当なテキストファイルを書き込むコードを用意する。
using Microsoft.WindowsAzure.Storage;

using Microsoft.WindowsAzure.Storage.Blob;

using System;
using System.IO;
using System.Threading.Tasks;

namespace PlayAzureStorage
{
class Program
{
private static async Task Func2Async()
{
var accountName = "devstoreaccount1";
var key = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
var connectionString = $"AccountName={accountName};"
+ $"AccountKey={key};"
+ $"BlobEndpoint=http://192.168.11.17:20000/devstoreaccount1;";
//+ "BlobEndpoint=http://127.0.0.1:1000/devstoreaccount1;";

var account = CloudStorageAccount.Parse(connectionString);
Console.WriteLine("connect: " + account.BlobStorageUri);
var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("test");
var isCreated = await container.CreateIfNotExistsAsync();
if (isCreated)
{
var permissions = await container.GetPermissionsAsync();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
await container.SetPermissionsAsync(permissions);
}

var name = "foo.txt";
using (var stream = File.OpenRead(name))
{
var blockBlob = container.GetBlockBlobReference(name);
blockBlob.Properties.CacheControl = "public, max-age=2678400";
blockBlob.Properties.ContentType = "text/plain";
await blockBlob.UploadFromStreamAsync(stream);
Console.WriteLine("Uploaded.");
}
}


static void Main(string[] args)
{
Func2Async().Wait();
}
}
}

 適当なテキストファイルfoo.txtをプロジェクトに用意しておく。あと接続文字列にあるIPとポート番号は自分の環境に合ったもので。今回はリバプロで、ポート20000に来たものをポート10000に飛ばす。

 NginXを落としてきて、解凍したディレクトリ内にあるnginx.confをリバプロとして動作するように書き換える。その辺に転がってるリバプロサンプルを書き換えて、外部からのC#コードによる書き込みを実行したところ二度エラーが出た。一つはヘッダをもとのままになるように設定することで解決した。もう一つはNginXがデフォではHTTPのバージョンを1.0に書き換えてしまうためにエラーになったので、バージョン1.1で動くように設定。
 最終的に設定ファイルは下記のとおり。
nginx.conf

worker_processes 1;

events {
worker_connections 1024;
}

http {
sendfile on;

upstream app_servers {
server 127.0.0.1:10000;
}

server {
listen 20000;

location / {
proxy_pass http://app_servers;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
}
}

 nginx.confを用意したら、"start nginx"で起動しておく。

 まずストレージエミュレータを起動する。次に、用意しておいたC#コードを実行して、ストレージエミュレータへの書き込みを実行してみる。エラーなく処理が終了するはず。エラーが出てくる場合、Azureのライブラリがエラーを出すので、本来エミュレータから送られてくるエラーメッセージはそのままでは見られない。ここらはFiddlerを使ってキャプチャしておけば、デバッグに役立つ。


 ストレージエミュレータへの書き込みが成功したら、ブラウザからそのファイルを参照してみる。
http://192.168.11.17:20000/devstoreaccount1/test/foo.txt

成功。

 Azureを使ったWebアプリの開発をしたいが、その開発環境で使うストレージエミュレータがローカルからのアクセスしか受け付けないので、NginXでリバプロを立てて外部(Dockerのコンテナ内を想定)からのアクセスを受け付けるようにしてみた。うまくいった。
 しかしこれ、けっこうメンドウだったのでエミュレータがコンテナで用意できたらなーと思っている。
comment: 0