Quantcast
Channel: 銀の光と碧い空
Viewing all 283 articles
Browse latest View live

Visual Studio 2017 SDKでXAMLのモーダルダイアログを出す

$
0
0

Visual Studio 2017 SDKでメニューなどからモーダルダイアログを出す場合に、その画面をXAMLで作ることにします。

といってもDialogWindowクラスを使うと簡単にできます。

docs.microsoft.com

とりあえず、プロジェクトにWPFのユーザーコントロールアイテムあたりを適当に追加します。(あとからクラスを変更するので、なんでもよい)

で、XAML側を次のように変更します。Microsoft.VisualStudio.Shell.15.0というアセンブリにあるMicrosoft.VisualStudio.PlatformUI.DialogWindowを使うのがポイントです。Gridの中身はサンプルで入れてますが、なんでもよいです。

<platformUi:DialogWindow x:Class="MyVisualStudio.Vsix.Views.MyDialogWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:platformUi="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0"mc:Ignorable="d"WindowStartupLocation="CenterScreen"d:DesignHeight="450"d:DesignWidth="800"><Grid><TextBox HorizontalAlignment="Left"Height="23"Margin="191,88,0,0"TextWrapping="Wrap"VerticalAlignment="Top"Width="120"Text="{Binding Title.Value}"/><TextBox HorizontalAlignment="Left"Height="23"Margin="191,128,0,0"TextWrapping="Wrap"VerticalAlignment="Top"Width="120"Text="{Binding Message.Value}"/><Button Content="Button"HorizontalAlignment="Left"Margin="213,196,0,0"VerticalAlignment="Top"Width="75"Command="{Binding DeployCommand}"/></Grid></platformUi:DialogWindow>

コードビハインドも書き換えます。helpTopicという引数を取るコンストラクタをオーバーライドして、これを呼び出すとヘルプボタンが表示されて、指定した文字列でF1ヘルプが有効になるのですが、F1ヘルプにコンテンツを追加する方法がまだわからないので、とりあえずこういうのがあるという紹介だけ。

using Microsoft.VisualStudio.PlatformUI;

namespace MyVisualStudio.Vsix.Views
{

    publicpartialclass MyDialogWindow: DialogWindow
    {
        public MyDialogWindow()
        {
            InitializeComponent();
        }

        public MyDialogWindow(string helpTopic) : base(helpTopic)
        {
            InitializeComponent();
        }
    }
}

あとはダイアログを表示する場所でViewをインスタンス化して、ShowModalメソッドを呼べばOKです。

private void MenuItemCallback(object sender, EventArgs e)
{
    var dialog = new DeployToOpenShiftWindow();
    dialog.ShowModal();
}

以上です。


Azure VM のDiskのAttachとDetachをREST API経由でやってみる

$
0
0

AzureのLinux仮想マシンにDiskをAttach、DetachするのをAPIレベルの挙動で確認したかったので、REST APIを生で実行することにしました。

REST APIでは認証トークンが必要なのですが、まずはトークンを取得するためにサービスプリンシパルを作っておきます。Azure CLI 2.0で実行します。下のコマンドでは、リソースグループに対してContributorの権限を持つサービスプリンシパルを作ります。<resource_group_id>は最初のコマンドで表示されたidの値をいれ、それ以外の値は適宜置き換えてください。<app_name>は任意の名前です。

$ az group show -n<リソースグループ名>-o json
$ az ad sp create-for-rbac --name<app_name>--password<strong_password>--role contributor --scopes<resource_group_id>

あと、次の手順でテナントIDが必要なのでそれも取得しておきます。

$ az account show -o json

ここからはURLを直接たたくので、おすきなツールでどうぞ。Chrome拡張を使いました。まずは、認証トークンを取得します。このドキュメントの通りです。

docs.microsoft.com

つまり、https://login.microsoftonline.com/<tenantid>/oauth2/tokenというURLに対しapplication/x-www-form-urlencodedで次のような値を送信します。このあと帰ってきた値のaccess_tokenをメモしておきます。

client_id=<さっき作ったサービスプリンシパルのapp_id>
grant_type=client_credentials
client_secret=<さっき作ったサービスプリンスパルのパスワード>
resource=https://management.azure.com/

DiskのAttachとDetachですが、すべてVirtualMachineの更新というAPIを使います。

Create or update an Azure virtual machine | Microsoft Docs

まずURLは https://management.azure.com/subscriptions/<tenantid>/resourceGroups/<リソースグループ名>/providers/Microsoft.Compute/virtualMachines/<仮想マシン名>/?api-version=2016-04-30-previewで、HTTPヘッダーにContent-Type: application/jsonと認証用にAuthorization: Bearer <さっき取得したaccess_tokenの値>をセットして、PUTで送信します。送信するBodyの中身は、何も接続されていない状態から1つAttachする場合はこんな感じになります。

{"properties": {"storageProfile": {"dataDisks": [{"lun": <0とかLUNの値>,
                    "name": "<ディスクの名前>",
                    "createOption": "Attach",
                    "caching": "<Noneとか>",
                    "managedDisk": {"storageAccountType": "<Standard_LRSとか>",
                        "id": "<diskのリソースID>"
                    },
                    "diskSizeGB": <ディスクサイズ>
                }]}},
    "location": "<westus2とか>"
}

dataDisksに指定しているディスクの配列に仮想マシンにつながっているディスクを更新するので、最初の状態がわからない場合は、まずGETして、それに1つディスクを追加という形になります。 そして、ディスクを全部Detachする場合は送信するjsonだけ次のように変更します。

{"properties": {"storageProfile": {"dataDisks":[]}},
    "location": "<westus2とか>"
}

実際にAPIを実行するとわかるのですが、API自体は数秒程度でレスポンスがかえってきます。が、ディスクのAttach、Detach自体はそこから操作が完了するまで時間がかかります。特にDiskのDetachは数分かかることがあって、そのときはAttachを再度実行するときにエラーがかえってきて気づくことになります。

fluentd で AWS Elasticsearchに長い間つないでいると"Cannot get new connection from pool."というエラーが出る件について

$
0
0

本記事はQiitaに投稿していたものを、Qiitaのコミュニティガイドライン追加に伴い削除の可能性を考慮してこちらに移行しました。理由は、fluentdからElasticsearchにログを投げ込み処理は弊社のOpenShiftのログ収集機能で利用しているものであり、記事投稿が自社で利用している技術の宣伝がないかといわれれば否定できないためです。

先にまとめ

以下のすべての条件を満す時、"Cannot get new connection from pool."というエラーが、fluentd起動後しばらく(自分のテストしたときは1日弱)してから発生し、以後すべてのログの送信ができなくなる

詳細

問題の概要

fluentdを使ってAWS elasticsearchにログを転送していると、最初は問題なくログを送信できているのにしばらくすると突然"Cannot get new connection from pool.“というエラーを出して、以降毎回送信のたびに同じエラーで送信が全くできない問題が発生しました。同じ様な現象はGitHubのissueやフォーラムなどでも議論されていました。

これらの議論を読むと、AWS elasticsearchはmanagedなサービスで _nodes APIで通常返すはずのnodeのIP情報が含まれていないこと。そして、Elastic Search のRuby Clientは一定リクエストごとにnodeのIPを取得しなおしてコネクションの再生成をしたり通信失敗時に同様の処理を行ったりすることが指摘されていました。それらの機能は、fluent-plugin-elasticsearchのプラグインのreload_connectionsreload_on_failurefalseに設定すれば無効化でき(後者はデフォルトがfalse)、実際にその設定により解決したという報告もありました。しかし、その設定をしても変化がないという報告もあり、私も同じ現象に悩んでいました。

問題の追及

エラー発生時のスタックトレースから、エラーが発生するときはget_connectionnilを返しているはずで、それはコネクションのリロードがfalseに設定しているのに起きているはずではと考え色々デバッグしていました。

で、最終的に見つけた結論はRubyでは文字列の"false"はboolで評価されるとtrueになる、ということに起因する問題です。

irb(main):001:0> a = "false"
=> "false"
irb(main):002:0> "OUT"if a
=> "OUT"
irb(main):003:0> "OUT"iffalse
=> nil

Elasticsearch Ruby Clientでリロードするかどうかの部分はこういう判定になっています。

reload_connections!         if reload_connections && counter % reload_after == 0

https://github.com/elastic/elasticsearch-ruby/blob/v2.0.0/elasticsearch-transport/lib/elasticsearch/transport/transport/base.rb#L70

reload_connections というフィールドはこのように代入されており、FixNumであることが期待されています。

@reload_connections = options[:reload_connections]
@reload_after    = options[:reload_connections].is_a?(Fixnum) ? options[:reload_connections] : DEFAULT_RELOAD_AFTER

なのですが、Issueコメントによると無効化したければfalseを指定すればいいよと書いており、実際falseを渡せば完全に無効化される処理になります。

github.com

じゃあ、プラグイン側で設定ファイルにfalseと指定すれば動く気もして、実際プラグインでdynamic configurationを指定しなければ、期待通り動きます。これはreload_connectionsなどをboolとして渡しているからです。これが、ある人はこの設定を指定すれば動くようになったとコメントしている理由ではないかと考えています。 https://github.com/uken/fluent-plugin-elasticsearch/blob/v1.9.0/lib/fluent/plugin/out_elasticsearch.rb#L41-L42

ところがdynamic configuration を指定していると、設定パラメータはstring型になります。これは設定ファイルを式として評価するために一旦文字列として扱う必要があるから、が理由な気がします。 https://github.com/uken/fluent-plugin-elasticsearch/blob/v1.9.0/lib/fluent/plugin/out_elasticsearch_dynamic.rb#L15-L16

ちなみに設定ファイルに

reload_conncetoins "#{false}"

のように評価結果がfalseになる式を記述しても、評価結果が文字列になるものしかチェックしないせいか設定は無視され、デフォルトの文字列としての"true"や"false"が使われます。

いずれにしても、reload_conncetionsreload_on_failureは文字列型以外の値をとることなくElasticsearch Clientに渡され、文字列としてifの条件判定に使われるため、falseと設定ファイルに指定してもtrueと評価され、どこかのタイミングでreload_connections!が実行され、その瞬間にnodeのIPがとれずにconnectionsが空になり、以降のログ送信が全て失敗する、という問題が発生する流れな気がしています。なお、AWS固有の機能を追加している、 fluent-plugin-aws-elasticsearch-service でも同じコードを通るので、dynamic configuration をつかっていると同じ問題が発生します。

https://github.com/uken/fluent-plugin-elasticsearch/blob/v1.9.0/lib/fluent/plugin/out_elasticsearch_dynamic.rb#L250-L253https://github.com/uken/fluent-plugin-elasticsearch/blob/v1.9.0/lib/fluent/plugin/out_elasticsearch_dynamic.rb#L54-L55

コードを抜粋するとこんな感じです。Dynamic configurationの目的上、設定ファイルの値を文字列型として扱うのはしょうがないかなあという気がするので、クライアントに渡すところでboolに変換するのが解決策ではないでしょうか。

  config_param :reload_connections, :string, :default => "true"
  config_param :reload_on_failure, :string, :default => "false"#<snip>

      transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new(connection_options.merge(
                                                                          options: {
                                                                            reload_connections: @dynamic_config['reload_connections'],
                                                                            reload_on_failure: @dynamic_config['reload_on_failure'],
                                                                            resurrect_after: @dynamic_config['resurrect_after'].to_i,
                                                                            retry_on_failure: 5,
                                                                            transport_options: {
                                                                              request: { timeout: @dynamic_config['request_timeout'] },
                                                                              ssl: { verify: @dynamic_config['ssl_verify'], ca_file: @dynamic_config['ca_file'] }
                                                                            }
                                                                          }), &adapter_conf)

問題の解決と現状

というわけで、以下のPRを作成して、無事1.9.1としてマージしてもらいました。感謝!

github.com

fluent-plugin-elasticsearch | RubyGems.org | your community gem host

また、fluent-plugin-aws-elasticsearch-serviceでも同じ問題が起きる件に関しては、fluent-plugin-elasticsearchの最新版に依存するように指定しているのでパッケージしなおせば解決するはずですが作者からの反応がない状態です。あまりよくはないなあと思いつつ、hotfix版としてforkしたうえでruby gemsも作成しています。

github.com

fluent-plugin-aws-elasticsearch-service-hotfix | RubyGems.org | your community gem host

Visual Studio SDKで設定ページに任意のユーザーコントロールを配置する

$
0
0

Visual Studio SDKで設定ページを作る場合、Visual Studioのメニューのツール>オプションに自分のカテゴリを追加することができます。この追加したカテゴリよく見ると、デフォルトっぽい画面と自前で作っているっぽい画面の二種類あることがわかります。

デフォルトの例 f:id:tanaka733:20180211003416p:plain

自前の例 f:id:tanaka733:20180211003433p:plain

デフォルトの設定ページの作り方はドキュメントがあるので、自前の画面の作り方を説明します。

オプション ページを作成する | Microsoft Docs

使うクラスはMicrosoft.VisualStudio.Shell.UIElementDialogPageクラスです。このクラスの存在はこのブログを読んで知りました。実際にVS2017で使うにはいくつか足りないところがあったので補足しています。

haacked.com

これを継承した適当なクラスを作ります。

using Microsoft.VisualStudio.Shell;
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows;

namespace MyVisualStudio.Vsix.Options
{
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")] //GUIDは適当な値publicsealedclass MySetting : UIElementDialogPage
    {
        privatereadonly MyViewModel viewModel;
        privatereadonly MyView view;

        protectedoverride UIElement Child => view;

        public OpenShiftMasterEndpointSetting()
        {
            viewModel = new MyViewModel();
            view = new MyView
            {
                DataContext = viewModel
            };
        }

        publicoverridevoid LoadSettingsFromStorage()
        {
            //ここを同期的に完了を待ったほうがいいかどうかは謎
            viewModel.LoadAsync().GetAwaiter().GetResult();
            base.LoadSettingsFromStorage();
        }

        protectedoverridevoid OnClosed(EventArgs e)
        {
            //設定画面でキャンセルが押されたときなど。//保存に失敗したとか、未保存状態のときにクローズをキャンセルする手はありそうbase.OnClosed(e);
        }

        publicoverridevoid SaveSettingsToStorage()
        {
            //保存処理
            viewModel.SaveAsync().GetAwaiter().GetResult();
            base.SaveSettingsToStorage();
        }

        publicoverridevoid ResetSettings()
        {
            base.ResetSettings();
        }

        protectedoverridevoid OnActivate(CancelEventArgs e)
        {
            //設定ダイアログで該当カテゴリに移動したときbase.OnActivate(e);
        }

        protectedoverridevoid OnDeactivate(CancelEventArgs e)
        {
            //設定ダイアログで該当カテゴリから移動するときbase.OnDeactivate(e);
        }
    }
}

Childプロパティを継承して自前のユーザーコントロールのインスタンスを返すようにします。この例では、ViewModelもこのクラスが参照を持っていますが、その辺はお好きに。設定データの読み込みと保存はLoadSettingsFromStorageSaveSettingsToStorageメソッドをオーバーライドして行います。なんとなく処理の完了を待機した方がいいのでしていますが、あまり自信はないです。

次にVisual Studio SDKプロジェクトを作ったときのPackageクラスの属性に次のように設定のカテゴリ、ページ名を追加します。

    [ProvideOptionPage(typeof(MySetting ), "MySettingCategory", "MySettingPage", 0, 0, true)]
    publicsealedclass MyVSPackage : Package

あとは、適当にViewとViewModelを渡せばいいわけですが、保存処理についてです。自前で適当なところに保存してもいいのでしょうが、今回はMicrosoft.VisualStudio.Settings.WritableSettingsStoreクラスを使いました。最初に紹介したブログによるとVSIXをバージョンアップしても設定をきちんと保持できるとあるので、今度検証してみましょう。WritableSettingsStoreはいくつかのプリミティブなオブジェクトしか保存するメソッドを用意していないので、今回は安易にJSONに変換して保存いています。

using Microsoft.VisualStudio.Settings;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Settings;
using Newtonsoft.Json;
using Reactive.Bindings;
using System;
using System.Diagnostics;
using System.Linq;

namespace MyVisualStudio.Vsix.Models
{

    internalclass SettingModel
    {
        conststring CollectionPath = "MySetting";
        conststring PropertyName = "AllMySetting";

        readonly WritableSettingsStore writableSettingsStore;

        internal SettingModel()
        {
            var shellSettingsManager = new ShellSettingsManager(ServiceProvider.GlobalProvider);
            writableSettingsStore = shellSettingsManager.GetWritableSettingsStore(SettingsScope.UserSettings);

            Load();
        }

        internalvoid Load()
        {
            try
            {
                if (writableSettingsStore.PropertyExists(CollectionPath, PropertyName))
                {
                    var json = writableSettingsStore.GetString(CollectionPath, PropertyName);
                    var entites = JsonConvert.DeserializeObject<MyEntity>(json);
                    //entites を適当に渡す
                }
            }
            catch (Exception ex)
            {
                Debug.Fail(ex.Message);
            }
        }

        internalvoid Save()
        {
            try
            {
                if (!writableSettingsStore.CollectionExists(CollectionPath))
                {
                    writableSettingsStore.CreateCollection(CollectionPath);
                }

                //entitiesを適当にとってくる
                var jsonString = JsonConvert.SerializeObject(entites);
                writableSettingsStore.SetString(CollectionPath, PropertyName, jsonString);
            }
            catch (Exception ex)
            {
                Debug.Fail(ex.Message);
            }
        }
    }
}

.NET Coreにおける新元号対応について

$
0
0

MVPグローバルサミットに参加している最中に新元号対応が気になったのでマイクロソフトのエンジニアに聞いてみたら、publicなissueで議論しようということだったので立ててみました。するとあっという間に回答が来たので、日本語で簡単にまとめてみようと思います。

github.com

なお、ここでの新元号対応は、新元号が追加された後、どんなライブラリが更新されたら.NET Coreにおいて新元号が適用されるかという話であり、だれがいつそのライブラリを更新するかという話ではありません。

.NET Core における元号

.NET Coreは国際化対応の一貫として日本の元号にも対応しています。具体的にはSystem.Globalization.JapaneseCalendarが日本の元号に対応しているカレンダーになります。元号という概念は、ロケールによらずeraという概念で管理しているのですが、そもそも.NET Coreが対応しているロケールのうちこのeraを複数持っているのはJapaneseCalendarとそれに依存いているJapaneseLunisolarCalendar (太陰暦) となっています。従って、.NET Coreのライフサイクルの間に追加されるイベントも、現時点での日本の元号でしか発生しないということになります。

github.com

.NET Core on Windowsの場合

さて、.NET Coreで新元号が対応可能になるトリガーはWindowsとUnix(LinuxとMacOS)でことなります。これは、カレンダーの実装がプラットフォームごとにことなるものに依存しているためです。Windowsの場合は、.NET Frameworkと同じくレジストリに依存しています。つまりレジストリが更新されれば、そのOS上で動く.NET Coreのアプリは新元号に対応することになります。原理的には、ビルドしたときのマシンが対応していなくとも、もしくは対応する前にビルドした古いバイナリでも、レジストリに追加されたマシンで実行すれば新元号に対応するはずです。

https://msdn.microsoft.com/ja-jp/library/windows/desktop/dd317805%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396msdn.microsoft.com

また、レジストリの追加に関してはすでにテストケース対応済とコメントされています。

.NET Core on Unixの場合

一方、Unixの場合、元号を含んだ国際化の情報はlib-icuというライブラリに依存いています。

github.com

従って、新元号に対応したICU ライブラリに更新すれば、.NET Coreアプリも対応することになります。対応したライブラリがリリースされたら.NET Coreでもテストを追加するとコメントされています。

それ以外

.NET Coreには一応、Windowsではレジストリからの取得に、UnixではICUライブラリからの取得に失敗した場合のフォールバックとして、ソースコード中にハードコードされた元号情報が含まれています。

[github.com

一応と書いたのは、これはあくまで何か想定しないことが起きた時のためのもので、コメントによるとこのハードコードされた情報が利用されることは基本的に想定していないということです。従って、この情報が使われるユースケースは考えなくていいわけなんですが、もし使われることがあるとすると、フレームワーク依存とself-containedで挙動が変わることが想定されます。フレームワーク依存型の場合、実行する環境の.NET Coreランタイムのハードコーティング部分が新元号対応済であれば、このフォールバックが働いた場合でも新元号に対応します。一方、self-containedの場合、ラインタイムもアプリと一緒に含まれているため、新しい元号に対応していない状態でビルドしたアプリは、このフォールバックの仕組みが働く限り永遠に新しい新元号に対応することはありません。

まとめ

.NET Coreに新元号対応を期待する場合、Windowsであればレジストリの更新、UnixであればICUライブラリの更新が行われることが前提条件となります。

Azure CLI 2.0 でMicrosoft Azure Stack に接続する

$
0
0

これであっているか自信ないのですがとりあえずメモしておきます。

Microsoft Azure Stack*1にAzure CLIで接続したい場合、managementAPIのエンドポイントを指定してcloudを登録します。名前は自由なので、複数Azure Stack環境がある場合などは適宜わかりやすい名前をつけましょう。

$  az cloud register -n AzureStackExample --endpoint-resource-manager "https://management.azurestack.example.com" --suffix-storage-endpoint azurestack.example.com

とりあえず上の2つのエンドポイントだけでよさそうですが、他にも指定できるパラメーターはあるようです。上の例はAzure Stackのユーザー環境を登録している想定で、下のドキュメントの手順1-bに相当します。また、Azure Stack環境の場合は、VPN接続が〜というあたりのドキュメントは無視してよさそうです。

docs.microsoft.com

次にここで登録したcloudを指定して接続先を切り替えます。

$ az cloud set -n AzureStackExample
Switched active cloud to 'AzureStackExample'.
Active subscription switched to 'XXXX (UUID)'.

これでログインできてコマンド実行できるはずですが、1つ忘れてはいけないことがあります。Azure Stack側で提供しているARM Rest APIのバージョンは古いらしく、コマンドを実行するとエラーになることがあります。そのため下記コマンドをまず実行しておく必要があります。

$ az cloud update --profile 2017-03-09-profile

なおこのコマンドは現在Activeなcloudに対して処理が行われます。現在利用可能なcloudの一覧は次のコマンドでリストできます。

$ az cloud list
Name                   Profile             IsActive
---------------------  ------------------  ----------
AzureCloud             latest
AzureChinaCloud        latest
AzureUSGovernment      latest
AzureGermanCloud       latest
AzureStackExample      2017-03-09-profile  True

AzureStackExample以外はデフォルトで利用可能なものです。そのため、例えばAzure Germanyを利用したい場合はazure cloud set -n AzureGermanCloudと実行するだけでよいです。

あとはログインです。次のコマンドを実行して、Azure Stack環境にログインする際の認証情報でログインすればOKなはずです。

$ az login
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXXXXXXXX to authenticate.

CloudName           IsDefault    Name   State    TenantId
------------------  -----------  -----  -------  ----------
AzureStackExample   True         NNNN   Enabled  UUID

*1:Azure Stack Development Kitではなく、ポータルやAPIエンドポイントをインターネットに公開できる方

Azure Stack環境で古いカスタムLinuxイメージ(VHD形式)が起動できない時はWALinuxAgentのバージョンをチェックしよう

$
0
0

Azure Stack環境でカスタムLinuxイメージ(オンプレミスで作っておいたLinux OSのVHDファイル)から仮想マシンを起動しようとしたとき、仮想マシンの作成自体はうまくいくものの起動状態にならなかった場合、WALinuxAgentのバージョンが古いことが問題の可能性があります。 たとえpublic Azure環境では起動できるVHDファイルだったとしてもAzure Stack環境では動かない可能性あるらしく、ドキュメントにも記載があります。

docs.microsoft.com

WALinuxAgentのバージョン2.2.2以上が必要です。かつ、2.2.12 や 2.2.13など特定のいくつかのバージョンは動かないとあります。WALinuxAgent 2.2.2のリリースは2017年1月なので古いといえば古いバージョンですが、念の為うまくいかないときはチェックするといいかもしれません。

Release v2.2.2 · Azure/WALinuxAgent · GitHub

Azure の Linux 仮想マシンを仮想マシンの内部からdeallocateする

$
0
0

このエントリはこちらのブログの日本語版になります。

developers.redhat.com

AzureにたてたLinux仮想マシンをdeallocateしたい場合、Azure Portalにログインできればそこからログインしたり、REST APIを実行する権限を作って適宜プログラムからdeallocateすることができます。しかし、そのLinuxにログインできる権限しか無い場合、OSのshutdownコマンドを実行してもdeallocateはされないため、仮想マシンの利用料金はかかり続けます。そこで仮想マシンの中からdeallocateするようにしてみたいと思います。

deallocateするにはREST APIを実行する必要があるので、Azure CLI 2.0をインストールして、Azure AD APPでService Principalを作成して認証を行います。もちろんService Principalのパスワードを指定してもいいのですが、パスワードを平文で保存することが懸念の場合は、Managed Service Identity (MSI)を利用してパスワードを利用せずに認証することができます。今回はその方法を紹介することにします。

対象となるLinux仮想マシンにAzure CLI 2.0がインストールされていない場合はインストールします。yum形式でのインストールは次のようにおこないます。

docs.microsoft.com

$ sudo rpm--import https://packages.microsoft.com/keys/microsoft.asc
$ sudo sh -c'echo -e "[azure-cli]\nname=Azure CLI\nbaseurl=https://packages.microsoft.com/yumrepos/azure-cli\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" &amp;amp;gt; /etc/yum.repos.d/azure-cli.repo'
$ sudo yum install azure-cli

次に仮想マシンに対しMSIを有効にします。Azure Cloud ShellなどAzure CLI 2.0を利用する場合は次のコマンドを実行します。

docs.microsoft.com

$ az vm identity assign -g<resrouce_group_name>-n<vm_name>

次にこの仮想マシンに実行できるIAM Roleを付与します。今回は同じ仮想マシンに対するVirtual Machine Contributorロールを付与することにします。最初のコマンドで仮想マシンのリソースIDを取得し、次のコマンドで先程与えたMSIのサービスプリンシパルIDを取得します。取得いた値を3番目のコマンドに与えて、ロールを付与しています。

$ az vm show  -g<resrouce_group_name>-n<vm_name>--query id
$ az resource list -n<vm_name>--query[*].identity.principalId --out tsv
$ az role assignment create --assignee<vm_resource_id>--role'Virtual Machine Contributor'--scope<sp_id>

これで準備は完了です。仮想マシン側でdeallocateするためのスクリプトを次のように作っておきます。MSIを利用したログインは--msiオプションで実行できます。また、deallocateするために自分自身のリソースグループ名と仮想マシン名が必要です。スクリプトにべた書きしてもいいですが、せっかくなのでインスタンスメタデータサービスを使って取得してみました。これで同一のスクリプトを好きな仮想マシンに配置するだけで実行できるようになります。このスクリプトであればcronでスケジュール実行することもできるでしょう。

#!/bin/bashresponse=$(curl -H Metadata:true"http://169.254.169.254/metadata/instance/compute?api-version=2017-12-01" -s)resource_group=$(echo$response| python -c 'import sys, json; print (json.load(sys.stdin)["resourceGroupName"])')vm_name=$(echo$response| python -c 'import sys, json; print (json.load(sys.stdin)["name"])')

az login --msi
az vm deallocate -g$resource_group-n$vm_name

また、MSIを利用しない場合は、サービスプリンシパルを設定したAzure AD Appを作成し、パスワードを指定してAzure CLI 2.0のログインコマンドを実行するとよいでしょう。


Microsoft Build 2018 のQ#関連のセッションの整理

$
0
0

Q# が発表されてから、おそらく公式のカンファレンスでは初めてではないかと思いますが、先週シアトルで行われたBuild 2018で技術解説セッションがありました。Youtubeでセッションが公開されているので、それを見た雑多なメモを残しておきます。

Empowering the quantum revolution with Q

youtu.be

マイクロソフトのユニークなソリューション

  • 統合的なソリューション Q#/Quantumn SDKを含めたソフトウェア開発キットや、Azureで提供されるというシミュレーターを含めた提供
  • スケーラブルなトポロジカル量子コンピューティング IBMやGoogleとは異なる、トポロジカル超伝導体のマヨラナ粒子を利用するといわれるスケーラブルな量子コンピューターを開発中
  • 大胆な投資とグローバルなチーム 昨年のIgniteで見せていたデバイスは世界中の研究室を巡って開発している

なぜ量子コンピューターか

たとえば2つの大きな素数の積の整数を素因数分解する問題を考えた場合、古典的コンピューターよりも量子コンピューターの方が圧倒的に早いことが期待されている。このような古典的コンピューターでは指数関数的に計算量が爆発する問題を、量子コンピューターでは線形程度の増加で抑えることができる。

今後、自然科学の分野で量子コンピューターが利用されることが期待されている。

Microsoftのめざす量子コンピューター

光が波と粒子の性質を兼ね備える、というところから説明がスタート。

30 qubitsで16Gb 40 qubitsで16Tb 50 qubitsで16Pb に相当。

重ね合わせ、量子測定、もつれ、などの物理現象と関連。

マヨラナ粒子は理論的には予測されていた。2000年、Micorosoftはマヨラナ粒子を利用したコンピューティングを数学者とともに進める。 2012年にその兆候を実験室で観測。

現在、GoogleやIBMなどがすでにQubitsを実現しているが、それらのスケーラビリティとエラーレートはそれぞれ違う。Microsoftはスケーラブルかつエラーレートの低いQubitの実現に向けて動いている。最初のエンタープライズレベルにスケーラブルなQubitを。いまの方向がそれを実現できるものだと信じている。

Qubitは15mKほどの低温の孤立した環境で実現している。これは希釈冷凍機を利用して実現しており、液体窒素(77K)、液体ヘリウム(4K)、宇宙背景放射(3K)より低い。 量子コンピューターそのものは15mKにあるが、希釈冷凍機のコンピューターと制御ソフトウェアは4Kにあり、量子コンピューターとは数千のワイヤーで繋がっている。 また、ライブラリを利用して記述して、実際の問題を解くために動かすソフトウェアは室温部分にある。

この、量子コンピューター、制御ソフトウェア、ライブラリと開発言語の3つのスタックが必要だと考えている。スケーラビリティに必要なものは次のようなものだと考えている。

  • スケーラブルなQubitの基礎
  • 冷凍装置
  • 量子と古典的コンピューターのインターフェース
  • 量子エラーを識別し訂正するための新しいプラットフォームの開発
  • スケーラブルなソフトウェアスタック
  • Azureとの完全な統合
  • アルゴリズムと現実世界の問題

スケーラブルなエンタープライズ量子コンピューターを最初に提供する」が今のところの目標らしい。

Microsoft Quantum Development Kit

量子ロジックのルール

  • 全ての操作は可逆的でなければならない
  • 測定は状態を破壊する
  • 状態を複製できない

量子状態をブロッホ球で表現する

古典的操作と量子操作の比較

  • 古典的操作
    • 1bit: NOT
    • 2bit: NAND/NOR n bit での全ての操作はn 入力をもつNANDgatesの有限回の操作で実現できる
  • 量子操作

    • 1 qubit
      • X,Y,Z パウリ回転
      • 位相演算子 S, H ゲート
    • 2 qubit
      • CNOT n qubitsでの全ての操作は、クリフォード群とT ゲートの有限回の操作で実現できる
  • 古典的コンピューター ドモルガンの法則で式の削減と変換ができる

  • 量子コンピューター Clifford群はパウリ群を共役作用のもとで不変である

Q#言語の特徴

  • ブロックスタイルの記述に近しい
  • 関数型言語に触発されている
    • デフォルトでイミュータブル
    • ファーストクラスの関数
    • 部分適用
  • 強い型システム
    • ジェネリクス
  • 量子特有のコンセプト
    • Functor
    • リソース管理
    • 古典制御部分との相互作用の削減

Q# 言語の論理モデル

Q# ライブラリとコードでホストプログラムを動かす。動かす先は、シミュレーターもしくはDriver経由で実際の量子ハードウェア、もしくはAzureシミュレーター。

QDK ライブラリ

  • HW固有のゲートをきれいに表現
  • 包括的なライブラリ
    • 数学
    • 位相推定、振幅増幅、QFT(量子フーリエ変換)
    • ハミルトニアンシミュレーター
    • 誤り訂正と蒸留
    • Quantum Characterization Verification & Validation (QCVV
    • Functional Abstraction & Combinator
  • 十分なサンプル
  • オープンソース、PRを受付

ターゲットマシン

  • 最先端のLocal Simulator: ローカルマシンの16GBで30qubitをシミュレーション
  • 最先端のAzure Simulator: 40 qubit以上
  • Quantum Trace Simulator: コードを評価して、どのくらい量子リソースが必要かを決定する
  • Microsoft Quantum System

参考資料

Setting up the Q# development environment | Microsoft Docs

Quantum computing | Microsoft

GitHub - Microsoft/Quantum: Microsoft Quantum Development Kit Samples and Libraries

付録:エラー訂正

古典的エラー訂正はノイズモデルに基く。0,1のビット配列を送信するときあるbitが誤って送信される確率をpとして、十分低いエラーレートでn論理ビット配列を送信するのに必要な物理bit配列はいくつになるのか?

量子エラー訂正ではエンタングルメント(もつれ)が鍵となる。1量子サイクルの間にqubitもしくは操作が失敗に終わる確率。

THR2503 Learn to build you first quantum solution with the Quantum Development Kit and Q

youtu.be

Visual Studio/Visual Studio Codeでの最初のQ#プロジェクトの作成を説明。 今までのプラグラミングとは異なるライブラリでプログラムを書いている。

Q#はQ#ライブラリを使ってQ#のコードを書き、それを古典的プログラムであるホストプログラムを通して実行する。実行先はシミュレーターもしくはDriver経由で実際の量子デバイスとなる。

実際にコードの説明。 Mainメソッドで、量子シミュレーターオブジェクトを生成し、Q#で記述したクラスを実行している。Q#で記述したコードはC#から通常のクラスとして見えている。 =>現在のSDKではQ#のコードはC#のコードにコンパイルされている(XAMLと同じようなイメージ)

Q#のコードはデフォルトで副作用がなく、また状態の複製も行えない。 Q#のコード中にブレークポイントをおき、そのときの変数の値を確認することもできる。

また、同じことがVisual Studio Codeで実現できる。.NET Coreで動くので、LinuxやmacOSでも開発できる。

Microsoft Build 2018 のSignalR関連のセッションの整理

$
0
0

Q#に引き続き、SignalR関連セッションの情報まとめです。

tech.tanaka733.net

(ブレークアウトセッション) Meet the new stack for real-time web communication: ASP.NET Core SignalR

youtu.be

ASP.NET Core SignalR overview

  • "Hubs"を使ったRPC style
  • ServerからClientはglobal, グループ、個別を選べる
  • HubのメソッドからのStreamの返り値はChannelクラスとなる
  • クライアントライブラリはTS/JSと.NET
  • JSONとMessagePackがドキュメント化されている実装プロトコル
  • WebScockets, Server Sent Events, Long Pollingから選択
  • ASP.NET Coreのrouting, DIとの統合
  • Redisもしくは新しいAzureのサービスを利用してスケールできる

既存のSignalR からの変更点

  • jQueryの依存性なし
  • メッセージの再送つきの自動再接続なし
  • Hubの状態ももたなくなった
  • 複数Hubのendpointもなし
  • 単一モデルでのスケールアウトもなし
  • 複数サーバー間のping-pongがなくなるため、sticky sessionが必要となる

SignalR機能概要

  • routing
  • Hubパラメーターbinding
  • JSON および MessagePackプロトコル
  • Controllerからのpush通知
  • グループとbackgroundサービスからのpush通知
  • 型付のHub
  • 認可
  • HubメソッドからのStream
  • .NET Client

Hubの下回りの構造

従来のSingalRは Hub-HubDispatcher-PersistentConnectionMiddleware-OWIN-System.Web HttpHandler

ASP.NET Core SignalR Hub-HubConnectionHundler-HubConnectionDispatcher-RoutingMiddleware-ASP.NET Core HTTP Pipeline

HTTPではなくTCP/IPを利用した転送も計画中

over HTTPの場合 Hub-HubConnectionHandler-HttpConnectionDispatcher-RoutingMiddleware-ASP.NET Core HTTP pipeline-Kestrel-Sockets or Libuv

over TCP/IP Hub-HubConnectionHandler-Kestrel-Sockets or Libuv

Project Bedrockの紹介

  • .NETのための新しい高パフォーマンスネットワーク抽象化
  • transport層からapplication層を取り除く
  • System.Net.Sockets と libuv を利用
  • アプリケーション層の書き換えなしに導入可能
  • ASP.NET Coreを対象
  • 新しいSystem.IO.Pipelines APIを利用
  • ClientとServer両方

ベンチマークを公開中 https://aka.ms/aspnet/benchmarks

Demoサンプル

KestrelHttpServer/BenchmarkApplication.cs at dev · aspnet/KestrelHttpServer · GitHub

Azure SignalR Service

  • SignalR clientの接続とスケールアウトのためのPaaS
  • ASP.NET Core SignalR と Bedrockを利用
  • サービスへの接続のオフロードやアプリケーションから/へのトラフィックの転送
  • ドキュメント化されているプロトコルが利用可能
  • web側のtrafficと独立してSignalRのみの簡単のスケールが可能
  • 2行のコードの変更で既存アプリから変更可能
  • public preview!

Azure SignalR Serviceの利用

これだったのか Hub-HubConnectionHandler-HubConnectionDispatcher-RoutingMiddleware-ASP.NET Core HTTP Pipeline

こうなる Hub-HubConnectionHandler-ServiceHubDispatcher-WebSocket Clients

今後の実装計画

  • クライアント再接続
  • より柔軟な接続。client intiated pingsなど
  • クライアント側の型付Hub
  • Java,C++,iOSなどのクライアント
  • TCP/IPを含めたさらなるtransports。サンプルではなく実際に利用できるものとして。

(シアターセッション) Build and manage real-time applications easily with the all new Azure SignalR Service

こちらは動画が公開されていないので、見てきたときのメモから。

Azure SignalR Service, a fully-managed service to add real-time functionality https://azure.microsoft.com/en-us/blog/azure-signalr-service-a-fully-managed-service-to-add-real-time-functionality/

数十人の参加者に開発したことのあるSignalRの規模を質問。ぱっと見た限り、100接続以上が10人くらい、1000接続が数人、10000接続以上はなし。

  • 上のセッションで公開したデモは2'40ほどの間に800人から接続され、100万メッセージ以上、秒間だいたい35kを処理。
  • Free Tier/Basic Tier
  • 使えるリージョンはいまのところ US E/US W/SE Asia/EU W
  • サービスを作成すると接続文字列が表示されるので、それをアプリ側で設定。
  • Azure Functionsを使ってServerless構成も可能

Q# Programming Contestが開催されるようです

$
0
0

CodeforcesというプログラミングコンテストのサイトでQ# Programming Contestが開催されるようです。

codeforces.com

本番は7/6-9のようですが、6/29からwarmupラウンドということでいくつかの問題が出題されています。簡単な問題3つについては解説するということです。

Q#はVisual Studioだけでなく、LinuxやMaxOSでも.NET CoreとVisual Studio Codeで始めることができます。

Setting up the Q# development environment | Microsoft Docs

上位50人にはMicrosoft Quantum Tシャツがもらえるとあるのでぜひ参加してみてはいかがでしょうか。自分も参加する予定です。

Q# Coding ContestでのDriverクラスの書き方

$
0
0

昨日紹介したQ# Coding Testですが、書いたクラスをテストするのに最初ちょっと戸惑ったのでメモしておきます。

codeforces.com

実際の問題は登録した後にみられて、今は3問ほど解説も見ることができます。が、テストするためのコードが書けないとそのあとが大変です。 問題の形式はいくつかるのですが、このコメントにあるとおり、引数で渡されたQubitを操作して指定した状態にするという問題があります。

Announcement: Microsoft Q# Coding Contest — Summer 2018 - Codeforces

なんとなく、C# のDriverクラス側で所定の状態のQubitをQ#のクラス(メソッド)に渡して実行して、その結果を見ればいいように思えますが、残念ながら量子コンピューターの性質上、Qubitの初期化などはC#のDriverからはできません。コメントにあるとおり、提出するSolveメソッドのほかにQ#側にDriverとなるメソッドを用意してそこで実行する必要があります。提出用ファイルにこのDriverメソッドを含めたくなかったので、次のようなQ#ファイルを作って、Testメソッドを作成してみました。Solveメソッドが提出対象のメソッドです。

namespace Solution {
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Extensions.Diagnostics;

    operation Test() : () {
        body {
            using (register = Qubit[1]) {
                let q = register[0];
                DumpMachine("dump-initial.txt");

                Solve(q,-1);

                DumpMachine("dump.txt");
                Reset(q);
            }
        }
    }
}

Qubitの初期化はusingキーワードでQubitを生成します。これにより|0>で初期化されます。

docs.microsoft.com

またQubitの状態を測定すると、それはそれで状態に影響してしまうので、デバッグのために DumpMachineメソッドを使います。これによりQubitの状態をファイルに出力します。

docs.microsoft.com

こんな感じで出力されます。

Ids: [0;]
Wavefunction:
0: 101: 00

ここまでQ#側でやるとC#のDriverはこのような簡単な記述になります。

using Microsoft.Quantum.Simulation.Simulators;

namespace Solution
{
    class Driver
    {
        staticvoid Main(string[] args)
        {
            using (var sim = new QuantumSimulator())
            {
                var received = Test.Run(sim).Result;
            }
        }
    }
}

一応、全部解けたので、Warmup Contestの期間が終わったら問題についてもちょっとまとめてみたいと思います。 f:id:tanaka733:20180701185341p:plain

Microsoft MVP を再受賞して、カテゴリがAzureになりました

$
0
0

TwitterやFacebookではすでに報告してお祝いのコメントももらっていますが、今年もMicrosoft MVPを更新できました。この場を借りてお礼させていただきます。MVPとはなんぞやというのはこちらにあります。

Microsoft MVP Award

最近になって、MVPの新規受賞は毎月(申請も毎月)なので、定期的に受賞された方が増えているのですが、すでに受賞している人の更新はまとめて7月に発表されるため、SNSで大量に言及される事態になっています。

私自身は、ここ1~2年は .NET Core/C# に加えて、コンテナ関連技術やLinuxを中心にAzureまわりの技術をテーマにしたブログや登壇もしていたので、AzureとVisual Studio and Development Technologies(VSDT)という2つのカテゴリで申請しました。審査の結果、去年まで受賞していたVSDTは申請が通らなかったため、更新した上でVSDTからAzureに移動という形になりました。カテゴリわけについてはこちら。

MVP Award Update - Oct 2015

とはいえ一番好きな言語はC#ですし、コンテナ上やLinux上での利用を中心に.NET Core/C#の技術情報も引き続き発信していければと思います。仕事上の必要にせまられてというケースがほとんどなんですが、最近は次のような技術を追いかけています。

  • .NET Core/ ASP.NET Core (コンテナ上での利用を中心に)
  • kubernetes on Azure (あるいはOpenShift on Azure)
  • Linux on Azure (仮想マシン管理を中心に)
  • SQL Server on Linux (特にRHEL、Azure上のRHELやkubernetes上でのAlwaysOn AGも)
  • Linux/kubernetes on Azure Stack (Linux/kubernetes管理者視点でどのようにAzure Stackを利用するか)
  • Windows Server Node in kubernetes
  • Q# (Microsoft Quantum/トポロジカル量子コンピューター)

(これらはさっきのカテゴリ分類みると、ばらばらなカテゴリなので来年どうなることやら)

活動内容は去年に引き続き、ブログでの情報発信やコミュニティイベントでの登壇ですので、もしこれらの技術について話してほしいという要望があればぜひお声掛けください。去年福岡に行ったので、首都圏以外も機会があればぜひ登壇したいと思っています。大きめのイベントでの登壇もやってみたいなあと思い、CFPも出していたりします。 それ以外の例えば雑誌や書籍の執筆なども機会があれば(もらえれば)ぜひやりたいですね(というのを毎年言っている気がする)

今年も一年よろしくお願いします。

Microsoft Q# Coding Contest warmupラウンドの自分の回答を公開しています

$
0
0

Microsoft Q# Coding Contest warmupラウンドが終了して結果として私は107位でした。自分にとってはたぶんこれが初めてのオンラインプログラミングコンテスト参加だったと思います。

f:id:tanaka733:20180704190050p:plain

また問題も公開されているようです。 codeforces.com

というわけで自分が提出した回答をGitHubに公開してみました。 github.com

問題そのものの解説はすでにあるようなので、

smijake3.hatenablog.com

最初の問題を例にどうやって実行したかを説明してみます。問題としては、状態{|0 \rangle}であるQubit型の引数qと1か-1であるInt型の引数signに与えられ、signが1であればqを{| + \rangle = \frac{1}{\sqrt{2}}(|0 \rangle + |1 \rangle)}、-1であればqを{| - \rangle = \frac{1}{\sqrt{2}}(|0 \rangle - |1 \rangle)}に変化させるoperationを記述するというものです。引数で渡された状態を変化させるため、このoperationは返り値を持ちません。

先日のエントリで書いた通り、QubitはC#のDriverクラスでは生成できないので、もうひとつQ#のoperationを作成し、その中でQubitを生成、operationを実行、実行した結果を確認、という手順を踏みます。というわけで、テスト用のQ#コードはこのようになります。

namespace Solution
{
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Extensions.Diagnostics;

    operation Test() : () 
    {
        body 
        {
            using (register = Qubit[1])
            {
                let q = register[0];
                DumpMachine("dump-initial.txt");

                Solve(q,-1);
                DumpMachine("dump-0.txt");
                Reset(q);

                Solve(q,1);
                DumpMachine("dump-1.txt");
                Reset(q);
            }
        }
    }
}

usingでQubitを初期化、(必要はないですが)配列のindex0のQubitを変数qとしています。DumpMachineは引数にファイルパスをとって、そのパスにQubitの状態を出力します。Solve operationを実行したあと、DumpMachineで状態を出力、Resetで再度初期化を行っています。DumpMachineの出力結果は次のようになって、期待通りのoperationを記述できたことがわかります。

dump-initial.txt

Ids: [0;]
Wavefunction:
0:  1   0
1:  0   0

dump-0.txt

Ids: [0;]
Wavefunction:
0:  0.707107    0
1:  -0.707107   0

dump-1.txt

Ids: [0;]
Wavefunction:
0:  0.707107    0
1:  0.707107    0

まじめに測定するコードを書いてもいいと思うのですが、デバッグ目的ではDumpMachineがかなり便利でした。 Microsoft Q# Coding Contestの本戦は土曜1時(金曜深夜25時)からなので、W-cup観戦の合間にいかがでしょうか。

Microsoft Q# Coding Contest Summer の解説が公開されています


Azure CLI を使ってLinux VMにAzure Disk Encryptionを適用する

$
0
0

Azure Storageの暗号化については、すでにほとんど、くらう道さんでわかりやすく説明されています。

www.cloudou.net

最近のManaged DiskであればStorage Service Encryption(SSE)でデフォルトで暗号化されているので、これで十分ということも多いでしょう。

docs.microsoft.com

ただ、場合によってはAzure Disk Encryption (ADE)による暗号化が必要になるケースもあると聞きます。

docs.microsoft.com

ADEについてもくらう道さんの記事でPowerShellを使った方法は紹介されているのですが、Azure CLIを使った方法について今回まとめてみました。

Linux VMの場合、注意すべきがベンダーによるサポートの有無です。ADEの適用がベンダーによりサポートされていないケースもあるので、まずそこはご確認ください。そのうえで実際に試した手順になります。 まず、WALinuxAgentを最新版にしておきましょう。手元の環境だと、古いバージョンだとなぜか処理がスタックして動かないことがありました。

そして、Azure CLIを使って、Service Principalを作ります。証明書を使う方法はLinux VMではサポートされないのでパスワードを利用します。RBAC用のService Principakと違ってパスワードは自動生成されないようなので、指定しています。また、indentifier urlはアクセスするURIとしては使いませんが、ユニークな値を指定しないといけないので適当に指定しておきます。最初のコマンドの実行結果に表示されている application_id を次のコマンドのオプションに指定します。このIDは先でも使います。

$ az ad app create --display-name <name> --identifier-uris https://<name> --Password <password>

$ az ad sp create --id <application_id>

次にKeyVaultを作成します。仮想マシンと同じリソースグループ、同じロケーションにある既存のKeyVaultを利用することもできます。新規に作る場合は同じリソースグループ、同じロケーションに作るようにします。最初のコマンドは場合によって必要になります。一度、同じキーで複数の仮想マシンの暗号化をしようとしたらうまくいかなかったので、もしかすると仮想マシンごとに用意する必要があるかもしれません。

$ az provider register -n Microsoft.KeyVault
$ az keyvault create -n <keyvalue_name> -g <resource_group> --enabled-for-disk-encryption True

$ az keyvault set-policy --name <keyvalue_name> --spn <application_id> --key-permissions wrapKey  --secret-permissions set

$ az keyvault key create --vault-name <keyvalue_name> --name <keyname> --protection software

そして、VMの暗号化を実行します。このコマンドが実行してしばらくするとVMは再起動します。時間がかかるので処理されているか気になる場合は、WALinuxAgentのログをtailしておくといいでしょう。 また、--volume-typeはOSディスクのみ(OS)、DATAディスクのみ(DATA)、すべて(ALL)の3つが選べます。なお、OSディスクが有効になっている場合のみ、データディスクが追加された場合に暗号化が有効になります。OSディスクの暗号化が有効になっていないと、DATAディスクの暗号化が有効になっていてても、そのあと追加されたDATAディスクの暗号化は実行されませんでした。

$ az vm encryption enable -g <resourcegroup_name> -n <vm_name> --aad-client-id <application_id> --aad-client-secret <password> --disk-encryption-keyvault <keyvalue_name>  --key-encryption-key  <keyname> --volume-type DATA

VMの再起動後もしばらく暗号化処理は実行されます。状態の確認はAzure CLIコマンドで行います。また、VMを再起動するたびに起動後しばらくは暗号化処理が行われています*1

$ az vm encryption show -g <resourcegroup_name> -n <vm_name>

暗号化が完了しているとこういうメッセージが表示されます。

{
  "dataDisk": "NotEncrypted",
  "osDisk": "Encrypted",
  "osDiskEncryptionSettings": {
    "diskEncryptionKey": {
      "secretUrl": "...",
      "sourceVault": {
        "id": "..."
      }
    },
    "enabled": true,
    "keyEncryptionKey": {
      "keyUrl": "...",
      "sourceVault": {
        "id": "..."
      }
    }
  },
  "osType": "Linux",
  "progressMessage": "Encryption succeeded for data volumes"
}

というわけで暗号化は完了です。暗号化のために、/dev/sdcにデバイスがマウントされていますが、これはBek Volumeといって重要なのでかってに消したりしてはだめなのはくらう道で説明されている通りです。という/dev/sdc関連でトラブルがおきるというのを次のエントリで紹介します。

*1:すくなくとも、deallocate/startでは確認済み

AKSでADEを適用すると、Azure DiskがPVとして利用できなくなった話

$
0
0

前回のエントリでADEを適用すると、/dev/sdcにBEK volumeがデバイスがマウントされると書いたのですが、

tech.tanaka733.net

それがうまく処理できないケースとして、kubernetesのAzure Cloud Providerとの組み合わせがあります。これについてはすでにissueとして報告しており、解決策が議論されています。

github.com

問題は、Azure DiskをkubernetesのPersistent Volumeとして利用する場合、ADEが有効化されている仮想マシンにマウントされると、/dev/sdcにPVとしてアタッチされたAzure Diskのデバイスが存在していると認識してしまうというものです。Azure Cloud Providerの問題なので、AKSでも発生しますし、素のkubernetesをAzure Cloud Providerを有効化しても発生します。

Azure Disk Encryption自体は透過的に働くので、kubernetesとは独立しているような気がするのですが、デバイスのマウント先の検出するロジックで問題が発生しているようです。

Azure Cloud ProviderはPVとしてマウントされたAzue Diskのデバイスについて必要な処理を行うのですが、その際、すでにマウント済みのデバイス*1は除外するようにコードが記述されています。が、この処理がADEのBEK volumeについての考慮が漏れているらしいというのが事の真相のようです。

kubernetes/azure_common_linux.go at v1.9.9 · kubernetes/kubernetes · GitHub

workaroundはなさそう?*2なので、しばらくはissueの行方を見守る必要がありそうです。

*1:PV以外の目的であらかじめマウントされている外付けデバイスなど

*2:udev ruleを記述すれば回避できるかも?

giffgaffをアイルランドとイギリスで使ってみた 2018年版

$
0
0

昨年giffgaffをイギリス旅行で使ってみたのですが、今年はアイルランドとイギリスで使ってみたので少し更新してみたいと思います。

tech.tanaka733.net

実際に購入したい方は次のアフィリエイトリンクから申し込むと、5£分のクーポンがもらえます。

www.giffgaff.com

久しぶりにgiffgaffを使う場合の注意点

正確な数字は忘れましたが、一度イギリスで使ったSIMを通信せずに数ヶ月以上経過すると*1、SIMが無効になります。このSIM自体を再度有効化することはできなさそうなので、再度あたらしいSIMを入手することになります。これはgiffgaffにログイン後のorder more SIMsのページから行うことが可能です。初回同様、SIMの追加自体は送料含め無料で送付されてきます。日本に送る場合は国際郵便なので余裕を持って入手しておきましょう。

新しいSIMを入手したらSetup wizardsで有効化します。有効化自体は日本国内でも無料でできるのでやっておくことをおすすめします。

アイルランドでのローミング

今回の旅行は、まず香港経由でアイルランド(ダブリン)に入国し、ダブリン市内を観光したあと北アイルランド(ベルファストなど)に入り、再度アイルランドに戻り、イギリス(Mainland)に行くという旅程です。giffgaffのroaming ポリシーについてはこちらに記述があります。

www.giffgaff.com

アイルランドはEU加盟国なのでEU and selected destinationsに当然含まれており無料で利用可能な対象に含まれています。しかしながら、giffgaffのfairuse規定?があるらしく、直近3ヶ月以内にイギリス国内からの通信が無い場合、そのアカウント(もしかするとSIM単位かも)でのローミングを有効化することができません。そのため、今回のように最初にアイルランドに入る場合はイギリス国内に入るまでSIMで通信することはできません。ヒースロー空港などイギリス国内の空港で乗り継いでアイルランドに向かう場合は、乗り継ぎの間に通信すれば有効化できそうですが、後述の理由で入国したその日は使えないかもしれません。

というわけなので、まず最初にイギリス以外の国に入る場合、イギリスに入るまでgiffgaffのローミングを利用するのは難しそうです。これはイギリス国内の他のキャリアも同じようなので、最初に入る国のキャリアのSIMを用意する必要がありそうです。

私の場合、イギリスに入るまではダブリン市内のみでそこまでSIMが必要ではなかったので今年もgiffgaffを使うことにしました。

giffgaffは北アイルランドでも利用可能なので、北アイルランドの国境付近からSIMが通信可能になります。レンタカーで高速を走りながら入国したので正確なタイミングはわかりませんでしたが、スマホのデータ通信を有効にしていたらいつのまにか通信できていました。余談ですが、今回通過したアイルランドとイギリス(北アイルランド)の陸路の国境は大き目の道であれば看板一枚程度、小さい道だと国境の表示が見当たりませんでした。ちなみにアイルランドの標識はメートル表記、北アイルランドはマイル表記な上、大きい高速だと同じ道でもアイルランドは最高速度120km/h、北アイルランドは最高速度112km/h (70 miles/h)と異なります。

イギリスに入国した直後にgiffgaffのマイアカウントページを確認しましたが、まだローミングは有効にできない(90日以内に利用実績がない表示)状態でした。翌朝9時を過ぎたころに再度確認すると、有効になっていた*2ので、おそらく日次処理で有効になるようです。そのため、イギリス国内で乗り継ぎでアイルランドに入る場合も翌朝まで待たないと利用可能にならないかもしれません。

北アイルランドでローミングが有効になったあと、アイルランドに再度入国するとローミングが有効であればSIMで通信できます。国境付近をドライブする間も特に不自由なくつかえていた印象です*3。アイルランドではゴールウェー、アラン諸島、グレンダロッホ、ダブリンあたりで利用しましたが、ゴールウェーやダブリン市内では4Gで快適に利用可能、アラン諸島では低速ながらSNSやメール、Google mapの情報表示、テキスト中心のWebブラウジングは問題なくできる程度*4、グレンダロッホでは圏外でほぼ通信できない、といった感じでした。

なおローミングは無料でも、国際通話は別途料金がかかるため、アイルランドで電話を使いたい場合は国際電話料金を払うか、アイルランドのSIMを利用する必要があるようです。

アイルランドでローミングにて利用後、イギリスでもつかっていますが、大きなストレスなくつかえています。5£分のクーポンももらえますので、利用したい方はぜひ次のリンク(再掲)からどうぞ。

www.giffgaff.com

*1:この記事によると6ヶ月後らしい

*2:もしかすると手動で有効にしたかもしれない

*3:どちらかたというと人里離れることで電波が悪くなる影響の方が強い

*4:ドンエンガスの壁より内側では通信できなかった

ロンドン市内でレンタルサイクルを使ってみた

$
0
0

一度使ってみようと思っていたロンドン市内のレンタルサイクルを使う機会があったのでまとめてみました。こちらが公式サイトで、Transport For London(ロンドン交通局)のサービスの一つです。

tfl.gov.uk

ロンドン中心部にdocking stationとよばれるたくさんの貸出/返却拠点があり、好きな拠点で借りて好きな拠点で返すことができます。範囲は地下鉄でいうところのzone1~zone2あたりな気がします。

f:id:tanaka733:20180823145652j:plain

料金体系ですが、基本的には2£で30分おきにdocking stationに立ち寄れれば、1日乗り放題となります。zone1の片道が2.4£、バスの片道が1.5£なのでうまく使えばお得です。

tfl.gov.uk

より正確に言うと、まず2£払うと24時間自転車にアクセスすることができるようになります。そして、拠点をスタートして30分以内に自転車を返却すれば無料です。もし30分以上かかった場合は30分ごとに2£追加されます。一つの自転車を24時間以上借りっ放しにすることはできません。支払はクレジットカードになります。Oyster Cardは使えません。 また、年単位で利用したり、物理鍵を利用することもできますが、これらは旅行者はあまり使うことはないでしょう。

利用方法ですが、モバイルアプリとdocking stationの端末を操作する2通りの方法があります。今回はモバイルアプリを利用しました。アプリを起動すると現在地に近いdocking stationが表示されます。借りるdocking stationを選んで「Hire Now」をクリックします。

f:id:tanaka733:20180825095004j:plain

まだアカウントを登録していない場合はここからアカウント登録が始まるので少し時間がかかります。どうもアカウント登録と同時に支払をする必要がありそうなので、事前に作っておくことはできない気がします。アプリから支払うので、アプリにクレジットカード番号を登録する必要があります。アプリの手順に従いましょう。auto-pay を無効化すると、次に支払う場合は再度クレジットカード番号の入力が必要です。

docking station で支払う場合はこの端末を操作することになります。

f:id:tanaka733:20180823145707j:plain

f:id:tanaka733:20180823145719j:plain

貸出手続きがすむと、暗証番号的な番号が表示されます。docking stationにつながっているどの自転車でもよいので、dockの操作盤で番号を入力して鍵を解除します。解除できたら、操作盤のシグナルが緑になるので、少し力をいれて自転車をdockから引き抜きます。これで利用開始です。

小さなバッグやリュックサック*1なら前にのせることができますが、後ろのかごなどはありません。自転車のサドルは高さ調整ができます。また三段変速がついています。ライトは暗くなると自転車のかたちが浮き出るライトが自動で付きます。

tfl.gov.uk

返却する場合は、dockに空きがある拠点に返します。空いているdockerに自転車を差し込むと操作盤のシグナルが緑になるので、これで返却完了です。30分以内にここまで完了すれば無料なので、再度借りたい場合は同じ手順を繰り返します。返した自転車をそのまま使うこともできます もし、返したいdockに空きがない場合は、端末の「No docking point free」メニューを押して操作を行います。アプリから借りた場合も端末を操作する必要があります。支払いに使ったクレジットカートを端末に差し込み自転車の番号を入力すれば、別の拠点に返すまで15分の猶予が追加されるはず...なのですが、私が試したらエラーになって、この番号に問い合わせしろと表示されました*2。自分の場合は、時間に余裕があったので別の場所に返しに行きましたが、返すときは余裕を持ってdocking stationを探しましょう。

さて、ロンドン市内での自転車の運転ですが、かなり面倒でした。日本と同様、自転車は車道の左端を走行します。が、ラウンドアバウトや複雑な形の交差点が多く、左折専用レーンなどがあり自転車はつねに車に気を付けて移動する必要があります。信号も車と同じですが、一部自転車専用の信号があります。信号が自転車の形をしているので、これはわかりやすかったです。また、あまりに交通量の多いラウンドアバウトでは歩行者用の横断歩道を使えという指示が書いてあるところもあります。このページに一通り目を通しておくことをおすすめします。

tfl.gov.uk

*1:10kgまでという表示あり。それ以上に荷物をゴムで固定する仕組みだが、そのゴムが短いので大きな荷物は固定できない。

*2:なお、通話料は自腹との表示あり

古い10£紙幣と1£硬貨を交換しようとした話

$
0
0

最近イギリスでは、紙幣や硬貨が新しいものにかわっています。移行期間中であれば比較的簡単に交換できるのですが、移行期間が数ヶ月と短く、旅行者だと前に余った紙幣や硬貨を交換するタイミングがなかなかみつかりません。今回、10£紙幣と1£硬貨を交換しようとしたので、その結果をまとめてみました。

10£紙幣

古い紙幣についてはイングランド銀行本店が交換してくれます。

www.bankofengland.co.uk

口座を持っていればその銀行が交換してくれたり、イギリス国内ならイングランド銀行が郵送で対応してくれるらしいですが、旅行者の場合は直接持って行くしかなさそうです。イングランド銀行本店のみの対応なので、そこに行く必要があります。身分証が必要になることがあるというので、忘れずパスポートを持っていきましょう。

最寄駅はその名も「Bank」です。ものものしいドアから入ると、警備員っぽい人に「御用はなんですか」と(もちろん)英語で聞かれるので、「I'd like to exchange my old banknotes.」みたいなことをいうと、その紙幣を見せてといわれます。実物を見せると入っていいよと言われるので、荷物チェックを済ませて入ります。HPには1時間近く待つこともあると書いていましたが、8月のしかも終了時間間際に行ったせいか数人並んでいた程度でした。呼ばれて紙幣を出すと、1枚だけだったせいか、パスポートを見せることもなく、なにかサインなどをすることもなく、あっさり新しい紙幣を渡されておしましでした。たくさん持っていくとそれなりに確認されるようでした。

ちなみにイングランド銀行の裏手には博物館があって、本物の金塊を持ち上げたり、イングランド銀行の歴史や紙幣/硬貨の歴史を観ることができます。ついでにここに行くのもいいでしょう。

1£硬貨

Twitterでコメントされて気付いたのですが、硬貨は発行(もしくは製造?)がRoyal Mintになります。

実際、先程のイングランド銀行のHPに"We do not exchange coins"と書いてあってRoyal MintのHPにリンクされているのですが...

www.royalmint.com

High-Streetの銀行が交換してくれるよ、だけど法律で保証されているものじゃないよ、と書いてあります。じゃあということで適当に見つけた銀行に入って聞いたところ「UKの口座を持っていれば交換できるが、持っていないならうちではできない。郵便局なら交換してくれるかもしれないが、郵便局でもだめなら口座がない限りできないと思う」と言われました。ということで郵便局に行ってみたら、「うちではできない。イングランド銀行にいけ」と無限ループになる回答をもらいました......

手持ちの古い1£硬貨は3枚しかないので、あまりがんばったところで元が取れないので、ここであきらめることにしました。大量に持っている場合は、口座をつくるか口座を持っている人に頼むというのが答えになるでしょうか...

ちなみに2020年までに20ポンド紙幣も新しいものに変わるらしいので、もし今持っていて近いうちにイギリスにいくのであれば、細かい紙幣に変えておくのがいいのではないでしょうか。

Viewing all 283 articles
Browse latest View live