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

ASP.NET Core MVC で static fileを認証ユーザーのみに公開する

$
0
0

ASP.NET Core MVCでstatic fileを公開する場合、基本的には用意されている Static File Middlewareを使うと便利です。以下のドキュメントに詳しく書いてあります。

Working with Static Files | Microsoft Docs

が、このMiddlewareを使うとファイルは認証なしでアクセス可能になるため、認証付きユーザーのみアクセス可能にしたい場合はちょっと手間をかける必要があります。

といっても、そのドキュメントに注釈として書かれているように設定するだけになります。

  • static file middleware で設定しているフォルダ (デフォルトだとwwwroot) 以外に、ファイルを配置し、かつ
  • Controllerのアクションで、FileResultとして返す

ことが必要です。サンプルとして、wwwrootと同じ階層にwwwフォルダを作成に、ファイルを配置しました。

f:id:tanaka733:20170109122226p:plain

最初に書いたようにStatic File Middlewareで公開すると認証なしでアクセス可能になるので、Middlewareでwwwフォルダを公開しないようにしないといけません。これさえ守っておけば、あとはコントローラー側のアクションメソッドでPhysicalFileヘルパーメソッドを使って返したいファイルを指定するだけです。

[Authorize]
public IActionResult File()
{
    return PhysicalFile(Path.Combine(environment.ContentRootPath, "www", "banner1.svg"), "image/svg+xml");
}

注意点としてはPhysicalFileResult(PhysicalFileヘルパーメソッドの返り値)は絶対パスを指定しないといけない点です。これさえしておけば、上の記述だけで認証ユーザーのみにファイルを公開できます*1

f:id:tanaka733:20170109123353p:plain

*1:認証まわりは適切に設定されている前提で


.NET Core on Linux で systemd scriptでプロセス管理する (手抜き版)

$
0
0

ASP.NET Core でLinuxでホストする場合、以前の公式ドキュメントではsupervisorを使う方法が紹介されていました。ただ、CentOSやRHELだとEPELリポジトリにあるしなあと思っていたら、いつの間にか公式ドキュメントがsystemdを利用したサンプルに変わっていました。せっかくなので手順を一通りなぞってみます。

Publish to a Linux Production Environment | Microsoft Docs

手抜きポイント

  • リバースプロキシは設定しない (適当なポートでローカルからアクセスして動作確認)
  • firewalldも設定しない (これは独立して設定できる)
  • SELinuxまわりは追加の設定しない (詳細は最後に)

SELinuxは追加の設定をしないというだけで、enforcingの状態です*1

# sestatus 
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

実行バイナリとユーザーの用意

systemd のscriptを使うだけならdotnet publishせずにdotnet runでプロジェクトを指定して実行することもできます*2が、せっかくなのでpublishして実行バイナリ一式を適当な場所に配置して、専用のユーザーで実行してみることにします。まずはpublishします。

$ dotnet publish -c Release

bin/Release/netcoreapp1.1/publish/以下に必要なバイナリ一式が生成されるので適当な場所に配置します。/var/www-aspnetを作って配置してみました。

$ sudo mkdir -p /var/www-aspnet/
$ sudo cp -R bin/Release/netcoreapp1.1/publish/* /var/www-aspnet

dotnetプロセスの実行用に専用のユーザーdotnetuserをログインシェルなしで作ってみます。

$ sudo useradd -s /sbin/nologin dotnetuser
$ sudo chown -R dotnetuser /var/www-aspnet

systemd scriptの作成と実行

それではsystemdのscriptを記述します。/etc/systemd/systemaspnet.serviceという名前で以下のように記述します。実行するコマンドのパスはフルパスで、以下の例はRed Hat Software Collections でインストールした時のパスです。

[Unit]
Description = hello aspnet core
Documentation = 

Wants=network.target  
After=network.target  

[Service]
ExecStart = /opt/rh/rh-dotnetcore11/root/usr/bin/dotnet AspNetLabo.dll 
WorkingDirectory = /var/www-aspnet/AspNetLabo/publish/ 
Restart = always
RestartSec = 10
User = dotnetuser
Group=dotnetuser
Environment=ASPNETCORE_ENVIRONMENT=Production

[Install]
WantedBy = multi-user.target

記述したらsystemctlで起動します。起動したかどうかの確認もできます。scriptファイルを修正した時などはdaemon-reloadしておきます。

$ sudo systemctl daemon-reload
$ sudo systemctl start aspnet.service
$  systemctl status aspnet.service 
● aspnet.service - hello aspnet core
   Loaded: loaded (/etc/systemd/system/aspnet.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2017-01-10 19:40:46 JST; 7s ago
 Main PID: 6815 (dotnet)
   CGroup: /system.slice/aspnet.service
           └─6815 /opt/rh/rh-dotnetcore11/root/usr/bin/dotnet AspNetLabo.dll

Jan 10 19:40:46 localhost.localdomain systemd[1]: Started hello aspnet core.
Jan 10 19:40:46 localhost.localdomain systemd[1]: Starting hello aspnet core...
Jan 10 19:40:46 localhost.localdomain dotnet[6815]: info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
Jan 10 19:40:46 localhost.localdomain dotnet[6815]: User profile is available. Using '/home/dotnetuser/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Jan 10 19:40:47 localhost.localdomain dotnet[6815]: Hosting environment: Production
Jan 10 19:40:47 localhost.localdomain dotnet[6815]: Content root path: /var/www-aspnet/
Jan 10 19:40:47 localhost.localdomain dotnet[6815]: Now listening on: http://localhost:5000
Jan 10 19:40:47 localhost.localdomain dotnet[6815]: Application started. Press Ctrl+C to shut down.

起動に失敗したときなどにログを見たい場合はjournalctlコマンドを使います。-uオプションでユニットを指定、-fでtailできます。デフォルトのテンプレートで作ったままなので比較的ログが多くでています。

$ $ journalctl -u aspnet.service -f
-- Logs begin at Tue 2017-01-10 18:29:33 JST. --
Jan 10 18:58:19 localhost.localdomain systemd[1]: Stopping hello aspnet core...
Jan 10 18:58:19 localhost.localdomain systemd[1]: Stopped hello aspnet core.
Jan 10 19:40:46 localhost.localdomain systemd[1]: Started hello aspnet core.
Jan 10 19:40:46 localhost.localdomain systemd[1]: Starting hello aspnet core...
Jan 10 19:40:46 localhost.localdomain dotnet[6815]: info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
Jan 10 19:40:46 localhost.localdomain dotnet[6815]: User profile is available. Using '/home/dotnetuser/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Jan 10 19:40:47 localhost.localdomain dotnet[6815]: Hosting environment: Production
Jan 10 19:40:47 localhost.localdomain dotnet[6815]: Content root path: /var/www-aspnet/
Jan 10 19:40:47 localhost.localdomain dotnet[6815]: Now listening on: http://localhost:5000
Jan 10 19:40:47 localhost.localdomain dotnet[6815]: Application started. Press Ctrl+C to shut down.

これで無事systemdで.NET Coreプロセスを起動できました。常時起動のプロセスである必要もないので、バッチとして.NET Coreプロセスを起動することもできるはずです。

systemd scriptの書き方については下記のブログが参考になると思います。

qiita.com

enakai00.hatenablog.com

SELinuxとの関係

最初にSELinuxはenforcingだが追加の設定はしないといいました。dotnetプロセスのSELinuxでの状態を見てみましょう。

$ ps -eZ | grep dotnet
system_u:system_r:unconfined_service_t:s0 6815 ? 00:00:00 dotnet

unconfined_service_tというタイプでdotnetプロセスが実行されています。これは制限のないプロセスと呼ばれ、SELinuxが有効な状態でも制約なくファイルにアクセスできます*3

3.2. 制限のないプロセス

ですので、SELinuxを使ってdotnetプロセスに制限をかけようとする場合は、dotnetプロセスが特定のSELinuxコンテキストで実行されるようにしないといけません。そもそも、dotnetプロセスがデフォルトのターゲットでは制限のないプロセスとなっているので、手作業で設定する必要が現時点ではあります。単純にsytemdサービスの起動時に特定のコンテキストにするのであれば下記のブログが参考になりそうです。

qiita.com

とはいえやはり手間ですね...ということで、現時点での解としてはdockerコンテナを使って運用することにして、dockerコンテナごと管理する方法が取れると思われます。例えば、dotnet含めてOpenShiftであればdockerコンテナ内で起動するプロセス、実行するdockerコンテナ内のファイル、Volumeとして接続したファイル、がSELinux管理下におけます。こちらも検討するのがよさそうです。

*1:とりあえずSELinux 無効化というのはそろそろなしじゃないかなあというのが正直な気持ちの今日この頃です

*2:その場合プロジェクトをビルドして実行される

*3:PhysicalFileResultなどで任意のファイルを返せる

Fiddler on Linux beta が出たのでFedoraで使ってみた

$
0
0

Fiddler on Linuxのベータ版がリリースされたようです。HTTP通信に特化している分使い易くなっているのが個人的に好きです。

www.telerik.com

実はアルファ版が以前に出ていたようでした。

Fiddler for Linux Updated

というわけで早速Fedora 24に入れてみました。まずはmonoが必須です。Updatesリポジトリにあるはずです。

$ cat /etc/fedora-release
Fedora release 24 (Twenty Four)
$ sudo dnf install mono
$ mono --version
Mono JIT compiler version 4.2.4 (tarball Thu Jun 23 18:49:17 UTC 2016)

Getting Startedの手順に/usr/lib/mono//mozroots --import --syncってあるんですがこんなパスはなくて、しかもmozrootsはdeprecatedって言われるのでcert-syncを使います。

$ cert-sync /etc/pki/tls/certs/ca-bundle.crt

あとは、fiddler for linux のzipをダウンロードして、解凍して、mono Fiddler.exeで実行します。無事実行できました。

f:id:tanaka733:20170112150144p:plain

なのですが、割とすぐにエラーが出て、Windowが消えてしまいました。

$ mono Fiddler.exe
can not parse as value of type 'i':
  ""
  ^^
can not parse as value of type 'i':
  ""
  ^^

この後、ブラウザでWebページが見れなくなりました。回避策としてはもう一度Fiddlerを起動して正常終了させることです。恐らくFiddlerはプロキシとして動作するので、プロキシサーバーを設定して解除しないうちにプロキシが死んだのが原因な気がします。

Feedbackはこのフォーラムにするようです。ほとんどスレッドが立っていないのが気になりますが。

www.telerik.com

ASP.NET Core でローカライズする場合のリソースファイル名について

$
0
0

ASP.NET Coreのローカライズする際のリソースファイル名についてこのドキュメントを読んで気になったことがあったのでまとめました。

Globalization and localization | Microsoft Docs

ローカライズそのものについてはこのドキュメントを参考にしてください。また、ローカライズに必要なNuGetパッケージですが、MVCの機能を使うためにMicrosoft.AspNetCore.Mvcを追加している場合は、依存しているMicrosoft.AspNetCore.Mvc.Localizationとさらにこれが依存しているMicrosoft.AspNetCore.Localizationがインストールされるので特に追加は不要です。MVCを使わずにローカライズしたい場合はMicrosoft.AspNetCore.Localizationが必要です。

はじめに

ASP.NET Coreでローカライズする場合、IStringLocalizer<T>IHtmlLocalizer<T>を指定してDIでローカライザーを注入します。この時、クラスTごろにリソースファイルを準備します。Viewの場合はIViewLocalizer、ViewModelの場合は特に指定は不要ですが、クラスごとにリソースファイルを準備するのは同じです。さて、このクラスTごとにリソースファイルを準備する際に、ファイル名が規約で決まっており規約に従っていないと正しく読み込めません。ここで少しはまったので説明します。

起点フォルダ

まず、リソースファイル名を置く起点となるフォルダですが、これはStartup.csResourcesPathに指定したフォルダ名になります。これは空白でも可能でその場合はプロジェクトのルートフォルダと同一になります。以下の説明では下記のコードの通り "Resources"を指定しているものとします。

publicvoid ConfigureServices(IServiceCollection services)
{
    //省略
    services.AddLocalization(options => 
    {
        options.ResourcesPath = "Resources";
    });
    //省略
}
ファイル名とアセンブリ名とクラス名と

そしてここを起点としたリソースファイルのファイルパスですが、これがリソースを指定するクラスTのクラス名が、アセンブリ名で始まっているか否かで分かれます。

どういうことかといいますと、例えばdotnet new -t webでASP.Core MVCプロジェクトを作成するとまずアセンブリ名はプロジェクトを作成したフォルダ名と一致します。これはproject.jsonにnameプロパティが指定されていないため、フォルダ名が利用されるためです*1

docs.microsoft.com

しかし、デフォルトの名前空間はWebApplicationで固定であるため、クラス名がアセンブル名で始まらないケースになってしまいます。一方、Visual StudioでASP.NET Coreプロジェクトを作成するとデフォルトではプロジェクト名がアセンブル名かつデフォルトの名前空間になるので、デフォルトの名前空間以外の名前空間にわざわざクラスを作らない限りは同じになります。

クラスTのFQDNがアセンブル名で始まる場合

例として、アセンブリ名がAspNetCore.StarterWebだとして、リソースを作りたいクラスがAspNetCore.StarterWeb.Controllers.HomeControllerでjaロケールのリソースを作りたいとしましょう。この場合リソースファイルはプロジェクトのルートから見て、Resources\Controllers\Homecontroller.ja.resxもしくはResources\Controllers.Homecontroller.ja.resxとなります。Resources以下を.区切りにしてフラットに配置するか\でフォルダ階層を切って配置するかはどちらでもよく、1つのプロジェクトで混在させることも可能です。つまり、クラスTのFQDNからアセンブリ名を省略した名前となります。これは省略できるではなく省略しないといけません

クラスTのFQDNがアセンブル名で始まらない場合

例として、アセンブリ名がAspNetCore.StarterWebだとして、リソースを作りたいクラスがWebApplication.Controllers.HomeControllerでjaロケールのリソースを作りたいとします。この場合はFQDNを省略できなく、Resources\WebApplication\Controllers\Homecontroller.ja.resxもしくはResources\WebApplication.Controllers.Homecontroller.ja.resxとなります。

まとめ
  • .NET Coreのアセンブリ名はproject.jsonのnameプロパティの値が使われる。指定していない場合はプロジェクトのルートフォルダのフォルダ名。
  • ASP.NET Coreのリソースファイルの名前は、クラスのFQDNがアセンブリ名で始まっている場合はアセンブリ名を省略する
  • そうでない場合は省略しない

ドキュメントがちょっとわかりにくいなあということでissueを投げているので、そのうち改善すると思われます。

github.com

*1:そのためフォルダ名に空白が入っていたりするとデバッグ実行のパス指定がデフォルトでは動かなくなったりと何かと面倒

VisualStudio 2017 RC3 から .NET Core on RHEL にリモートデバッグする

$
0
0

VisualStudio 2017 RC3からリモートデバッグのプロトコルにSSHが選択できるようになり、Linux上の.NET Coreプロセスにアタッチすることができるようになりました*1

blogs.msdn.microsoft.com

これは、以前ブログに書いたdocker上の.NET Coreプロセスをリモートデバッグするのと同じ仕組みだと思われます。

tech.tanaka733.net

で、MSDNブログではUbuntuが取り上げられていますが、RHELでもできることを確認したのでその手順をまとめておきます。現状では、VisualStudioで発行したバイナリを転送して実行するのが一番速そうです。これはWindowsとRHELの.NET Core SDKがまだVisual Studio 2017 RC3のcsprojの構造に追い付いていないようで、VisualStudioで認識できるプロジェクトをdotnetコマンドでビルドできなかったからです*2

まず、RHEL側の準備ですが、.NET Core 1.1をインストールしておきます。

Chapter 1. Install .NET Core 1.1 on Red Hat Enterprise Linux - Red Hat Customer Portal

つぎに、以前dockerにリモートデバッグする場合はclrdbgをインストールしておきましたが、新しいVisualStudioの機能を使う場合は接続時に必要に応じてインストールしてくれるので事前にインストールしておく必要はありません。その代わりインストールに必要なコマンドとして、unzipとcurlもしくはwgetのインストールが必要です。curlやwgetは割とインストールされていることが多いと思いますが、unzipが入っていないことがあるのでいれておきましょう。sshサーバーの設定も必要なので、こちらを参考にどうぞ。

9.2. OpenSSH の設定

$ sudo yum install openssh-server unzip curl

次にVisualStudio側でプロジェクトを作成します。今回は.NET Core 1.1でASP.NET Core Webの空アプリケーションを作成しました。作成した後、プロジェクトを右クリックして「公開」を選び、発行先にフォルダーを選びます。

f:id:tanaka733:20170127224043p:plain

デフォルトだとReleaseビルドになるので、Debugビルドに直しておきます。

f:id:tanaka733:20170127223838p:plain

f:id:tanaka733:20170127223900p:plain

あとは発行ボタンを押して実行用のバイナリを生成します。

f:id:tanaka733:20170127223920p:plain

で、バイナリ一式をRHELに転送します。面倒なのでプロジェクトまるごとSCPで転送しました。WindowsでSSHするのはBash on Ubuntu on Windowsを使いました。/mnt/<ドライブレター>以下にWindowsのファイルシステムが見えます。

# scp -r WebApplication1 <user>@<server>:~/

あとはRHEL側に入ってdotnetコマンドで実行します。

$ dotnet WebApplication1/bin/Debug/netcoreapp1.1/WebApplication1.dll

VisualStudioに戻って、デバッグ>プロセスにアタッチを選びます。出てきた画面でRHELサーバーのホスト名を入力しEnterを押します。検索ボタンを押すのではないのに注意しないといけないのは今までと同じです。

f:id:tanaka733:20170127224735p:plain

するとこんな画面になるので、Password認証かPrivateKey認証を選んで接続します。その後プロセスの一覧が表示されるので、該当のプロセスを選択してアタッチします。

f:id:tanaka733:20170127224637p:plain

最後にコードの種類を聞かれるので、.NET Core on Unix を選びます。

f:id:tanaka733:20170127224906p:plain

これでリモートデバッグが開始されるので、あとはブレークポイントを置いたりできます。ちなみにunzipコマンドが入っていなかったりするとこの時点でエラーになってデバッグ出力の欄に表示されるので、確認しましょう。

*1:ブログのタイトルにPrivateがついていたり、1/31になっているのが気にならないことはない

*2:そのうち改善されるでしょう

Visual Studio 2017 リリース記念勉強会 にて登壇します

$
0
0

もう定員オーバーなのですが、今回まどすたと行き来自由ということなので、どちらのセッションを選ぶかの参考にもなるように発表内容を紹介しようかと思います。

csugjp.connpass.com

Visual Studio 2017 リリース記念!とうたっているのですが、私はLinux担当ということであまりVisual Studioは出てこなかったりします。テーマとしては、実際に.NET CoreのアプリをLinux環境、とくにdocker環境に配置する場合を想定した開発に使える.NET Coreの機能などを紹介しようと思っています。また、docker単体というのも最近ではあまり聞かなくなって、いわゆるkubernetesやOpenShift, Azure Container Servicesなどコンテナークラスターが良く使われている気がします。というわけでOpenShiftやAzure Container Servicesへの配置もちょっと見せたいなと思っています。

お品書きはこんな感じ。ほかの登壇者の方との調整や、直前の機能リリースなどで変更する可能性はあります。

  • Visual Studio 2017リリースでのLinux関連の新機能まとめ
  • Previewじゃなくなった.NET Core Tooling まとめ
    • project.json終了。MSBuildとcsprojへ。
    • dotnet new コマンドなど使い勝手が変わったコマンド紹介
  • docker(クラスター)への配置を見据えて使えそうな機能
    • 環境ごとのConfiguration切り替え
    • セッションをRedisなどASP.NET Coreプロセス外で管理する方法
    • など
  • ビルドとdockerイメージ作成
    • dockerイメージ作成法 (ちょこっと)
    • private NuGetサーバーの利用
  • dockerやLinux環境への配置
    • SELinux*1と.NET Core プロセス
    • systemd による.NET Coreプロセスのサービス化
    • Azure Container ServiceやOpenShiftへの配置例 (ちょこっと)
  • デバッグ
    • Visual StudioとVisual Studio Codeのデバッグの仕組み
    • Visual StudioからLinux上のASP.NET Coreプロセスへのリモートデバッグ
    • Visual StudioからOpenShift上のdocker上のASP.NET Coreプロセスへのリモートデバッグ
    • Visual Studio Codeからdockerへのデバッグ

というわけで興味のある方はぜひどうぞ。

*1:enforcing前提

SQL Server Availability Group を RHEL Clusterで作ってみる

$
0
0

注意: SQL Server Availability Group をRHEL Clusterで作る場合はHA add-on が必要ですが、このアドオンはAzure上ではサポートされていません。ということでサポート対象外だけど試したいという場合にAzure上でどうぞ。全体の作り方はAzure上に限らないはずです。

公開直後になんとなく作ったのですがそのときは挙動があやしかったので再度作り直してみた結果をまとめてみます。

作業の流れとしては、

  1. Clusterを構成する各NodeにSQL Serverをインストールする
  2. Availability Groupを構築する
  3. Cluster化する

となります。最後のCluste化するところではプラットフォームごとに利用するPacemaker管理ソフトが異なります。RHELの場合はpcsを使います。このエントリを読む前にこちらで概要を把握するのがよいと思われます。

blog.engineer-memo.com

作業の流れ自体はこちらに書いてある通りになります。このドキュメントが公開された当初はいろいろ記述が足りなかったのですが、今やった限りでは一通り揃っているようです。とはいえ、いろいろハマリどころが多かったのでその辺をまとめておきたいと思います。

Configure availability group for SQL Server on Linux | Microsoft Docs

ホストの用意とSQL Serverのインストール

今回はAzure上のVMで構築しました。問題としては最後にVIPを割り振った後、VIPでのアクセスが同じネットワーク内の別ホストからできないことなのですが、これはAzureのNetworkを勉強しないといけなさそうです。また同じVNETのSubnet内にNodeを配置するので、ホスト名での通信はデフォルトのAzure DNSでできる状態です。VMを起動したら、このドキュメントに沿って、各NodeにSQL Serverをインストールします。

docs.microsoft.com

また、sqlcmdで接続して処理を進める必要があるのでSQL Server Toolsも各ホストにインストールしておきました。

docs.microsoft.com

Availability Groupの構築

次にこのドキュメントに沿ってAvailability Groupの構築を行います。ちなみにこの中の手順で失敗して、復旧が難しい状態になったらSQL Serverのアンインストールをして最初からやりなおすことをオススメします。。。

Configure availability group for SQL Server on Linux | Microsoft Docs

手順をまとめると

  1. Always On availability groupsを有効化してmssql-serverサービス再起動(全Node)
  2. AlwaysOn_health event sessionの有効化(任意、やる場合は全Node)
  3. db mirroring endpoint user作成(全Node)
  4. Masterでのcertificate作成とMaster以外のNodeへの転送(Masterのみ)
  5. Secondary Nodesでのcertificate作成(Master以外の全Node)
  6. database mirroring endpoints作成(全Node、設定するIPアドレスはNode自身のアドレス*1なのでNodeにより異なる)
  7. availability group作成(Masterのみ、ノード名やリスナーのIPを環境に合わせて設定する)
  8. Secondary Server(s)をAvailability Groupに追加(Master以外の全Node)
  9. DBを作成し、Availability Groupに追加(Masterのみ)
  10. 追加したDBがSecondary Nodeからアクセスできることを確認(Master以外のNode)

となります。mirroring endpointの作成あたりから操作うまくいったか不安になるのですが、まずendpointができているかどうかはSELECT * FROM sys.endpointsでわかります。

f:id:tanaka733:20170313185449p:plain

作ったエンドポイントのstate_descSTARTEDになっていればOKです。おかしい場合はDROP ENDPOINT Hadr_endpointで消せるはずです。ちなみにちゃんとうごいていると上のクエリがすぐに結果を返しますが、変な状態になっていたら結果がかえるのにやたら時間がかかる状態になっていました。

また、Availability Group自体はこの時点で動いているのでその状態を確認することもできます。このブログを参考にしました。

blog.dbi-services.com

なんとも見辛いですがこんな感じで表示されます。この環境はdb1とdb2を追加しています。

f:id:tanaka733:20170313190025p:plainf:id:tanaka733:20170313190032p:plainf:id:tanaka733:20170313190042p:plain

Cluster化

RHELではCluster化を行うのに、Pacemakerを利用して作られたHA add-onを使います。というわけでご利用の際には該当のSubscriptionが必要になります。

また、このCluster化の手順で失敗した場合、Availability Group本体に影響がなければこの手順のみをやりなおすことができます。その場合はまず、pcs cluster delete --allをMasterで実行するか、pcs cluster deleteを各Nodeで実行するとよさそうです。クラスターを削除した場合、pacemakerがdisableになっているのでsudo systemctl enable pacemakerを再実行します。また、pcs cluster authはclusterを削除しても認証が残ったままになりますが、ここもやり直したい場合は--forceオプションをつけることができます。

STONITH(Shoot-The-Other-Node-In-The-Head)の無効化ですが、テスト目的ではドキュメントどおり無効化すればよいのですが、本番環境では設定しておくべきでしょう。なぜかリンク先はRHEL6ですが、RHEL7向けのドキュメントはこちらです。

第4章 フェンス機能: STONITH の設定

また、こちらのドキュメントなどを見ると、Azure上ではVMをShutdownさせてるようにするの一つの方法のようです。

負荷分散セットを使用して MySQL をクラスター化する | Microsoft Docs

あとはドキュメント通りに、PacemakerがヘルスチェックするためのSQL Serverログインユーザーを作成し、pcsのavailability groupリソースと virtual IPリソースを作成します。ここまで来ればpcsの状態でも確認できます。

f:id:tanaka733:20170313191434p:plain

VIPが着いている側のNICにVIPに設定した172.17.2.50が割り振られているのがわかります。

リソースを手動でFailoverするとsolnode2に移動するのもわかります。

f:id:tanaka733:20170313191701p:plainf:id:tanaka733:20170313191707p:plain

solnode2側で見ればVIPがつけかわっています。

f:id:tanaka733:20170313191749p:plain

さて無事に動けばいいのですが、手順を誤まると動かないことがあります。実際にこんなエラーが出たことがありました。

f:id:tanaka733:20170313191914p:plain

こういうときはSQL Serverのエラーログを見てみましょう。/var/opt/mssql/log/errorlogにあります。

というのがSQL Server Availability Group on RHEL Clusterを作ってみた感想になります。特にCluster化はHA add on を使うのでドキュメントに倣うだけでもある程度知っておくことが必要で、実際に使いこなすにはさらに習得しておく必要を感じました。

*1:このアドレスはクラスタ内の別Nodeからアクセスできるアドレス

Visual Studio 2017 で ASP.NET Coreプロジェクトでdockerデバッグしたいときはソリューションディレクトリを作らないといけない件

$
0
0

タイトルだけで言いたいことは以上なんですが、Visual Studio 2017でASP.NET Coreプロジェクトを作ってdockerサポートを有効化すると、こんな風にdocker-composeプロジェクトが作られてDocker for Windowsの上のDockerコンテナを使ってデバッグ実行ができるようになります。

f:id:tanaka733:20170319223510p:plain

なんですが、これは新規プロジェクトを作成する際にソリューションのディレクトリを作成にチェックボックスを入れておかないといけません。 f:id:tanaka733:20170319223548p:plain

ここをチェックボックスを入れなくても、次のプロジェクトのプロジェクトの詳細を選択する画面でDocker Supportにチェックボックスを入れられるのですが、その場合 docker-composeプロジェクトが作成されません。 f:id:tanaka733:20170319223907p:plain

ソリューションディレクトリがないと作られるソリューションはASP.NET Coreプロジェクト本体のみになります。 f:id:tanaka733:20170319224239p:plain

Visual Studio 2017のDockerデバッグはdocker-composeプロジェクト側に仕掛けがあるようで、ソリューションディレクトリがない状態だとDockerでデバッグできません。というわけでDockerでデバッグしたい場合はソリューションディレクトリを作るようにしましょう。


Azure CLI 2.0 で自分のイメージにRHELやCentOSと名付けたら、意図せずMarketplaceからVMが起動される件

$
0
0

最近はまってしまって、意図しない課金が発生したのでMicrosoft supportとやりとり中なのですが、公開できる部分に関してこちらで調査した結果わかったAzure CLIの挙動についてメモしておきます。

最近発表された、管理ディスクとイメージの機能によって、OSをカスタマイズしたVHDからVMを起動していた場合、イメージとして汎用化して保存しておくことができるようになりました。これにより、今迄起動するVMを同じリソースグループかつロケーションにVHDを配置しないといけなかったのが、異なるリソースグループにあるイメージからVMを起動できるようになりました。 docs.microsoft.com

そこで、今迄つかっていたカスタムイメージのVHDファイルを使って、rhelという名前のイメージを作成しました。Azure CLI 2.0 で確認するとこうなります。

$ az image list
Location    Name        ProvisioningState    ResourceGroup
----------  ----------  -------------------  ---------------
japanwest   rhel        Succeeded            RHEL-BASE

で、これを使ってVMを起動します。ポータルから起動する場合は下の図のようにイメージのメニューにあります。 f:id:tanaka733:20170330174101p:plain

なのですが、NICを複数つけたい場合などポータルではサポートされていない機能を使いたい場合はAzure CLI 2.0を使うことになります*1。イメージを指定する場合のAzure CLI 2.0のコマンドについては下記ドキュメントに記載があります

docs.microsoft.com

で、おそらく必要最低限のオプションを指定するとこうなります。

$ az vm create -n testvm3  -g rhel-base -l japanwest --image rhel --storage-sku Standard_LRS --size Standard_A1 --authentication-type password --admin-password clouduser

これでVMが無事起動…と思いきや、よくVMの中を見てみるとこのVMはMarketplaceに登録してあるRed Hat Enterprise LinuxのVMになっています。注意すべきこととしては、MarketplaceのVMは追加でRed Hatのサブスクリプションが上乗せされています*2。これはなぜかというと、Azure CLI 2.0(もしくはサーバー側)でいくつかのMarketplaceのイメージに対してエイリアスが登録されていて、そのエイリアスと自分の作成したイメージ名が重なった場合、エイリアスの方が優先される挙動となっているためのようです*3

エイリアスとしては下記のものが登録されているようですが、このあたりは将来的に追加、変更などがあるでしょう。

  • ‘Win2016Datacenter’
  • ‘Win2012R2Datacenter’
  • ‘Win2008R2SP1’
  • ‘Win2012Datacenter’
  • ‘UbuntuLTS’
  • ‘CentOS’
  • ‘openSUSE-Leap’
  • ‘RHEL’
  • ‘SLES’
  • ‘Debian’
  • ‘CoreOS’

ドキュメントには「イメージとは別のリソース グループに VM を作成するには、イメージに対する完全なリソース ID を指定します。」と書いていますが、同じリソースグループにVMを作成する場合でもエイリアスの方が優先されるので注意が必要です。

というわけで、現状の挙動をふまえて、意図しないMarketplaceからのVMの起動を防ぐには下記の対策が有効ではないでしょうか。

  • 自分の作成するVMにはrhelやCentOS、Win2016Datacenterといったエイリアスと重なりそうな名前はつけない
  • Azure CLI 2.0でイメージを指定する場合、イメージ名ではなくリソースID /subscriptions/GUID/resourceGroups/ResourceGroupName/providers/Microsoft.Compute/images/ImageName) を指定する

個人的にはスコープが限定されているものが優先されて選択されるのが直感的なのですが、このあたりは好みによるのでしょうか… また続報があれば更新します。

*1:従来のAzure CLIだと使えなかったり、説明が足りていなかったりすることがあるので

*2:カスタムのRHELのVHDを使うということは、すでに持っているサブスクリプションをAzureに持ち込んでつかいたいはずで、Marketplaceのサブスクリプションを使うことは想定していないと思われます

*3:サポートに確認中

docs.com に「password」といった単語が含まれるドキュメントをアップロードすると機密情報を含む文書として一般公開できなくなる問題

$
0
0

昨日、Global Azure Boot Campの資料を公開しようとしたら突然こんな画面が出ました。

f:id:tanaka733:20170423224227p:plain

「???」と思い、リンク先のページを見ると、どうも最近のリリースで機密情報保護機能というのがはいって、おせっかいにもdocs.comが機密情報を含んでいると判断すると問答無用で一般に公開できなくなります。これはすでに公開済みの文書にも適用されていて、該当する文書は一般公開が停止されているはずです。

Docs.com flagged this content as possibly containing sensitive information

とりあえずいったんは、リンクを知っている人のみ公開にしてドキュメントを共有したのですが、そうすると検索エンジンからの流入がなくなったり*1とせっかく資料を公開したのにメリットが少なくなります。というわけで、このあたりを調べた顛末をまとめました。

とりあえずオフィスの大家二人に聴いたところ、おひとりが有力情報を寄せてくれました。

なんと、「password」という単語が含まれるとNGらしいのです。実際、アップロードした資料にはAzureのVMを作る際のコマンドオプションに「password」という単語が含まれていました。じゃあということでいくつか試してみました。

passwordはだめ f:id:tanaka733:20170423224227p:plain

p@sswordはOK f:id:tanaka733:20170423224837p:plain

ConfidentialはOK f:id:tanaka733:20170423224856p:plain

ConfidentailとFor intenal use only はNG f:id:tanaka733:20170423224927p:plain

というよくわからないルールでNGになっていました。そもそも今回のコマンドのサンプルのように、「password」という単語が含まれていても機密情報を含んでいないケースは多々あるように感じます。さらに、この機能は無効化できないうえに、どの単語が原因で機密情報を含んでいるかという基準は公開されていません。docs.comはスライド共有ができるサービスとしては後発ながらも、スライド以外のオフィス文書やWebページをコメント付きで共有できるコレクションという機能を公開したりと文書の共有機能を強化していたのに、突然それを妨げる向きの機能がリリースされて一気に使い勝手が落ちてしまったように感じます。

この機能の廃止もしくは無効化をしてほしいというuservoiceを英語と日本語で上げたので、賛同いただける方はvoteしてもらえるとうれしいです。

新しい提案
  • 8 votes
  • 1 comment

「機密情報が含まれている可能性があるドキュメント」として一般公開されなくなる機能の廃止、もしくは無効化

下記のページで説明されている機能が最近リリースされたせいで、公開済みのドキュメントおよび新規に公開するドキュメントが「機密情報が含まれている可能性があるドキュメント」というメッセージにより一般公開されなくなってしまいました。
しかし、この機能は「password」という単語が含まれているだけで機密情報と判定してしまいます。passwordという単語そのものは機密情報でもなんでもありません。私は主に技術文書を一般公開しますが、コマンドやソースコードの中で「password」という単語があるだけで一般公開されなくなってしまい、非常に困っています。
そもそも機密情報保護の機能としては誤った...

docscom.uservoice.com

I would like...
  • 18 votes
  • 0 comments

Remove or Disable the feature "flagged this content as possibly containing sensitive information"

Recently docs.com released a new feature described in this link.
https://sway.com/2cdHbZ8pgWdATAsd

Many documents already published or publishing become "no longer available publicly".
I wonder this feature is unmeaningful and harmful because docs.com marked my document as sensitive only bec...

docscom.uservoice.com

個人的には、これが対応されないとdocs.com使うのやめようかなというぐらい使い勝手の悪さを感じるので対応されることを祈っています。(既存のドキュメントを移行させるのめんどい)

*1:そもそもdocs.comに検索エンジンからの流入が見込めるかは謎

clrdbg は vsdbg にリプレースされました

$
0
0

以前このような記事を書いて、先日同じ手順を実行しようとしたらVisual Studio Codeは最早clrdbgをサポートしなくなりました、といった類のメッセージが出てデバッグできなくなっていました。

tech.tanaka733.net

確認してみると、Visual Studio CodeのC#拡張の1.8でclrdbgがvsdbgにリプレースされていました。

omnisharp-vscode/CHANGELOG.md at master · OmniSharp/omnisharp-vscode · GitHub

詳細な手順はこちらにあります。

Attaching to remote processes · OmniSharp/omnisharp-vscode Wiki · GitHub

というわけで先のdocker上のプロセスにリモートデバッグする手順もclrdbgからvsdbgに置き換える必要があります。置き換える必要があるのは、まずdocker上にclrdbgをインストールする部分でvsdbgをインストールするコマンドに置き換えます。

$ curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg

さらに、Visual Studio Code側のlaunch.jsonは次のようになります。パスをvsdbgに置き換えるのに加えて、"quoteArgs": falseと設定する必要があります。これを設定しないと勝手に実行するコマンドが"で括られてしまうため、docker execコマンドの引数が正しく解釈されなくなってしまいます。

{"version": "0.2.0",
    "configurations": [{"name": ".NET Core Docker Remote Attach",
            "type": "coreclr",
            "request": "attach",
            "processId": "<PID>",
            "pipeTransport": {"pipeProgram": "docker",
                "pipeArgs": ["exec", "-it", "<name>"],
                "debuggerPath": "/opt/app-root/src/vsdbg/vsdbg",
                "pipeCwd": "${workspaceRoot}",
                "quoteArgs": false},
            "sourceFileMap": {"/opt/app-root/src": "${workspaceRoot}"
            }}]}

以上を設定すればvsdbgで利用可能になるはずです。なお、vsdbgのライセンスなのですが、おそらくRuntimeのライセンスが該当するものと思われます。

omnisharp-vscode/OpenDebugAD7-License.txt at v1.9.0 · OmniSharp/omnisharp-vscode · GitHub

これを読む限り、Visual StudioやVisual Studio Code以外での利用が禁止されているのと、共有や公開が禁止されているようです*1。そのため、vsdbgを同梱したdocker imageを公開するのも禁止されているような気がします*2。個人的には改善を期待しています*3

*1:解釈に関しては自己責任でお願いします

*2:Dockerfileに指定された手順を記載したDocker imageの公開がこのライセンスのshareやpublicに当たるかはよくわからない。が個人的にライセンスで危い橋は渡りたくないので

*3:Microsoftは今やOpen by defaultだ!と宣言していましたし https://www.forbes.com/sites/adrianbridgwater/2016/11/08/microsoft-is-now-open-by-default-says-xamarin-founder-miguel-de-icaza/#595733e97c40

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

Chatwork.Api をnetstandard1.6とnet45対応しました

$
0
0

ChatWorkのAPIエンドポイントがv2に変わる対応を公開したのですが、同時に0.5では.NET Frameworkでは使えなかったので0.6.1で.NET Framework 4.5でも使えるようにしました。

www.nuget.org

紆余曲折あった.NET Coreのプロジェクトファイルですが、*.csprojになったおかげで最終的にはNuGetライブラリの設定もcsprojの中で定義することができるようになったのですっきりしました。また、Visual StudioからNuGetパッケージの作成もできるようになりました。

CSharp.Chatwork.Api/Chatwork.Service.csproj at v0.6.1 · tanaka-takayoshi/CSharp.Chatwork.Api · GitHub

さて、.NET Coreと.NET Frameworkの両方に対応する方法ですが、csproj内のTargetFrameworks要素に併記すればOKです。対象が1つのときはTargetFrameworkでもいいのですが、複数のときは複数形のTargetFrameworksです。

<TargetFrameworks>netstandard1.6;net45</TargetFrameworks>

この辺の記載についてはこちらに記述があります。

docs.microsoft.com

ただ、これだけだと下記に報告されているように .NET Framework側のビルドでHttpClientクラスがみつからないエラーが出ます。

github.com

とりあえずのworkaroundとして.NET Frameworkのときだけ明示的にSystem.Net.Httpを追加すると動くようです。

<!-- see https://github.com/dotnet/cli/issues/6033 --><ItemGroup Condition=" '$(TargetFramework)' == 'net45'"Label=".NET 4.5 Package References"><Reference Include="System.Net.Http" /></ItemGroup>

さて、この複数のTargetFrameworkの指定、VisualStudio 2017 Preview (15.3)からデバッグ実行などが容易になったとRelease Notesに書かれています。

blogs.msdn.microsoft.com

なのですが、まだバグがあってTargetFrameworksを複数指定しているとNuGetのリストアが片方で実行されないようで、Issueを報告しておきました。

developercommunity.visualstudio.com

これのworkaroundとしては、直接dotnet restoreコマンドを実行するとリストアが正常に完了されました。NuGetパッケージの作成もdotnet pack -c Releaseで実行できます。

Red Hat Summit や //Build 2017 での発表まとめ

$
0
0

Red Hat SummitやらMicrosoftのBuild 2017でいろいろ、Red Hat on Azure, .NET Core, SQL Server on RHEL などなどのセッションがあったので、それぞれの走り書きメモをまとめています。随時更新中。Red Hat Summitは公開されているセッションがすくないので、一つにまとめています。Buildの方は下記のフィルタをかけたものからさらに関係ありそうなものを選んでいます。

Build 2017 | Channel 9

Red Hat Summit

Azure Ref Arch が公開されました。

Deploying Red Hat OpenShift Container Platform 3 on Azure - Red Hat Customer Portal

SQL Server Container をOpenShift上で動かすデモを実行。Public Previewとして誰でも利用できます。

AzureへのOpenShiftのセットアップは、Azure の ARM Template と Red Hat Ansible Installer Scriptの組み合わせで。

OpenShift上のアプリから、Microsoft Bot Framework と Azure Functions を使った Skype Bot を利用。

.NET Core 2.0への対応作業も開始。すでに、s2i imageは.NET Core 2.0 Previewのinitial support branch

OpenShiftからWindows container を扱うデモ。

Windows containerについてはこちら。

DockerCon17 - Beyond the backslash - Docs.com

Build 2017

Azure

Azure CLI 2.0

JEMSPathによるフィルタリングやOutputフォーマットの指定など。 Tab補完や、in-lineでのドキュメントの強化。 IntaracticeモードやCloud Shell。

Azure Compute: New features and roadmap

新機能の紹介

  • NVIDIA GPUとかIB Connectivity とか大容量SSDとかSAP向けとか新しいVMサイズ
  • Dv3とEv3でNested Virtualization
  • Azure Cloud Shell with PowerShell
  • Cross Region Site Recovery
  • Instance Metadata
  • Service Fabric: Windows Server Containers GA, Docker composeのプレビューサポート, Direct Azure endpoint, Hyper-V Isolation
  • OpenShiftやCloufFoundryもあるよ
  • Azure Batch/Low Priority Batch
  • AutodeskによるAzure Batch Rendering Service
  • Web Apps & Lunux container: CI/CD with VSTS and Docker Hub, Direct SSH
  • ローカルで実行できる Azure Functions Runtime Preview
  • Azure Managed Applications & Service Catalog

Introducing Azure Network Watcher

Network topologyの可視化 診断ツール(フィルタリングできるパケットキャプチャとか) メトリクス ログ 8月まで無料

Leverage Azure instance metadata for instance bootstrap and runtime

インスタンスメタデータはVMから認証なしで取得できるREST API。 予定されているメンテナンス情報や、VM自身の方法を取得できる。 今でも使われている 169.254.169.254 というアドレスが正式なサービスとして展開されるイメージ? Azure Instance Metadata Service Overview | Microsoft DocsScheduled Events with Azure Metadata Service | Microsoft Docs

Big data workloads with Azure Blob Storage | Build 2017 | Channel 9

  • IaaS: Disk, Files
  • PaaS: Blobs, Tables, Queue

Blob Storage?

  • Block blobs: 一般的
  • Append Blobs: 追記
  • Page Blobs: ランダムリード、ライト

Blob Storageのキーコンセプト

  • strong consistency
  • 複数の冗長化の種類
  • Tiered Storage - Hot & Cool
  • 複数のプラットフォーム、言語のサポート

技術的な考慮点

  • 最上位にコンテナというディレクトリ/隔離できる構造がある
  • multipart uploadと範囲指定取得
  • Blobはmutable
  • ETAGとtimestampによる楽観的一貫性
  • 時間もしくは無期限のロック

その他、新機能の予定など

  • Big Data関連のサービスはAzure上に複数あるが、Blobがそれらを支えている
  • AzCopy がLinuxでもサポート(Preview, CoreCLR依存)
  • Blobのゴミ箱サポート
  • Hot/Coolに加え、Archived Storageもサポート予定

Blobの耐久性など

  • 3 replica+ erasure coding
  • MD5ハッシュ
  • CRC checksum
  • GRSによるDisaster Recovery
  • 99.9%のSLA、RG-GRSではReadが99.99%

セキュリティ関連機能の予定など

  • BlobのMS提供キーによる暗号化をサポート予定
  • Secure Transferオプション
  • Network Access Control: 特定のVNETからのアクセスのみ
  • AADのよる認証とBlobへのRBAC

VM storage optionも4TBまでなどと増強予定

Large Block Blobが5TBまで

Storage Accountも5 PBまで

Azure VNet for containers

  • 今迄は Bridge/NAT 接続か、Overlay network modeだった => ACSでSDNも利用可能に (public preview)
  • CNI(k8s, DC/OS), CNM(Docker Engine)といったプラグイン
  • LinuxおよびWindows向け
  • AzureおよびAzure Stack で利用可能

Azure Active Directory v2 endpoint and MSAL: What’s new

  • AAD v2 dev guide: aka.ms/aadv2
  • AADv2は Azure ADのwork&schoolアカウントに加えて個人アカウントでも利用可能
  • クライアントライブラリはMSALと呼ばれるものに変更
  • resourceの代わりにscopeに
  • staticな同意からdynamicな同意に?
  • id_tokenはOpenID connect standardに準拠
  • 1つのアプリでWebとNativeに対応

MSAL はProduction利用可能なPreview。ただし、AADとMSアカウントの両方に対応させる必要がないなら、まだv1がよい。

How containers transform operations and development

What’s container? - アプリのパッケージや配置の単位として使う、 アプリの境界を統一する, Runtime の隔離 What’s container orchestration? - マシン単位での管理をcontainer APIに統一する OPs - Hardware/OSはIaaSに、OSやクラスタリングの設定はコンテナに、クラスタの実行やアプリケーションはDevOpsチームに

=>コンテナクラスタを実行するOSとその管理をAzure Container Servicesに任せよう

Azure Container Service for your cloud native, data intensive, or modernization needs | Build 2017 | Channel 9

VerisonによるACS上でのDC/OSの事例

ASP.NET Core + Azure Service Fabric

  • ASP.NET CoreのMVCやWeb APIをFrontにおき、backendにWeb APIを配置したService Fabric
  • Service Fabicは信頼されたサービス(Reliable Service)として起動
  • ICommunicationListenerを実装したサービスインスタンスを作成し、その中に複数のASP.NET Coreサービスを配置
  • Stateful replicaの場合Change roleライフサイクルでPrimary/Secondary/None を選ぶ
  • NamingServiceを介してサービスを登録/発見する

推奨:

  • WebListener: Internetに面する永続的なエンドポイント。DoS対策や認証なども。
  • Kestrel: 内部向けのエンドポイント

Design for serverless success on Microsoft Azure

Blockchain on Azure

NET Core

Three Runtimes, one standard… .NET Standard: All in Visual Studio 2017 | Build 2017 | Channel 9

.NET Standard とは?

NetStandard.Library というNuGetパッケージはnetstandard.dllを含んでいる ビルド時にはプラットフォームごとのアセンブリにtype forwardする 実行時には環境ごとの実装にtype forwardする

.NET Standard 2.0 Preview出ました

.MET Core 2.0 Preview出ました

  • Frameworkへの参照を単一のパッケージで
  • パッケージングの単純化(ASP.NET CoreやEF Coreを含む)
  • ASP.NET Core 2.0やEF Core 2.0もPreview出ました

Introducing ASP.NET Core 2.0

  • .NET Standard 2.0
  • Web API + MVC + Razor Pages
  • vNext (2.1?) で SignalR も
  • Perf: 4-core Ubuntu 16.04で558,000 rps

Azure AD B2Cも使えるように

SignalR .NET Core: Realtime cross-platform open web communication

  • ASP.NET Coreにあわせて書き換え、再設計
  • HTTP以外での利用(AMQP,MQTT,TCP)
  • 脱jQuery, WebWorkerからの利用も想定
  • JSON & ProtocolBuff protocol
  • Redis, Service Bus, SQL Server (TBD)によるスケールアウト
  • .NET Standard, TypeScript,C++,Java,Swiftのクライアントライブラリ
  • バイナリサポート
  • .NET Core 2.0にあわせてPreview,秋にGA

Entity Framework Core 2.0: data, mobile, server, IoT, and more

2.0の新機能紹介

  • Global Query Filters
  • Context Pooling
  • Compiled Query
  • EF.Functions

[C#]

The future of C#

C# 7.1,7.2,7.3,8.0を計画中

C# 8.0 の予定

Async Streams and Disposable を予定。Rx的な? Extensions Everything ** Record型

言語機能の議論についてはこっちのリポジトリで

github.com

Tools

Visual Studio Code: Conquer the cloud with an editor and a CLI

VS Codeは単なるテキストエディタだけではなくて、クラウド含めたデータストアの操作ツールとしても使えるようにするよというお話?

[The future of Visual Studio] (https://channel9.msdn.com/Events/Build/2017/B8083)

2017 Preview (15.3)出ました

  • .NET Core 2.0
  • C# async main & default expressoins
  • Task status center
  • Docker nano container support etc

any developer, any platform

ユーザーからのFeedback大事

Supercharge your debugging in Visual Studio 2017

DebugのTips集。ビデオみるのがよい。

Developing on Windows Server: Innovation for today and tomorrow - containers, Docker, .NET Core, Service Fabric, and more

  • Windows Server Container と Service Fabricのユーザー事例
  • Visual Studio Docker Toolのデモ
  • Image2Docker モジュール - WIM, VHD, VHDx, 実行中のサーバー からDockerイメージを作成

Docker Enterprise Edition (Docker Datacenter)のWindowsサポート

  • Windows Server container
  • Web管理コンソールの統合
  • LDAP/AD Access
  • etc

Azure Service Fabric

  • Windows Server Container と Hyper-V isolationのサポート
  • イメージの配置とactivation
  • Volume Driverサポート
  • NetworkingとDNS discovery
  • etc

kubernetes

  • Alpha support for Windows Server container
  • Linux nodeでのControl planeの実行と、kubelet/kube-proxyのWindowsでの実行
  • L3 routingでのNerworking
  • 1 Pod あたり 1コンテナのみ

Preview of Azure Functions Runtime https://aka.ms/azafr

  • PortalのホストやEndpointの発行を行う
  • FunctionsはWIndows Server Container内で実行
  • TimerやFileSystem, SQL Service brokerなどからトリガー

Hyper-V 隔離されたLinux Container

  • 1つのDocker engine
  • 1つのコンテナホスト
  • OS/kernelは任意
  • Windows 10上でも動く

=> Ubuntu/SUSE/Fedora on WIndows 10

Nano Serverは圧縮前で1GB程度

dockerのVolume mappingでSMBのサポート

TypeScript

What’s new in TypeScript?

2.0 non-nullable types, discriminated unions 2.1 downlevel async/await, Mapped types 2.2 Mixin classes, Quick fixes 2.3 Type check js files, Plug-in support

TypeScript のLang server: Editor 側にTypeScript pluginを入れ、tsserver (Node.js)とJSON形式で通信

Y8 2017 spring in Shibuya で .NET Core on Linux の内部について話しました

$
0
0

Y8 2017 Spring という技術系ノンジャンル(と私は理解している)イベントがあったので登壇してきました。CFPにリアクションして頂いたみなさまありがとうございました。こちらが資料です(更新するかもしれないです)。

doc.co

イベントサイトはこちら。

y8-2017-spring.hachiojipm.org

.NET Core がLinux(やmacOS)で動くようにどうやって実装しているかとか、デバッグの仕方とか、OS固有の部分をどうやってLinuxの世界に持ち込んでいるのか、というテーマはずっと話したくて機会を伺っていたのですがようやく世に出すことができました。

もし次があれば、デバッグまわりの部分はもう少し実践的な内容にしたいなあと思います。また、Linuxユーザー向けにはVisual Studio側の機能紹介もしたいですね。今回デモしたように、.NET CoreをLinuxにデプロイする場合でも、Windowsで開発することができ、リモートデバッグすることができます。また、リモートデバッグについてはいつの間にかやたらリモートデバッグの接続の種類が増えているので、改めて調査します。

f:id:tanaka733:20170527164325p:plain

dllに含まれるシグニチャを見るには?

質問されて答えが出せなかったので、いったん調べた内容をこちらに。dllの中で定義されているクラスとかメソッド一覧を取得したいという質問だったのですが、dllの中に定義されているのはIL(中間言語)なのでnmコマンドなどでは見れないはずです。あくまで.NET CoreのILを解釈する必要があります。Windows上の.NET FrameworkならILSpyなどのフリーのツールで逆コンパイルすることもできるのですが、Linux上で動作する.NET Core向けの逆コンパイルツールは見つけられませんでした。

ILSpy

とりあえずできそうな方法はLLDBでlibsospluginをsosコマンドからたどって行く方法です。.NET Coreのlibsospluginの使い方の詳細はこちらにあります。

github.com

定義されているsosコマンドは.NET Frameworkのものと対応しており、その詳細はこちらに書いてあります。

SOS.dll (SOS デバッガー拡張)

ではこれを使って、stringクラスのメソッド一覧を出してみましょう。ちなみにsosコマンドあまり詳しくないので、よりよい方法があればコメントなどをもらえるとうれしいです。

DumpHeapでstringを指定します。

(lldb) sos DumpHeap string
         Address               MT     Size
00007f6b1aed5000 00000000010717b0       24 Free
00007f6b1aed5018 00000000010717b0       24 Free
00007f6b1aed5030 00007f6d3b77db68       72     
(以下略)

どれか1つのアドレスを指定してDumpObjします。

(lldb) sos DumpObj 00007f6b1aed50b8
Name:        System.String
MethodTable: 00007f6d3b77db68
EEClass:     00007f6d3b0916d0
Size:        60(0x3c) bytes
File:        /opt/dotnet/shared/Microsoft.NETCore.App/1.1.1/System.Private.CoreLib.ni.dll
String:      Format_GuidDashes
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
00007f6d3b797948  4001aa6        8         System.Int32  1 instance               17 m_stringLength
00007f6d3b7827c0  4001aa7        c          System.Char  1 instance               46 m_firstChar
00007f6d3b77db68  4001aa8     1258        System.String  0   shared           static Empty
                                 >> Domain:Value  00000000010e3fb0:NotInit  <<

メソッド一覧はMethodTableで取得できます。詳細を出すために--mdを指定します。

(lldb) sos DumpMT -md 00007f6d3b77db68 
EEClass:         00007F6D3B0916D0
Module:          00007F6D3B00B000
Name:            System.String
mdToken:         00000000020005AD
File:            /opt/dotnet/shared/Microsoft.NETCore.App/1.1.1/System.Private.CoreLib.ni.dll
BaseSize:        0x18
ComponentSize:   0x2
Slots in VTable: 196
Number of IFaces in IFaceMap: 7
--------------------------------------
MethodDesc Table
           Entry       MethodDesc    JIT Name
00007F6D3B42CE10 00007F6D3B0E1508 PreJIT System.String.ToString()
00007F6D3B42E3F0 00007F6D3B0E17A8 PreJIT System.String.Equals(System.Object)
00007F6D3B42EA60 00007F6D3B0E1878 PreJIT System.String.GetHashCode()
00007F6D3B41EE10 00007F6D3B0DF0B0 PreJIT System.Object.Finalize()
00007F6D3B42CE20 00007F6D3B0E1510 PreJIT System.String.ToString(System.IFormatProvider)
00007F6D3B42CE30 00007F6D3B0E1518 PreJIT System.String.Clone()
00007F6D3B42CF40 00007F6D3B0E1550 PreJIT System.String.GetTypeCode()
00007F6D3B42CF50 00007F6D3B0E1558 PreJIT System.String.System.IConvertible.ToBoolean(System.IFormatProvider)
(以下略)

まあ、めんどくさいですね… これはもう少し調べてみることにします。


#decode17 に参加してきました

$
0
0

de:code 2017に久しぶりに参加しました。初年度以来な気がします。ということで感想をまとめてみました。

キーノート

Mobile First, Cloud First からAI中心の Intelligent Cloud, Intelligent Engineへ。あらゆる製品にAIを搭載する流れ。音声認識の認識率が人間の-5.8%まできたいうのが衝撃でした。自動翻訳については、PowerPointとMicrosoft Translator連携。Skypeも合わせて、プレゼンテーションのリアルタイム翻訳も可能に。

Microsoft と Preferred Networkの提携発表。Chainer-readyなVMをAzureに。SQL ServerにもChainerを組み込み。もう一つのテーマはHoloLens。生みの親であるKipman氏が初来日で講演。

MicrosoftはクロスデバイスでのUX向上を進めている。AndroidでコピーしたテキストをWindows PCでペーストできるようなイメージ。

GitHub - Microsoft/project-rome: Code samples and documentation of Microsoft's Project Rome feature

という感じで、.NET TechnologyとかWindows Mobileといった端末とかはほぼほぼ出てこないキーノートでした。

Azure

あとはテーマ別に参加したセッションの感想を。Twitterという名のメモから拾って構成しているので、あまりうまくまとまっていないかもしれないです。

SC02 シチュエーション別 Active Directory デザイン パターン

2020年めどにServer 2008のサポート切れにともなう移行案件があるので、その話。移行先にAzure ADも考えましょうというお話。ADFSとかAADDSとかの利用シチュエーションの説明もあって、現在使えるAADまわりの機能が復習できました。

SC04 あなたのサービスを “ID” で守る! Azure Active Directory の条件付きアクセスの基礎と実装

AADにアプリを繋いで認証すれば、サイン機能の開発も不要、既存のIDが使える、監査セキュリティログもやってくれる、といいことばかり。AADは毎日150万回のアタックを回避し、3万人の攻撃を受けた可能性のあるユーザーを特定している。つまり、自前で作る認証基盤では実現できないようなリスクベースの防御ができる。多要素認証もサポートしているよ、という話。

AC01 Container 環境を支えるマルチ クラウド運用監視のデザインと実装案

セッションの前半はWindows Server Containerの話。nanoserverのサイは350MBくらい。ダウンロードはDockerHubからがおすすめ。今後の目標は.NET最適化コンテナーのサイズ50%OFF

Windows ServerにもInsider Programを導入。nested Hyper-VがAzureにも来たら、Azure上でHyper-Vコンテナも利用可能に。

後半(長さ的には5分くらい)は、コンテナの監視はOMS Agentがおすすめという話。Azure上の仮想マシンに限らず監視できる。OMSはLinux on Azureでも便利なので期待しているんですが、いかんせんIE以外だとうまく表示されないことがよくあり、Linuxデスクトップでどうするんだという個人的懸念が…

AC11 サーバー管理よ、サヨウナラ。サーバーレス アーキテクチャの意義と実践

サーバーレスとは、サーバーの抽象化・イベントどり分で簡単にスケール・実行単位のフェアな課金という3つをポイントとしたサービス。Azureにおけるサーバーレスは、Azure FunctionsやLogic App などなど多くのサービスが該当している。

Azure Functionsはローカルでデバッグできる。またリモートデバッグもできる。Visual Studioのリモートデバッグ含めたデバッグ機能は大きな優位点ですね。Visual Studio Codeなどでもまだまだ到達できてないですし。

Twitterを拾ってメール通知まで、接続するサービスが対応していれば30秒くらいで作れる。Azure Functionsのトリガーの特徴はステートのチェック間隔を秒単位で指定できること。Azure Functionsは課金体系が2種類ある。用途に応じて決めよう。 Azure Functions も App Service PlanならDeployment SlotでBlue-Green Deploymentが可能に。

という感じでAzure Functionsの入門としてもわかりやすい内容でした。

CT06 チョークトーク: 実践! Azure PaaS/IaaS アーキティクチャ デザイン パターン & アンチ パターン

これ、どこまで内容話していいかよくわからないので、あまり言及できないんですが、内容自体は間違いなくよかったです。同様の形態のセッションは来年以降もぜひやってほしい。

DI07 あらゆるデータに価値がある! アンチ断捨離ストのための Azure Data Lake

Data Lakeという大容量のデータを保管し必要に応じて解析するサービス。思想としては、必要なるタイミングまでネイティブフォーマットのまま生データを大量に保管しておく。解析するための言語として、C#の表現力とSQLのクエリを統一したU-SQLというものを利用。U-SQLスクリプトを記述し、ジョブとして投入する。

あとは、U-SQL入門、Data Lake入門として聞いていました。

.NET / .NET Core

TL04 .NET 15 周年の今こそ考えるクラウド ネイティブ アプリケーションと .NET の活用

自分の聞いていた中ではベストセッションだと思います。自分の手を動かしてみないと気づかないような嵌りポイントにも触れていましたし、何よりデモの構成がよくてすべてのデモが最後につながっている流れがありました。自分がセッションやると、ついつい自分のやりたいデモをやってしまって、流れが切れてしまって、理解の妨げになるようなことがあるので、セッションをやる側としても学びが多かったです。

内容としては、.NET Coreにつながれ歴史の振り返り。One ASP.NET 構想とか、OWIN, KATANA Projectといった懐かしい単語がでてきます。そして、その多くはASP.NET Coreに引き継がれている。

.NET Core 2.0 で導入される.NET Standard 2.0で今より多くのAPIが利用可能になる。既存の.NET Frameworkとの共通点も多くなる。

どのAPIが使えるかは.NET APIブラウザーで

.NET API Browser | Microsoft Docs

.NET Framework 4.7 のプロジェクトに.NET Standardのライブラリを追加する場合は、 NETStandard.Library.NETFramework を追加する必要がある。

VS 2017 PreviewからNuGetパッケージ作成まわりのメニューも強化。Visual Studio Codeを使う場合はdotnetコマンドで。Visual Studio 2017 から Linux docker上のdotnetプロセスにリモートデバッグできる。

より高次な.NET アプリのアーキテクチャガイダンスもあるから参考に。

www.microsoft.com

DI01 窓は開かれた! SQL Server on Linux で拡がる可能性

このセッションも、自分の知らなかった知識を補完してくれるということで助かりました。

SQL Serverの掲げるゴール

  • 展開先を選ばない
  • 様々なOSからの選択
  • 多種多様なデータ
  • DB内の分析/学習環境
  • 多彩な開発言語

SQL Server 2017新機能

  • クエリチューニングの自動化
  • データベースと分析環境の融合

SQL Server on Linuxへの道程を説明。LinuxのうえでSQL Serverを互換環境をつかってそのまま動かそうとした。しかし、それはパフォーマンス上の問題があった。理由はSQL ServerがCPUのスケジューリングをWindows OSの機能ではなく自前で実装していたため。それには理由があり、Windows OSのスケジューリング機能がRDB向きではなかった。SQL Server 7.0~2000でUser Mode Scheduleを採用。SQL Server 2005~2016でCPUに加えてメモリ管理も行うSQL Server OSが実装。ブラックボックス化していたので動的管理ビューも追加した。そこで、SQL Server + SQLOS + Linux Host extensionをLinuxプロセスとして動かそうとした。Linux Host Extensionで全部抽象化しようとしたがパフォーマンスに問題がでた。そこでSQLPALを導入。これがDrawBridgeの成果物。この結果、現時点でもon Linuxの方がon Windowsよりパフォーマンスに優れている点がある。将来的にはWindows版も同じアーキテクチャにそろえる予定。

SQL Serverの管理ツールもクロスプラットフォームへ。CLIならsqlcmd、GUIならVisual Studio Codeが現時点で利用可能。将来的にはLinuxではsqlcmd, bcp, sql-cli (nodejs), mssql-scripter(予定)が使える。さらに、DBA向けのクロスプラットフォームで動くGUI Toolsも開発中。

SQL Server on Linuxに接続するアプリの開発言語もいろいろ選択できる。SQL Server 2017 on Linuxでもバックアップ/リストアは同じ手順。Windowsでエクスポートした bakファイルを転送して、Linux上でリストアもできる。SQL Server 2017 on Linux での自動フェールオーバー可能な構成は、Pacemaker + corosyncを使う。SQL Server自身の機能でフェールオーバーするのに加え、接続するIPアドレスを Pacemaker + corosyncでフェールオーバー。

TCP-Hでの測定では、SQL Server 2017 on Linuxは 2016 on Windows Server 2012 R2より高評価。

その他のセッション

あと参加したけどちょっと感想かきづらいセッションとか、参加していないけど参加したかったセッションとかあります。特に、Web Apps on LinuxとWindows ハードコアデバッキングは聞きたかったですね… 仕事に役立ちそうな方を優先してしまったので*1……

Hack Days (Post event)

今年からの試みとしてdecode終了後の2日間で、ハンズオンとハッカソンを実施されました。私はハンズオンに参加したのですが、ハンズオンはdecodeでも説明のあったMicrosoftの各種技術を自習形式で開発し、わからないことがあったらその場にいるMSのエンジニアに聞けるという形式です。10個くらいテーマがあったはずなので、全部やるには2日で足りない人もいたかもしれないです。という自分は、Linux関連メインであまり該当するテーマがなかったので、独自ハンズオン(ハッカソン)を進めました。

成果

Cognitive ServiceのEmotion API(人の顔の写真から感情を推定する)を使ったアプリを開発。.NET Frameworkを使った例だったので、ASP.NET Coreに変えてLinuxでも動くようにしてみました。

github.com

あと、下記のページにあるRed Hatが出した、OpenShift on AzureのARM Templateの解読とハッキングをしたりしてました。これは、ARM TemplateでAzure上に必要なリソースを展開し、ARM Templateから必要な設定ファイルの配置とOpenShift のAnsible Installerを実行するスクリプトも実行しています。ただ、MarketplaceのRHELイメージを前提としているので、これをBYOLな自前RHEL VHDイメージを基に展開するようにいじろうとしていました。

Deploying Red Hat OpenShift Container Platform 3 on Microsoft Azure - Red Hat Customer Portal

また、この辺の話に興味のある方は6/24のinteract2017の「OpenShift on Azure」のセッションで話す予定なので、ぜひご参加を。

interact.connpass.com

まとめ

運営面の感想としては、満足したという面もあれば、それはちょっとどうだろうという面もあり、アンケートでフィードバックしました。なんか後から話を聞くと、じゃあやむを得ないかと思わないこともないんですが、アンケート書いた時点では知らなかったということで、厳しいフィードバックもご了承いただければ…

セッション全体としてはかなり満足でしたが、やはり自分の立場的には.NET CoreとかASP.NET CoreとかLinux on Azure *2とかとかのセッションが増えるとと嬉しいなという感じです!!

*1:というか最終日の最後の枠が重なりすぎ

*2:OSS on AzureではなくてLinux on Azureね

2017年 .NET Core 1.x (Visual Studio 2017) プロジェクト向け AppVeyor での自動ビルドの設定

$
0
0

ChatWork 向けのC# クライアントを開発していて、ここ1~2年は更新していなかったものの、最近.NET Core対応させたり、API endpoint v2に対応したりしてまた更新するようになりました。

github.com

2年前にAppVeyorで自動ビルド環境を作っていましたが、当時は.NET Core対応などなくVisual StudioのMSBuildでビルドしていました。今回、.NET Core対応したので、dotnetコマンド中心に自動ビルドを対応したので、そのまとめです。作ったプロジェクトはここにあります。

AppVeyor

2年前に作ったプロジェクト、publicリポジトリ向けの無償プランなのにまだビルドログまで保存されていて驚きだったんですがコミット連携とかがおかしくなっていたのでいったんAppVeyorのプロジェクトを作成しなおしました。その上で今回実現できた自動ビルドの中身はこんな感じです。

  • 任意のブランチ*1へのコミット、もしくはPRが作成されたらビルドがトリガーされる
  • 最新の.NET Core SDKでビルドする
  • AppVeyor側で採番されるビルド番号をsuffixにつけたバージョンのNuGetパッケージを生成する。逆に言うと、<Major>.<Minor>.<Patch>形式のバージョンは明示的にcsprojで指定し、AppVeyor側からは操作しない。
  • 自動ビルドで生成したNuGetパッケージはAppVeyorが持っているプロジェクトごとのNuGetリポジトリにpushする
  • (この項目だけ未テスト)GitHubにタグをpushすると、デプロイ処理が実行され、nuget.orgにリリースビルドされたパッケージをpushする。リリースビルド用のパッケージはsuffixをバージョンにつけない。

順番に見ていきましょう。

ビルド番号とトリガー

AppVeyorの場合、設定したGitHubリポジトリに対してデフォルトですべてのコミットでビルドがトリガーされます。トリガーされたくないブランチや、特定のブランチのみトリガーしたい場合はsettingsGeneralタブで指定します。また、ビルド番号形式も指定できます。{build}で自動インクリメントされる数値、{branch}でコミットされたブランチ名が入ります。

f:id:tanaka733:20170531164534p:plain

このページのほかの設定はデフォルトのままにしています。

ビルド環境の設定

最新の.NET Core SDKはVisual Studio 2017という種類のイメージを指定するとすでにインストールされています。インストールスクリプトを記述することもできるので、指定したバージョンのSDKであったりその他のツールをインストールすることもできるでしょう。gitリポジトリをcloneするフォルダは、あとあとのスクリプトの記述を楽にするために明示的に指定しています。

f:id:tanaka733:20170531164857p:plain

ビルドスクリプトとsuffixの指定

次にBuildタブでビルドスクリプトを記述します。.NET Coreプロジェクトなので、組み込みで用意されているMSBuildではなく、dotnetコマンドを使ったスクリプトを記述します。といってこのように数行程度のスクリプトです。

dotnet --info
cd Chatwork.Service
dotnet restore
dotnet pack -c Debug --version-suffix $env:APPVEYOR_BUILD_VERSION
dotnet pack -c Release

デバッグのために--infoを出力した後は、プロジェクトディレクトリに移動して、NuGetのリストアー、そしてDebug構成とRelease構成でdonet packしてNuGetパッケージを作成しています。普段の自動ビルドはDebug構成のみ、タグのpushのときはRelease構成のみビルドすればいいのですが、条件分岐をさぼって両方実行しています。また、--version-suffixはNuGetパッケージを作成するとのバージョンサフィックスをコマンドから指定するオプションです。プロジェクトファイル(csproj)で指定しているVersionPrefixとここで指定したサフィックスがあわさってバージョンとなります。またenv:APPVEYOR_BUILD_VERSIONという環境変数を使ってGeneralタブで指定したバージョンを参照することができます。

docs.microsoft.com

CSharp.Chatwork.Api/Chatwork.Service.csproj at v0.6.2 · tanaka-takayoshi/CSharp.Chatwork.Api · GitHub

バージョン番号がciではじまっているのは、アルファベットを含むことでprerelease扱いにすることができるからです。

docs.microsoft.com

Debugビルドパッケージの開発用NuGetフィードへの登録

AppVeyorではプロジェクトごとにNuGetフィードが用意されていて、ArtifactタブでnupkgファイルをArtifactに指定すると、自動で登録してくれます。これとは別にアカウントごとに用意されたNuGetフィードもあって、こちらにpushするときは通常のNuGetリポジトリ同様、ApiKeyとServerを指定してdotnet nuget pushします。

f:id:tanaka733:20170531170032p:plain

リリース用のDeployment

開発用にはこれで以上ですが、リリース時にnuget.orgにpushするべきDeploymentタブで設定します。デフォルトだとビルドのたびにDeploymentが実行されるので、今回のようにタグがpushされたときのみDeployするには、Deployment ConditionでAPPVEYOR_REPO_TAGtrueの条件を追加しておきます。NuGetへのpushはNuGetというproviderが用意されているので、それを選択し、ApiKeyやpushするファイルを指定すればOKです。

f:id:tanaka733:20170531170135p:plain

まとめ

以前のVisual StudioのMSBuildをいろいろいじっていた時と比べると、dotnetコマンドだけで完結するのでだいぶシンプルになりました。AppVeyorではVisual Studio 2017のイメージに.NET Core SDKが入っているのでそれを使っていますが、実際にはVisual Studioは必要ないです。実際にこの設定でPRを作成すると自動ビルドが走って、Botがコメントしてくれます。

github.com

*1:設定で特定のブランチのみ、もしくは特定のブランチ以外も指定できる

Azure Active Directory Domain Services (AAD DS)を使って、RHEL Serverから openldap-clients で接続してみる

$
0
0

AADは非常に便利なのですが、LDAPプロトコルがそのままでは使えません。LDAPを使いたい場合はAAD DSを使います。

docs.microsoft.com

なのですが、意外とLinuxのopenldap-clientsから接続する場合の手順がみつからず非常に手間取ったのでまとめておきたいと思います。なお手順は試行錯誤の末できたという状態なので、もしかすると不要な手順やよりよい手順がある可能性が高いです。ちなみに最終的にやりたかったことは、OpenShiftのmaster APIの認証をLDAP経由でAADから認証させたいということです。

Configuring Authentication and User Agent | Installation and Configuration | OpenShift Container Platform 3.5

AAD DSの構築

基本的にはこの手順に従って作成するだけです。

docs.microsoft.com

注意点としては、Classicネットワークしかサポートしていないので、今は懐かしい旧ポータルで作業をすすめていきます。また、今では仮想マシンはAzure Resource Manager (ARM)で作ることが多いと思いますが、その場合は後でVNETピアリングやVNET-to-VNET VPNでprivateネットワーク接続することになります。 先に仮想ネットワークを作成しておいてから、ドメインサービスを有効にする段階で該当するネットワークを選択します。設定後、最初のIPアドレスが表示されるまで20~30分、2つ目のIPアドレスが表示されるまでまた20~30分かかるので気長に待ちましょう。

AAD Premiumの有効化とパスワード同期の設定

さて、ドメインサービスを設定するとこのような表示がでます。

f:id:tanaka733:20170706152037p:plain

これはドメインサービス側にパスワードハッシュが存在しあいので、そのままだとパスワードで認証できないことを意味しているようです*1。実際にパスワード同期を設定しないままLDAP接続を試みても認証が通りませんでした。というわけでパスワード同期を設定するためにこのドキュメントに沿って進めます。

docs.microsoft.com

つまり、パスワード同期をするためにはユーザー自身がそれぞれでパスワードのリセットを行う必要があるということのようです。そしてこの手順を行うには、ユーザーによるパスワードのリセットを有効化しないといけないのですが、この設定はBasicかPremiumが必要です。自分が検証に利用したアカウントはFreeだったので、trialでPremiumを有効にして検証を進めました。

docs.microsoft.com

さてこの手順を行うとユーザーによるパスワードのリセットができますが、注意点として、Microsoftアカウントのユーザーではリセットできません。AzureにサインアップするときMicrosoft アカウントを利用すると、AADにMicrosoftアカウントが追加されますが、このユーザーではパスワードリセットできないので、AADに追加したユーザーでないといけないようです。

VNET ピアリングの設定

今回はARMで仮想マシンを構築したいので、ClassicのVNETと仮想マシンに使うARMのVNETをVNETピアリングで接続することにしました。注意点としては、プライベートIPレンジが重ならないように設計しておくことでしょうか。

docs.microsoft.com

(オプション)Windows Serverを作成して、ドメイン参加してLDAPで接続してみる

ゴールはLinuxマシンからの接続なので本来は不要な手順なんですが、いきなり openldap-clientsだけでつなごうとしてうまくいかなくて心が折れたので、まずはWindows Serverでこて調べをします。ARMでWindows Server 2016 Datacenter Editionを作成して、VNET peeringした仮想ネットワークにつなぎます。いったんは仮想マシン作成時に指定できる普通のユーザー/パスワードでリモートログインしたあとにドメインに参加します。 このとき、デフォルトだとVNET PeeringしたARM側のVNETはDNSサーバーがAzure内部DNSのままで、AAD DSのIPアドレスにはなっていません。ARM側のVNETのDNSサーバーをAAD DSのものにしてもいいですが*2、今回は仮想マシンのVNIC単位でDNSサーバーを設定しました。

f:id:tanaka733:20170706154839p:plain

これでAAD DSを設定するときに指定したドメイン(デフォルトだと hogefuga.onmicrosoft.com 的なドメイン)に参加することができます。参加するときにユーザーとパスワードを聞かれるので、そのタイミングで事前にパスワードハッシュが作成されAAD DS側に同期されている必要があります。また、ここでWindows Serverに追加したユーザーでリモート接続できるようになります。

さて、ドメインに参加して追加したユーザーでログインすると、Active Directory Users and Computers (ADUC)で中を観ることができます。

f:id:tanaka733:20170706155448p:plain

ここで見るとわかるように、デフォルトのOUはAADDC Usersになります。addmin*3とocpuser1がAADで追加したユーザーでopenshiftがグループです。

最初、AADユーザーやグループのOUがどれになるのかわからなくて困っていたのですが、ブチザッキに助けてもらいました。

Azure Active Directory Domain Services (Public&nbsp;Preview)buchizo.wordpress.com

ただ、これはLDAPではなくActive Directoryとして見ています。せっかくなのでWindowsからLDAPクライアントとして見ることができないかと思っていたら、こういうツールを見つけました。

LDAP Admin - a free LDAP directory browser and editor

インストールの必要なく、解凍してでてきたexeを管理者として実行するだけでよいのでこれを使いました。実行すると接続先を聞かれるので、ドメイン名を入力します。

f:id:tanaka733:20170706160121p:plain

表示するとこんな風になります。

f:id:tanaka733:20170706160353p:plain

これでLDAPの属性などが見られるので便利です。これで確認できたところで本題に移ります。

RHEL Serverからopenldap-clientsでつなぐ

というわけでまずは、ARMでRHEL Serverを構築します。構築したあと、openldap-clientsをインストールします。

$ sudo yum install openldap-clients

これでldapsearchコマンドが使えるようになったので繋いでみます。-Wと指定しているので、プロンプトでパスワード入力を求められます。AAD DSのIPアドレスが172.XX.XX.XX、ドメインがexample.onmicrosoft.comという前提で、出力結果からいくつかの属性を除いています。

$ ldapsearch -LLL -x -D "cn=addmin,ou=AADDC Users,DC=example,DC=onmicrosoft,DC=com" -h 172.XX.XX.XX -W -b "CN=openshift,OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com"
dn: CN=openshift,OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com
objectClass: top
objectClass: group
cn: openshift
member: CN=ocpuser1,OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com
distinguishedName: CN=openshift,OU=AADDC Users,DC=example,DC=onmicr
 osoft,DC=com
instanceType: 4
name: openshift
sAMAccountName: openshift
sAMAccountType: 268435456
groupType: -2147483646
objectCategory: CN=Group,CN=Schema,CN=Configuration,DC=example,DC=o
 nmicrosoft,DC=com
msDS-AzureADObjectId:: d2aCBDo84E2dQES9N5djSw==
msDS-AzureADMailNickname: 0846aab7-9b8e-45d5-b8fd-3cc70c05310b

という感じでわかってしまえば簡単そうなのですが、AAD DSにopenldap-clientsで接続するまでの手順になります。

f:id:tanaka733:20170706162153p:plain

*1:いまいち自信がない

*2:その場合、DNSサーバーを設定後仮想マシンを再起動する必要があります

*3:adadminをtypoした説がある

AAD DSを使って、OpenShiftのLDAP認証先としてAADを参照する

$
0
0

前回の続きとなる記事です。

tech.tanaka733.net

OpenShift はmasterのAPIへのアクセス(Webのポータル画面含む)にいくつかの認証方法を選べます。認証のプロバイダにAADを使いたい場合はOpenID Connectが使えます。ただ、どうしてもAADに定義したグループ、ユーザーを使ってLDAP認証したいという場合は、AAD DSを使えば、LDAPのプロバイダーとなれるので、他のLDAPプロバイダー同様に利用することが可能になります。

Configuring Authentication and User Agent | Installation and Configuration | OpenShift Container Platform 3.5

というわけで、AAD DSを使う場合の設定方法です。

master-config.yamlの設定

AAD DSのIPアドレスがXXX.XX.XX.XX、AAD DSに設定したドメインがexample.onmicrosoft.com、管理ユーザーがadadmin、AADに定義したocpgroupというグループに属するユーザーが利用可能となる設定例です。

- name:"aad_ds_provider"challenge:truelogin:truemappingMethod: claim 
    provider:apiVersion: v1
      kind: LDAPPasswordIdentityProvider
      attributes:id:- dn
        email:- userPrincipalName
        name:- cn
        preferredUsername:- cn
      bindDN:"cn=adadmin,ou=AADDC Users,DC=example,DC=onmicrosoft,DC=com"bindPassword:"<adadminユーザーのパスワード>"insecure:trueurl:"ldap://XXX.XX.XX.XX/OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com?userPrincipalName?sub?(memberof=CN=ocpgroup,OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com)"

bindDNbindPasswordのところにLDAPに接続しにいくユーザーとパスワードを記述します。この書き方だとパスワードが平文としてテキストに記述されますが、環境変数や外部の平文ファイルおよび暗号化された外部の暗号化ファイルに記載することができます。

Master and Node Configuration | Installation and Configuration | OpenShift Container Platform 3.5

他の注意事項としては、前回も記載した通り、AADのユーザーやグループはAADDC Users OUに所属すること、EメールアドレスはuserPrincipalNameで取得できること、特定のグループに属するユーザーを利用できる対象とする場合はLDAP URLのフィルタの部分に記述できること、が挙げられます。

LDAP URLのattributeの部分にuserPrincipalNameを指定しているのでログイン画面ではeメールアドレスを入力してログインできるようになります。実際にLDAPに投げられるクエリはLDAP URLのフィルターとattribute=(ログインフォームのUsernameに入力した値)を組み合わせたクエリになります。

f:id:tanaka733:20170707172245p:plain

あとは要件にあわせて適宜設定ファイルを変更すればいいでしょう。

Syncing Groups with LDAP

ついでに、Syncing GroupsでのAAD DSの設定例もまとめておきます。Syncing Groupsは事前にLDAPのクエリで拾ったグループと属するユーザーをOpenShiftのグループにマッピングしておく機能です。先程と同じ前提で、ocpgroupをOpenShift上ではusergroup1としてマッピングする例です。

kind: LDAPSyncConfig
apiVersion: v1
groupUIDNameMapping:"CN=ocpgroup,OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com": usergroup1
url: ldap://XXX.XX.XX.XX
insecure:truebindDN:"cn=adadmin,ou=AADDC Users,DC=example,DC=onmicrosoft,DC=com"bindPassword:"<adadminユーザーのパスワード>"rfc2307:groupsQuery:baseDN:"OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com"scope: sub
   derefAliases: never
   filter: (CN=ocpgroup)
   pageSize:1000groupUIDAttribute: dn
 groupNameAttributes:[ cn ]groupMembershipAttributes:[ member ]usersQuery:baseDN:"OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com"scope: sub
   derefAliases: never
   pageSize:1000userUIDAttribute: dn
 userNameAttributes:[ sAMAccountName ]

これでocpgroupに属するユーザーをマッピングさせることができます。

$ oadm groups sync --sync-config=ldapsync.yaml --confirm

Microsoft MVPを再受賞しました

$
0
0

5年目の受賞になります。MVPプログラム全体での受賞のサイクルが変わりましたが、もともと7月受賞だったので変わりなく7月に再審査の結果更新となりました。

tech.tanaka733.net

今回もカテゴリはVisual Studio and Development Technologiesとなります。今回は加えて、AzureとData Platformカテゴリの受賞申請もしましたが、VSDTのみでの受賞となりました。正直、活動内容としてはAzureの方が多かったですし、自分のやっている活動は.NET Core on LinuxなのでVisual Studio製品との絡みはVisual Studio Codeのみなので、むしろAzureへのカテゴリ変更がありうるかもと思っていましたが、結果としてVSDTのみの受賞となりました。Data Platformは少しばかり行ったSQL Server on Linuxの活動がそこにしかカテゴライズできないので、まあ基準には満たないだろうけど活動したんだからでしておこういう気持ちで提出しました。

というわけで、今年も活動としては、

  • .NET Core on Linux
  • Linux on Azure
  • SQL Server on Linux

が中心に情報発信していく予定です。イベントとしては、.NET Core 2.0リリースや、SQL Server on Linux正式リリースがあるので、また最新情報をまとめていこうと思います。また、Linux on AzureについてはRed Hat製品のOpenShift on Azure関連で、単純にAzure上にLinuxのVM立てて動かしたよだけではなく、いかにAzureの機能を活用して使いやすくなるかについても発信していこうと思います。

Viewing all 283 articles
Browse latest View live