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

ASP.NET Core 2.0 preview 2 では C# 7.1 の構文がRazor Viewの中で使えなかった話

$
0
0

このissueのやり取りがすべてなんですが、備忘録として残しておきます。

github.com

.NET Core 2.0 / ASP.NET Core 2.0のタイミングでC# 7.1が利用可能になる予定で、実際preview 2の時点で利用可能です。

blogs.msdn.microsoft.com

このブログには"Razor Support for C# 7.1"とあって<LangVersion>latest</LangVersion>をプロジェクトのプロパティにつけろと書いてありますが、Razor内に限らずC# 7.1の構文を利用するにはこのプロパティを追加しておく必要がありそうです。そもそもC# 7.1で追加される機能についてはこちらが詳しいです。

ufcpp.net

で、実際にRazorの中にC# 7.1の機能を使ったコードを書くとVisual Studio上でのコンパイルエラーは見えないし、ASP.NET Coreのアプリも起動まではするのですが、該当ページへアクセスしようとするとRazorがコンパイルできないというエラーが出ます。ASP.NET Core 2.0ではデフォルトのテンプレートで発行時のRazorコンパイルが有効になっているのですが、実際 dotnet publishするとその段階でコンパイルエラーを検出します。

で、冒頭のissueに戻るのですが、どうやらpreview 2のバグのようで、現在作業中のRTMでは修正済みとなっています。開発中のRTMを利用するには、まず.NET Core SDKをここからダウンロードしてインストールしたうえで、

github.com

ASP.NET Coreのパッケージをmyget経由でRTM版にアップデートします。具体的にはNuGet.configを追加して、

<?xml version="1.0" encoding="utf-8"?><configuration><packageSources><add key="dotnet-2-0-0-rtm"value="https://dotnet.myget.org/F/dotnet-2-0-0-rtm/api/v3/index.json" /></packageSources></configuration>

参照するパッケージをRTMにあげます。

<ItemGroup><PackageReference Include="Microsoft.AspNetCore.All"Version="2.0.0" /></ItemGroup><ItemGroup><DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools"Version="2.0.0" /></ItemGroup>

これで<LangVersion>latest</LangVersion>と指定すればRazorの中でもC# 7.1の構文が使えるようになります。なお、<LangVersion>7.1</LangVersion>とバージョン番号を指定することもできるのですが、こちらはRTMでもバグが残っていて、これを回避するにはこのコメントにあるワークアラウンドを適用する必要があります。


イギリス旅行で giffgaff というプロバイダのSIMカードを使ってみました (2017年8月版)

$
0
0

10日ほどイギリスに旅行に行っていたのですが、いつものごとくSIMフリーの携帯にSIMカードのみを購入して現地でインターネットと通話に使っていました。ちなみに2年前にいったときは three.co.uk のSIMカードを購入しました。

miscellany.tanaka733.net

今回もこれを買うつもりだったのですが、試しに社内のなんでもメーリングリストに相談してみたら、すごい勢いでいろんな意見が集まりました。threeがいいよという意見ももちろんあったのですが、今回は別におすすめしてもらったgiffgaffというプロバイダ(回線網はo2 networkを利用)で購入しました。

新しいのを試した方がネタになるから、という理由もあるのですが、結果的に下記の点でおすすめできます。

  • 海外の住所に送料無料で配送してくれるので、出発前に確実に入手できる (現地で購入に時間をかけることなく、到着後すぐに利用できる)
  • つまり、そもそも海外のユーザーが利用することを想定しているので安心
  • 同程度のプランがthreeより多少安い (今再度確認すると、threeも出発前より安いプランがあるみたいなので、これは購入のタイミングで要確認)
  • 今回行った Wales地方では多少giffgaff の方がネットワークのカバレッジがよい (カバレッジの地図で確認した範囲で実機での確認ではないです。そもそもちょっと街からはなれると圏外だったりしますが)

購入から利用までの流れはこのような感じです。

まずはgiffgaffのサイトにいってSIMカードを配送してもらいます。下記のリンクは私の紹介リンクになっていて、ここから購入するとアクティベート後に£5のクレジットがもらえるはずです*1

www.giffgaff.com

プランと自宅の住所を入力すると、クレジットカードの情報などいれることなく配送手続きが完了します。プランは後から変えることもできます*2。自分はどこまで入力できそうかためしにやってみようという感じで進めたら、住所入れるだけで手続きが完了してびっくりしました。手続き完了後しばらくしたタイミングと発送時(私の場合は手続きした翌日)にメールが来ます。ヨーロッパ圏外には5+ business dayとありますが、水曜に申し込んで、木曜に発送され次の週の月曜には届いていました。うすい封筒の国際郵便でした。

届いたら、とりあえず日本にいる間にアクティベートと月額プランの購入までやります*3。メールもしくは封筒に書いてあるリンクに飛び、giffgaffアカウントを作成して、SIMカードの番号を入れてアクティベートします。まだこの時点では通信できないはずです。登録時に同時に月額プランも購入できますが、ボーナスのクレジットがもらえる場合はいったん購入せずにアクティベートのみするのがいいでしょう。おそらくアクティベートしばらくするとクレジットが追加されると思います。

次に月額プランを購入します。下記のSIM only planで好きなものを選びます。自分は£20のAlways On*4にしました。電話使わないかなあと思いつつ、結果的に無料だから気軽に使うこともあった*5のであると便利です。

www.giffgaff.com

あとはSIMを挿してAPNの設定をすれば利用可能になります。自分は飛行機の中(つまりまちがってもローミング通信が発生しないであろう場所)でやりました。giffgaffの便利なところはAPNの設定方法がいろんな端末別に説明してある点です。

Settings for your device - The giffgaff community

ちなみに、自分は行きはフィンランド乗り継ぎだったので、いったんフィンランドでローミング無効の状態でつないでみたのですが、EU圏内は「EUの人なら」ローミング無料だよーというメッセージが来ました。イギリスがEUから脱退完了したらどうなるかは謎です…

現地滞在中はgiffgaffアプリを入れておくと便利です(Windows Phone版はないです)。ネットワーク利用量などが確認できます。ネットワークの質ですが、4Gがつながる場所ではおおむねスマホで何をするにもストレスを感じなかったです。というわけで、イギリスでのSIMの購入候補としてgiffgaffを入れてみるのはいかがでしょうか。

*1:私はとくに紹介から登録しなかったのでこのクレジットはなし

*2:というよりここで指定している意味はあまりない感じ

*3:現地についてからでもできると思いますが

*4:6GBを超えると日中は256kbpsが速度上限

*5:当日いろんなお店に確認して空席状況とか確認した

Red Hat版 .NET Core 2.0 のリリースや、OpenShiftのWindows Server Containerサポートなどが発表されました

$
0
0

Red HatとMicrosoftが協力している技術分野に関して立て続けにプレスリリースが発表されています。いくつかの内容についてはすでに発表済みですが、再度まとめての記事になっているようです。

www.redhat.com

www.redhat.com

news.microsoft.com

技術的な詳細はまだ発表されていないものもありますが、簡単にまとめてみます。

Windows Server containers on Red Hat OpenShift

OpenShiftというのはRed Hatの提供するContainer as a Serviceのソフトウェアですが、これがWindows Server containersをネイティブにサポートするとあります。5月のRed Hat summitでデモが行われたのですが、あくまでこのときは、OpenShiftが内包するkubernetesがWindows Server Containerをサポートしようとしているので、こういう可能性もある、が具体的なロードマップとしては考えていないという状態でした。これが今回明確にロードマップにのったことになります。2018年春にプレビューが利用可能になるようです。

より詳細にはブログ記事が出ています。

www.redhat.com

注目ポイントはここでしょう。

Said succinctly, let Windows run Windows Server containers and Red Hat Enterprise Linux run Red Hat Enterprise Linux containers, while OpenShift orchestrates them as building blocks to compose your next generation applications.

つまり、Windows Server ContainersがLinuxで動くようになったり、その逆ができるようになるわけではなく、あくまでWindows Server ContainerはWindows Server上で、RHELコンテナーはRHEL上で動いて、OpenShiftはそれらをまとめてオーケストレーションするということのようです。

Red Hat OpenShift Dedicated on Microsoft Azure and Red Hat Enterprise Linux on Microsoft Azure Stack

OpenShift DedicatedというのはRed Hatがインフラの面倒まで見てくれるサービスで、今のところAWSとGCP上での提供となっていました。今回、Azure上での提供が可能になるとあります。

Red Hat OpenShift Dedicated

また、RHELをAzure Stack上でもサポートするとも記述されています。

SQL Server on Red Hat Enterprise Linux and Red Hat OpenShift

SQL Server for Linux についてもRHELとOpenShift上でサポートすると記述されました。

.NET Core 2.0

Red Hat版.NET Coreのリリースが発表されました。

www.redhat.com

Red Hat版というのは以前Build Insiderで書いたこの記事に詳しく書いています。

www.buildinsider.net

RHELやOpenShiftでサポートする.NET Core SDKというのは、Red Hatがrpm形式で配布しているものであり、これがMicrosoftが提供しているものとは違うという話です。特に.NET Core 1.x 時点では、Red Hatはビルドツールのcsprojへの移行を行わない決断をしたため、大きな違いが生じていました。.NET Core 2.0のリリースでついにproject.jsonとも完全におさらばできます。

ブログ記事も公開されています。

Red Hat Releases .NET Core 2.0 – RHD Blog

Quick Introduction of .NET Core 2.0 – RHD Blog

また、OpenShift上で利用するためのs2iイメージやテンプレートについても鋭意作業中のようです。

github.com

github.com

Azure AD Domain Services を ARM VNetに作成し、peeringさせてVNet上のOpenShiftからLDAP認証させる

$
0
0

以前に同じような記事を書きましたが、そのときはAzure AD Domain ServicesはClassic Networkにしか作成できませんでした。

tech.tanaka733.net

tech.tanaka733.net

今回ARM VNetに作成できるようになったので試してみました。

作成する前にこのドキュメントを読んでおきます。

docs.microsoft.com

単純には、Domain Servicesを有効にしたVNet上にOpenShiftやそのほかAAD DSを参照するサービスを置けば動くはずですが、Domain Servicesに設定するVNetは専用のものを割り当てた方がよいとあるので、それに倣います。あとで、必要なVNetとpeeringして参照できるようにします。リージョン越えて接続する必要がある場合はサイト間VPNが利用できます。

実際に作成する手順はこちらのドキュメントを見て進めます。

docs.microsoft.com

特に面倒なところはなく作成まで進みます。ただ、作成を開始してから実際にDomain Servicesを参照するIPアドレスが利用可能になるには30~1時間ほどかかりました。

Domain ServicesのIPアドレスが利用可能になる間に(なってからでもいいですか)、VNet peeringの設定を行います。といっても、ARM VNet同士のpeeringはAzure PortalのVnetブレードから設定できます。注意点としては、双方向でpeeringを設定しないと接続できません。Azure Portalの表示でPEERING STATUSがConnectedになっているところまで確認しましょう。

f:id:tanaka733:20170906013524p:plain

ここまでできたら、peering相手のVNet上に起動したVMからDomain Servicesが参照できるようになります。VMが起動済みの場合はpeering完了後に再起動しておく必要があります。

OpenShiftの設定をする前にopenldap-clientsをインストールしてLDAP接続を確認しておきましょう。ドメインはexample.onmicrosoft.comを仮定しています。AAD DC Administratorsにadminユーザーが属しており、testというユーザーがocpusersというグループの中にいます。

# yum install openldap-clients

# ldapsearch -x -LLL -h <DomainServicesのIPアドレス> -D "cn=<AAD DC管理者ユーザーのを識別するCN>,ou=AADDC Users,DC=example,DC=onmicrosoft,DC=com" -W -b "OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com"
//testユーザーの結果のみ表示
dn: CN=test,OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: test
distinguishedName: CN=test,OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com
instanceType: 4
whenCreated: 20170903140510.0Z
whenChanged: 20170905081811.0Z
displayName: test
uSNCreated: 20496
memberOf: CN=ocpusers,OU=AADDC Users,DC=example,DC=onmicrosoft,DC=
 com
uSNChanged: 29234
name: test
objectGUID:: XXXXX
userAccountControl: 544
badPwdCount: 1
codePage: 0
countryCode: 0
badPasswordTime: 131490732568021847
lastLogoff: 0
lastLogon: 131490731077979891
pwdLastSet: 131490727552992577
primaryGroupID: 513
objectSid:: XXXXXXXX
accountExpires: 9223372036854775807
logonCount: 0
sAMAccountName: test
sAMAccountType: 805306368
userPrincipalName: test@example.onmicrosoft.com
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=example,DC=onmicrosoft,DC=com
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 131490730911102975
msDS-AzureADObjectId:: XXXXXX
msDS-AzureADMailNickname: test

//testユーザーのパスワードがDomain Servicesの同期されていることを確認する。パスワードを入れて認証できればOK。
# ldapwhoami -x -D "CN=test,OU=AADDC Users,DC=example,DC=onmicrosoft,DC=com" -h <DomainServicesのIPアドレス> -W
Enter LDAP Password: 
u:EXAMPLE\test

ここまで確認できたら、OpenShiftのmaster configurationをドキュメントに従って変更します。

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

今回の場合肝心の部分はこんな感じになります。

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

変更後、masterサービスを再起動すればLDAP情報でログインできるようになるはずです。ならない場合、詳細なエラーログはログレベルを上げて確認します。/etc/sysconfig/atomic-openshift-master (single masterの場合)のloglevelを5に変更します。8とかでもいいですが、余計な出力が増えるのでまず5で試すのがいいかと思います。

OpenShift で .NET Core 2.0を使いはじめる

$
0
0

先日、Red Hat版*1の.NET Core 2.0がリリースされました。

tech.tanaka733.net

Getting Started Guide - Red Hat Customer Portal

続いてOpenShiftでも利用可能なコンテナやテンプレートも提供されました。OpenShift本体のアップデートとは別ものとして、イメージやテンプレートの更新が提供されています。

Chapter 2. .NET Core 2.0 on Red Hat OpenShift Container Platform - Red Hat Customer Portal

というわけで実際に使ってみましょう。

まずは手順に従って、imagestreamを設定するのですが、最初は検証用のプロジェクトを作ってそのプロジェクトにimagestreamを作ってみましょう。

$ oc create -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/dotnet_imagestreams.json

複数のプロジェクトで共有できるようにするにはopenshift名前空間に作るのですが、おおくの場合で1.0のimagestreamが存在しているはずなのでreplaceします。

$ oc replace -n openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/dotnet_imagestreams.json

これで.NET Core 2.0のコンテナイメージをimagestreamから参照できます。2.0のコンテナイメージからdotnet-runtimeという.NET Core SDK全部入りではなくて.NET Core のRuntimeのみがインストールされている軽量なコンテナが提供されています。

Container Catalog - Red Hat Customer Portal

Container Catalog - Red Hat Customer Portal

2.0-5の時点で全部入りが324.8 MBに対してRuntimeのみが227.1 MBなので100MBほど軽くなっています。このRuntimeを使ったテンプレートは最後に紹介します。

さて、imagestreamを作成もしくは更新しておくと新規にアプリケーションが作れます。ドキュメントにあるように、典型的にはこんなコマンドでアプリのGitリポジトリーのリンクと合わせて指定します。

$ oc new-app --name=exampleapp dotnet:2.0~https://github.com/redhat-developer/s2i-dotnetcore-ex#dotnetcore-2.0 --build-env DOTNET_STARTUP_PROJECT=app

OpenShiftではs2iという仕組みによりアプリのリポジトリを指定すると自動的にbuild用のコンテナが起動し、そのコンテナ内でリポジトリからのクローンとアプリのビルドが行われます。.NET Coreの場合build用のコンテナは先程の.NET Core SDK 全部入りのコンテナになります。基本的にはデフォルトの設定でいい感じにビルドできるようになっています。また.NET Core 1.xの時はリスニング用のポートの設定を記述しないといけなかったのですが、環境変数でデフォルトのポート8080を指定しているので、dotnet new mvcとdotnetコマンドで作成されるテンプレートのプロジェクトをなにも変更することなしにデプロイできるようになっています。

oc new-appコマンドで最低限のアプリは作れるのですが、実際に使われるアプリにより近い例としてアプリのテンプレートが用意されています。これも2.0対応したものを有効にします。imagestream同様まずはプロジェクト内に作成します。f:id:tanaka733:20170906165239p:plain

$ oc create -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-example.json
$ oc create -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-runtime-example.json
$ oc create -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-pgsql-persistent.json

プロジェクト間で共有するには同様にopenshift名前空間に作るのですが、既存のテンプレートがあるかもしれないので、createとreplaceを両方実行してしまうのが手っ取り早いです。

$ oc create -n openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-example.json
$ oc create -n openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-runtime-example.json
$ oc create -n openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-pgsql-persistent.json
$ oc replace -n openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-example.json
$ oc replace -n openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-runtime-example.json
$ oc replace -n openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-pgsql-persistent.json

テンプレートを追加すると、コマンドラインからも利用できますが、OpenShiftのWeb consoleからも参照できます。プロジェクトの画面から、Add to project>Browse catalogを選んで、.NET を選ぶと表示されます。

f:id:tanaka733:20170906165225p:plainf:id:tanaka733:20170906165207p:plainf:id:tanaka733:20170906165300p:plain

これで好きなテンプレートを選ぶと次のような画面が表示されます。

f:id:tanaka733:20170906165422p:plain

Try it outでサンプルリポジトリの値を入力してくれます。その場合はアプリ名だけいれればOKです。またより詳細な設定を行うこともできます。

f:id:tanaka733:20170906165434p:plain

これでアプリを作成すると、ビルド、デプロイが実行されてアプリのコンテナが起動してくるはずです。

さて、.NET Core 1.0のころからあったs2iでのビルドとテンプレートのアプリの場合、アプリケーションのコンテナは.NET Core SDKが入っている状態のコンテナにアプリのプロジェクト一式とビルド成果物を配置したものになります。ただ、アプリを実行するだけなのに.NET Core SDKが入っているのは重いだということで、.NET Core Runtimeだけが入ったコンテナが提供されました。そして、同じようにs2iでアプリのリポジトリだけを指定すれば最終的に、.NET Core Runtimeだけがはいったイメージにアプリのビルド成果物だけを加えたアプリのポッドを作るためのテンプレートがdotnet-runtime-exampleになります。

使い方は他のテンプレート同じく必要なパラメーターを入力すればよいです。実際にビルドする流れとしては、まずは以前からあるs2iのビルドを実行して、.NET Core SDK + アプリのコード + アプリのビルド成果物 が入っているコンテナを作ります。そして、もう一度ビルドを走らせて、そのコンテナ中で単純には次のDockerfileをビルドしてアプリのコンテナを作成します。

FROM dotnet-runtime:..
ADD app.tar.gz .

アプリのビルド成果物のみをdotnet-runtimeイメージに追加したコンテナを作成するわけです。これでより軽量なアプリのコンテナを作成することができます。

*1:Red Hatのサポートが受けられる

SQLCAT チームが出した SQL Server on Linux の監視ツールをOpenShift上で動かそうとしてみた

$
0
0

2か月ほど前にリリースされたブログ記事の話になります。

How the SQLCAT Customer Lab is Monitoring SQL on Linux | SQL Server Customer Advisory Team

日本語ではこちら。

blog.engineer-memo.com

せっかくコンテナなので、OpenShift上で動かそうとしてみた結果をまとめてみます。(現時点ではそこまでうまくは動いていない)

最大の問題は実はこの監視ツールの仕組みにあって、ブログ記事にもあるこの絵の通り、この監視ツールはSQLServer on Linuxが動いているホスト上にcollectdをコンテナとして動かし、コンテナ上のcollectdがホスト上のプロセスやらネットワークやらも監視する仕組みになっています。

https://github.com/Microsoft/mssql-monitoring/raw/master/media/solution_diagram.png

つまりこれはcollectdのコンテナはSQL Server on Linuxと同じホスト上に動かす必要があるため、コンテナをどこかのノードにスケジュールさせて動かそうとするOpenShiftとは相性が悪いつくりです。個人的には、SQL Server on Linuxをコンテナではなくホスト上のプロセスとして動かす場合は、そのホストはSQL Server専用のホストとしてCPUやらネットワークやらディスクリソースやらを占有させたいことが多いと思うので、少なくともそのホストをOpenShiftのノードとして動かすのはないかなあという考えです。もし、この監視システムをOpenShiftで動かすならOpenShiftで動かすのはinfluxdbとgrafanaの部分で、collectdはSQL Serverを動かしているホストに単独のコンテナとして動かすか、コードを書き換えてホスト上のサービスとして動かすかになるかなと思います。

という感じなのですが、今回は検証目的でやってみるということで、コンテナ上のSQL Serverをこの監視ツールで監視することにします。コンテナはすべてOpenShift上で動かします。

SQL Server on RHELをOpenShiftで動かす

OpenShift EnterpriseはホストOSはRHEL Serverを前提としていますが*1、その上で動かすコンテナはLinuxコンテナであればベースのディストリはなんでもよいです。ただ、サポートの観点でRHELベースにしたいという要件はあるかと思いますので、RHELベースのコンテナを動かしてみたいと思います。dockerhubで提供されているコンテナを動かす場合はこの部分は省略できます。

MicrosoftがGitHubにDockerfileを提供しているのでこれを使います。

github.com

このDockerfileをビルドしてイメージを作ればよいのですが、RHELのsubscriptionをコンテナ上で扱う場合、docker buildを実行するホストOSはRHELでかつ適切なsubscriptionを登録している必要があります。おそらくRHEL Serverのsubscriptionを登録していれば動くと思いますので、このDockerfileの存在するディレクトリに移動してビルドします。

$ docker build .

手元で作ったdockerイメージをOpenShiftで動かす場合、dockerイメージをOpenShiftのinternal registryに登録する必要があります。詳細な手順はこのドキュメントを参照してください。

Managing Images | Developer Guide | OpenShift Container Platform 3.6

さて、Dockerhubのイメージであれ作成したイメージであれ、コンテナ内のSoLを動かすのにroot権限が必要です。OpenShiftではデフォルトではこの挙動は許可していないため、適当に許可してやる必要があります。

blog.openshift.com

今回はこのコマンドで許可しています。

$ oadm policy add-scc-to-user anyuid -z default

後はイメージを指定してSoLのコンテナを起動します。環境変数が以前のバージョンとは変わっているので、最新版のドキュメントを参照してください。(次のコマンドはopenshift名前空間にmssql-server-linuxという名前でpushしたイメージを使う場合)

$ oc new-app openshift/mssql-server-linux -e ACCEPT_EULA=Y -e MSSQL_SA_PASSWORD=<Password> -e MSSQL_PID=Developer --name mssql
InfluxDB

ここから実際の監視ツールのセットアップに入ります。ちなみにGitHubのリポジトリにはrun.shとDockerfile(とそこから参照するファイル)が置いてありますが、デフォルトの設定で動かす場合はrun.shファイルだけでOKです。Dockerfileは利用するDockerイメージに手を入れたい場合に使います。

InfluxDBの場合、環境変数を指定してdockerイメージを起動すればよいことがわかります。データ永続化のためにホスト側のディレクトリをマウントしていますが、今回は無視します。

mssql-monitoring/run.sh at master · Microsoft/mssql-monitoring · GitHub

するとOpenShiftにInfluxDBをデプロイするコマンドはこうなります。

$ oc new-app microsoft/mssql-monitoring-influxdb:latest -e INFLUXDB_DATA_DIRECTORY=/host/influxdb/data/db -e INFLUXDB_META_DATA_DIRECTORY=/host/influxdb/data/meta -e INFLUXDB_WAL_DATA_DIRECTORY=/host/influxdb/wal/wal -e INFLUXDB_HH_DATA_DIRECTORY=/host/influxdb/data/hh -e INFLUXDB_COLLECTD_LISTEN_PORT=25826 --name=influxdb

これでデプロイは完了しますが、このままだとこのコンテナが再起動するたびに接続するIP(コンテナに割り振られるIP)が変わります。OpenShift側でサービスを作成してあげると指定したポートに対して、コンテナが再起動しても変更しないIPを発行することができます。これはコンテナが複数台で稼働する場合もこのIPにアクセスすることでリクエストが複数コンテナに割り振られるので、ロードバランサーと考えるとよいでしょう。

$ vim svc-influxdb.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: influxdb
  name: influxdb
spec:
  ports:
  - name: 25826-udp
    port: 25826
    protocol: UDP
    targetPort: 25826
  - name: 8086-tcp
    port: 8086
    protocol: TCP
    targetPort: 8086
  selector:
    deploymentconfig: influxdb
  sessionAffinity: None
  type: ClusterIP
$ oc create -f svc-influxdb.yaml

ちなみに、SQL Serverのコンテナをデプロイした場合は、デフォルトでサービスも作成されているはずです。

collectd

collectdを作成する前にブログにもある通り、接続するユーザーを準備しておきます。対象のSQL Serverにログインして次のコマンドを実行しておきます。

USE master; 
GO
CREATE LOGIN [collectd] WITH PASSWORD = N'mystrongpassword';
GO
GRANT VIEW SERVER STATE TO [collectd]; 
GO
GRANT VIEW ANY DEFINITION TO [collectd]; 
GO

collectdもこんな感じで作成したいのですが、1つ問題があります。それはcollectdのconfigurationが127.0.0.1上のSQL Serverへの接続を前提にしていることです。環境変数で変更できるようになっているのですが、どうも設定もれのようです。

mssql-monitoring/collectd.conf at master · Microsoft/mssql-monitoring · GitHub

実際に設定した環境変数はsedコマンドで書き換えられて、collectdに渡されます。

mssql-monitoring/run-collectd.sh at master · Microsoft/mssql-monitoring · GitHub

ので、先ほどの該当行をこんな風に書き換えてから、新たにdockerイメージを作成することにしました。

        DriverOption "host" "##SQL_HOSTNAME##"

作成したdockerイメージはSQL Serverの時と同じようにOpenShiftにpushしてから、デプロイします。

$ oc new-app mssql/collectd -e INFLUX_DB_SERVER=<作成したサービスのClusterIP> -e INFLUX_DB_PORT=25826 -e SQL_HOSTNAME=<SQL ServerのIP> -e SQL_USERNAME=<上のコマンドで作成したユーザー(スクリプトのままならcollectd)> -e SQL_PASSWORD=<作成したユーザーのパスワード> -e SQL_POLL_INTERVAL=5

ちなみに最初にかいた通り、ホスト側のprocを見に行くことはできないのでログはこんな風にでますが、SQLによる監視に関しては動いています。また、collecd.confの書き換えがうまくできていない場合はこのログにDBへの接続エラーのメッセージがでます。

$ oc logs dc/collectd
*** Running /etc/my_init.d/00_regen_ssh_host_keys.sh...
*** Running /etc/rc.local...
*** Booting runit daemon...
*** Runit started as PID 8
umount: /proc: must be superuser to unmount
mount: mount /host/proc on /proc failed: Permission denied
Plugin `df' did not register for value `ReportReserved'.
Sep 10 09:02:34 collectd-2-wkxlp syslog-ng[16]: syslog-ng starting up; version='3.5.6'
Initialization complete, entering read-loop.
Sep 10 09:17:01 collectd-2-wkxlp CRON[50]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Grafana

Grafanaはdockerhub上のイメージをそのまま動かしているだけなのですが、これもそのままでは動かないという問題がありました。/etc/grafana/grafana.ini というファイルが存在しない場合に起動に失敗するという問題があるためです*2。OpenShiftの場合、設定ファイルであればConfigMapsという仕組みを使うことで、dockerイメージを変更することなく、外部からファイルを指定したディレクトリにマウントすることができます。ConfigMapsなどからのマウントはいったんnew-appコマンドで作成してから編集する必要があるのでまず作成します。

$ oc new-app grafana/grafana --name grafana

grafana.iniが存在していれば中身は空でもよいのでConfigMapsはこのコマンドで作成します。

$ touch grafana.ini
$ oc create configmap grafana --from-file=grafana.ini

おそらくデフォルトの状態でデプロイしたgrafanaはemtprydirという種類のVolumeがマウントされているはずです。

$ oc volume dc/grafana --list
deploymentconfigs/grafana
  empty directory as grafana-1
    mounted at /etc/grafana/
  empty directory as grafana-2
    mounted at /var/lib/grafana
  empty directory as grafana-3
    mounted at /var/log/grafana

ので、いったん削除してConfigMapをマウントします。

$ oc volume dc/grafana --delete --name=grafana-1
$ oc volume dc/grafana --add --type=configmap  --configmap-name=grafana --mount-path=/etc/grafana

これでgrafanaが起動するはずです。そしてgrafanaもInfluxDB同様に外部から接続するのでサービスを作成します。

$ vim svc-grafana.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: grafana
  name: grafana
spec:
  ports:
  - name: 3000-tcp
    port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    deploymentconfig: grafana
  sessionAffinity: None
  type: ClusterIP
$ oc create -f svc-grafana.yaml

そして、ブラウザからアクセスしたいということは多くの場合OpenShiftの外部から接続したいということになります。サービスは内部からの接続のみで、外部からの接続にはrouteを作成してあげます*3

$ oc expose svc/grafana --hostname=<ホスト名>

これで http://<ホスト名>でgrafanaに接続できるので、ブログにあるgrafanaのUI上での操作を行います。何度も書いている通り、DMVを使ったSQLに接続しての監視しか今回は意味がないため、grafanaのダッシュボードはこの設定ファイルのみを追加しました。

https://raw.githubusercontent.com/Microsoft/mssql-monitoring/master/grafana_dashboard_templates/core_sql_metrics.json

ここまでやるとこんな画面が表示されます。

f:id:tanaka733:20170910193029p:plain

今回はうまくいかないところがあるのをわかりつつ、とりあえずやってみたという記録になっているため、実際にセットアップするコマンドも少し遠回りになっています。今後、監視する仕組みについてどのようにすればいいかがわかれば、それにあわせてセットアップのコマンドもわかりやすいものに変えようと考えています。

*1:OSSコミュニティ版のOpenShift originはCentOS前提

*2:GitHub上に上がっているissueはcloseしているものの、コンテナの最新版はこのエラーが出てしまう

*3:oc create routeというコマンドもありますがこちらはSSL接続のルートを作成するコマンドです

無料のRed Hat Developer Program でSQL Server on RHELを体験してみる

$
0
0

本日10月2日にSQL Server on RHEL がGAされると発表がありました。

blogs.technet.microsoft.com

www.redhat.com

RHELだと試すのにもSubscriptionの購入が必要と思われるかもしれませんが、開発者向けプログラムを使うと無料でお試しすることができます。以前にも記事を書きましたが、ここから登録して使えます。そして、SQL Serverも試すことができます。

developers.redhat.com

このプログラムを使ってHyper-V上にRHELの仮想マシンを作成するときの注意事項が、過去の記事です。

tech.tanaka733.net

では実際にこの仮想マシン上でSQL Serverを試してみましょう。もし古いままの仮想マシンがある場合は、作り直さずともyum updateで更新すればOKです。また、subscriptionの登録も行ってください。Red Hat Developer Programの場合の手順はこの記事に記載しています。

tech.tanaka733.net

あとはMicrosoftの公式ドキュメントの手順に従えばインストールできるのですが、

docs.microsoft.com

こちらのリポジトリを使ってハンズオン形式で進めることができます。

github.com

READMEに手順が書いているのですが、git cloneした方がはやいとおもいます。

$ git clone https://github.com/mheslin/SQL-Server---RHEL-BM-Demo.git
$ cd SQL-Server---RHEL-BM-Demo
$ chmod +x *.sh

で、$ ./demo.shと実行すると実行されるコマンドが表示されながら、1つ1つインストールや基本的なDB接続とクエリを試していくことができます。画面表示が止まったと思ったらEnterキーを押すと進んでいきます。入力が求められる箇所では適宜入力してください。なお、DB管理者のパスワードはRedHat123!でないとスクリプトが動きません...

f:id:tanaka733:20171002165605p:plain

f:id:tanaka733:20171002165624p:plain

f:id:tanaka733:20171002165652p:plain

f:id:tanaka733:20171002165722p:plain

なお、この手順途中で失敗してもやりなおしできないので、もしかするとスクリプトファイルを直接みて、コピペなどで1つずつ実行した方が使いやすいかもしれません。パスワードが固定なのは実行するコマンドがこうなっているからです。

github.com

Red Hat Developer ProgramはSQL Server以外にも様々な製品が試せるのでぜひ活用してください。

SQL Server on RHEL でAD認証をセットアップする

$
0
0

SQL Server on Linux はADに参加させた端末からAD認証情報でログインできる機能があります。今回、Azure上に立てたAD DCとRHEL Serverで動作する環境が作れたのでその時の手順をまとめてみました。

docs.microsoft.com

まず、AzureADではなく、AD DCサーバーを構築しているのはsetspnなどの操作が必要だからです。で、ADの構築ですがこんな感じになります。静的IPが割当たるようにNICを作っておいて、Windows Server 2016 datacentereditionを起動します。

$ az group create -n sollab1 -l japaneast

$ az network vnet create \--resource-group sollab1 \--name myVnet \--address-prefix 192.168.0.0/16\--subnet-name mySubnet \--subnet-prefix 192.168.1.0/24

$ az network public-ip create -g sollab1 \-n pubip-myAzureDC1 \--dns-name tanaka733-addc1 \--allocation-method Static

$ az network nic create \--resource-group sollab1 \--name nic-myAzureDC1 \--vnet-name myVnet \--subnet mySubnet \--public-ip-address pubip-myAzureDC1 \--private-ip-address 192.168.1.4

$ az vm create --resource-group sollab1 \--name AzureDC1 \--image win2016datacenter \--admin-username clouduser \--admin-password P@ssword123 \--nics nic-myAzureDC1

起動したWindows ServerにAD DCをセットアップする手順はこちらのドキュメントを参考にしました。なお、今回ドメイン名はexample.netにしています。

gallery.technet.microsoft.com

DNSサーバーの設定まで完了したら、該当VNet(上の例だとmyVnet)のDNSサーバーをAzure defaultからAD DCサーバーの192.168.1.4に変更します。

次にSQL ServerをインストールするRHEL Server仮想マシンを作成します。今回はカスタムイメージ(VHDファイル)をアップロードしています。NICは上の手順と同様にして作成してください。

$ az vm create --resource-group sollab1 --name SORHEL1 --image'<uploaded_image_id>'--admin-username clouduser --admin-password P@ssword123  --nics nic-mysorhel1

起動後、FQDNでホスト名を割り当てておきます。

$ sudo hostnamectl set-hostname sorhel1.example.net

また、ドキュメントの手順に従ってSQL Serverもインストールしておきます。

docs.microsoft.com

次に、AD DCにユーザーとDNSレコードを追加しておきます。

ユーザー: solrhel1@example.net

DNSレコード: sorhel1.example.net に対し、RHEL Serverに割り当てたprivate IPアドレス

ここから、ドキュメントに従ってAD認証をセットアップしていきます。

docs.microsoft.com

設定に使ったのは下記の値です。

realm: EXAMPLE.NET

user: solrhel1@example.net

以下、いくつか途中で困ったコマンドの実行結果になります。

realm joinするときにパッケージが不足していると言われることがあるのでその場合は追加でインストールします。

# realm join EXAMPLE.NET -U 'solrhel1@example.net' -v
 * Resolving: _ldap._tcp.example.net
 * Performing LDAP DSE lookup on: 192.168.1.4
 * Successfully discovered: example.net
Password for solrhel1@example.net: 
 * Couldn't find file: /usr/sbin/sssd * Required files: /usr/sbin/oddjobd, /usr/libexec/oddjob/mkhomedir, /usr/sbin/sssd, /usr/bin/net * Resolving required packages ! PackageKit not available: The name org.freedesktop.PackageKit was not provided by any .service files ! Necessary packages are not installed: oddjob, oddjob-mkhomedir, sssd, samba-common-toolsrealm: Couldn't join realm: Necessary packages are not installed: oddjob, oddjob-mkhomedir, sssd, samba-common-tools

# yum install oddjob oddjob-mkhomedir sssd samba-common-tools

完了するときはこう表示されます。

# sudo realm join EXAMPLE.NET -U 'solrhel1@example.net' -v
 * Resolving: _ldap._tcp.example.net
 * Performing LDAP DSE lookup on: 192.168.1.4
 * Successfully discovered: example.net
Password for solrhel1@example.net: 
 * Required files: /usr/sbin/oddjobd, /usr/libexec/oddjob/mkhomedir, /usr/sbin/sssd, /usr/bin/net
 * LANG=CLOGNAME=root /usr/bin/net -s /var/cache/realmd/realmd-smb-conf.0FZH7Y -U solrhel1@example.net ads join example.net
Enter solrhel1@example.net's password:DNS update failed: NT_STATUS_INVALID_PARAMETERUsing short domain name -- EXAMPLEJoined 'SORHEL1' to dns domain 'example.net'No DNS domain configured for sorhel1. Unable to perform DNS Update. * LANG=C LOGNAME=root /usr/bin/net -s /var/cache/realmd/realmd-smb-conf.0FZH7Y -U solrhel1@example.net ads keytab createEnter solrhel1@example.net's password:
 * /usr/bin/systemctl enable sssd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/sssd.service to /usr/lib/systemd/system/sssd.service.
 * /usr/bin/systemctl restart sssd.service
 * /usr/bin/sh -c /usr/sbin/authconfig --update--enablesssd--enablesssdauth--enablemkhomedir--nostart&& /usr/bin/systemctl enable oddjobd.service && /usr/bin/systemctl start oddjobd.service
 * Successfully enrolled machine in realm

# id solrhel1@example.netuid=113001103(solrhel1@example.net)gid=113000513(domain users@example.net)groups=113000513(domain users@example.net)

ドキュメントにある通り、kinitコマンドで@の後ろは大文字で指定します。

# kinit solrhel1@EXAMPLE.NET
Password for solrhel1@EXAMPLE.NET: 

# klist 
Ticket cache: KEYRING:persistent:0:0
Default principal: solrhel1@EXAMPLE.NET

Valid starting       Expires              Service principal
10/12/201702:41:0610/12/201712:41:06  krbtgt/EXAMPLE.NET@EXAMPLE.NET
    renew until 10/19/201702:41:03

AD DCサーバーでの作業はこんな感じになります。

PS > Import-Module ActiveDirectory
PS > New-ADUser mssql -AccountPassword (Read-Host -AsSecureString "Enter Password") -PasswordNeverExpi
res $true -Enabled $true
Enter Password: ********
PS > setspn -A MSSQLSvc/sorhel1.example.net:1433 mssql
Checking domain DC=example,DC=net

Registering ServicePrincipalNames for CN=mssql,CN=Users,DC=example,DC=net
        MSSQLSvc/sorhel1.example.net:1433
Updated object

kvnoコマンドはこんな感じ。

# kvno MSSQLSvc/sorhel1.example.net:1433
MSSQLSvc/sorhel1.example.net:1433@EXAMPLE.NET: kvno =2# ktutil
ktutil:   addent -password-p MSSQLSvc/sorhel1.example.net:1433@EXAMPLE.NET -k2-e aes256-cts-hmac-sha1-96
Password for MSSQLSvc/sorhel1.example.net:1433@EXAMPLE.NET: 
ktutil:  addent -password-p MSSQLSvc/sorhel1.example.net:1433@EXAMPLE.NET -k2-e rc4-hmac
Password for MSSQLSvc/sorhel1.example.net:1433@EXAMPLE.NET: 
ktutil:  wkt /var/opt/mssql/secrets/mssql.keytab
ktutil:  quit

で最後にSQL ServerにログインしたWindows認証ログインを作成して完了です。

# sqlcmd -S sorhel1.example.net -U SA1> CREATE LOGIN [EXAMPLE\solrhel1] FROM WINDOWS;
2> go
1> SELECT name FROM sys.server_principals;
2> GO
name                                                                                                                            
--------------------------------------------------------------------------------------------------------------------------------
sa                                                                                                                              
public                                                                                                                          
sysadmin                                                                                                                        
securityadmin                                                                                                                   
serveradmin                                                                                                                     
setupadmin                                                                                                                      
processadmin                                                                                                                    
diskadmin                                                                                                                       
dbcreator                                                                                                                       
bulkadmin                                                                                                                       
##MS_SQLResourceSigningCertificate##                                                                                            ##MS_SQLReplicationSigningCertificate##                                                                                         ##MS_SQLAuthenticatorCertificate##                                                                                              ##MS_PolicySigningCertificate##                                                                                                 ##MS_SmoExtendedSigningCertificate##                                                                                            ##MS_PolicyEventProcessingLogin##                                                                                               ##MS_PolicyTsqlExecutionLogin##                                                                                                 ##MS_AgentSigningCertificate##                                                                                                  
BUILTIN\Administrators                                                                                                          
NT AUTHORITY\NETWORK SERVICE                                                                                                    
NT AUTHORITY\SYSTEM                                                                                                             
EXAMPLE\solrhel1                                                                                                                

(22 rows affected)

これで、ADユーザーとしてログインしたLinux端末上からSQL Serverにログインできるようになります。今回は、SQL Serverをインストールした同じホストに、suコマンドでユーザーを切り替えて試してみました。

# su sorhel1@example.net

$ sqlcmd -S sorhel1.example.net
1>

注意事項としては、IPアドレスやADドメインではないpublicnなドメインでは認証できません。

$ sqlcmd -S 192.168.1.5
Sqlcmd: Error: Microsoft ODBC Driver 13for SQL Server : SSPI Provider: Server not found in Kerberos database.
Sqlcmd: Error: Microsoft ODBC Driver 13for SQL Server : Cannot generate SSPI context.

Red Hat Container Development Kit を使って、.NET Core on Linux containerを無料で体験する

$
0
0

先日の記事に続いて、Red Hat Developer Programを利用しての無料体験の宣伝です。

developers.redhat.com

.NET Core on RHEL (Red Hat Enterprise Linux Server)はRHELサーバー上でも動くのですが、Container Platform製品であるOpenShift上での利用もおすすめです。Gitリポジトリを指定するだけでContainerを作成して配置、ルーティングまでやってくれるところや、コンテナのスケーリング、死活監視など、.NET Coreアプリを配置する際にいろいろ面倒なところをやってくれます。

developers.redhat.com

ただ、無償でお試しするにはハードルがあり、現状の選択肢としては、OpenShift Onlineの無償枠(Activateされるまで時間かかることも)、Azure上でのTest Drive(短時間のみ)、upstream projectであるOpenShift origin(CentOSで動くが、製品版とは厳密には異なる)などいろいろ条件があります。

そこで今回は、ローカルのWindows/Mac/Linux上でシングルインスタンスで動く、Container Development Kitを紹介して、Windowsユーザー向けに.NET Coreアプリを配置するまでを説明してみようと思います。インストール手順はドキュメントを詳細してもらうことにして、いくつか注意点をまとめていきます。

developers.redhat.com

インストール手順のページを見るとわかりますが、まずはRed Hat Development Suite for Windowsをインストールします。インストーラーを起動するとまずインストール先を指定します。

f:id:tanaka733:20171020153722p:plain

このあとインストールするコンポーネントやHypervisorの選択などを行って、前提条件のチェックを行うのですが、このチェック時間がかかる上にスクリーンショットを撮ろうとしたり、Windowのフォーカスを切り替えたりすると最初からやりなおしになるので注意してください。

Development SuiteがインストールされたらCDKのインストールに移ります。Hyper-Vの場合、externalな仮想ネットワークスイッチを作って、その名前を環境変数に渡してから、インストールします。cmdとPowerShellのエスケープの違いに注意と書いています。

f:id:tanaka733:20171020150541p:plain

インストールされると、Hyper-Vにminishiftという名前の仮想マシンが作成されているはずです。

f:id:tanaka733:20171020151335p:plain

ここまで来たら、minishift startで起動します。正しく起動したときはこんな感じのログになるはずです。

f:id:tanaka733:20171020151451p:plain

うまくいかない場合は、Hyper-Vに対する操作が失敗していることが多いと思いますので、ログやHyper-V側の状態を確認してみてください。さて、表示されたURLにアクセスするとOpenShiftのWeb Consoleが表示されます。

f:id:tanaka733:20171020151611p:plain

空文字以外の任意のパスワードでログインできる状態になっているので、ユーザー名developerでログインします。

f:id:tanaka733:20171020151730p:plain

さて、Add To Projectでさっそく.NET Coreのプロジェクトを追加したいのですが、残念ながらデフォルトでは追加されていませんでした。

f:id:tanaka733:20171020151819p:plain

以前書いた記事に沿ってimagestreamとtemplateを追加してください。-n openshiftをづけることでopenshift名前空間にインポートすることができ、その場合は全てのプロジェクトから参照できます。

Chapter 2. .NET Core 2.0 on Red Hat OpenShift Container Platform - Red Hat Customer Portal

~~~ $ oc create --namespace openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/dotnet_imagestreams.json

$ oc create --namespace openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-example.json $ oc create --namespace openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-runtime-example.json $ oc create --namespace openshift -f https://raw.githubusercontent.com/redhat-developer/s2i-dotnetcore/master/templates/dotnet-pgsql-persistent.json ~~~

f:id:tanaka733:20171020152018p:plain

再度、先程のAdd To Projectの画面に戻ると.NET が追加されています。

f:id:tanaka733:20171020152102p:plain

.NET を選択して、Exampleを選択します。ここからがOpenShiftのs2iと呼ばれる機能をつかって行くのですが、containerで動かしますが、面倒なDockerfileを用意する必要はありません*1。gitリポジトリを指定すると、そこからclonseしてビルドして、成果物を配置して必要なポートを開放したコンテナを自動でビルドしてくれます。ということで必要なのは、ASP.NET Coreプロジェクトをpushしたgitリポジトリです。また、基本的には、ASP.NET CoreプロジェクトにOpenShift用の特別な設定を入れる必要はありません。リスニングするポートもOpenShiftが環境変数に渡しているので、ASP.NET Coreプロジェクトもそれに倣っていればOKです。また、自分で用意しなくても、Try it outのリンクをクリックすると用意されているexampleプロジェクト用のパラメーターを入れてくれます。

ただ、minishiftを使う場合1つ自前で設定しないといけないパラメーターがあります。アプリケーションにアクセスするためのhostnameです。手元のブラウザからコンテナ上のブラウザでアクセスするには、指定したドメインがOpenShift(minishift)のrouterのIPアドレスに解決される必要があります。

f:id:tanaka733:20171020152805p:plain

hostsファイルに書いてもいいのですが、もっと簡単には、nip.io といった好きなホスト名からprivat アドレスも解決してくれるようなサービスを使うと便利でしょう。解決すべきIPは、今アクセスしているOpenShiftのWeb Consoleのアドレスと同じです。この状態では、portが8443であればWeb Consoleにアクセスし、portが80もしくは443なら、routerにアクセスし、アプリケーションへリクエストを振り分けてくれます。

NIP.IO - wildcard DNS for any IP Address

というわけでhostnameを入力してアプリケーションを作成して、プロジェクトの画面に戻るとこんな表示になっているはずです。ビルドとデプロイの様子が確認できます。

f:id:tanaka733:20171020153406p:plain

デプロイ完了後に、先程入力してホスト名にアクセスするとアプリケーションが表示されます。

f:id:tanaka733:20171020153451p:plain

以上で、.NET Core on Linux containerがWindows上でお手軽に試せました。minishiftは単一ホストのOpenShiftにかなり近く、他にも様々な機能が利用できるので今後紹介していきたいと思います。

*1:Dockerfileを用意してビルドする方法も用意されています

ふくてん Fukuoka .NET Conf で ASP .NET Coreのセッションをしました

$
0
0

国内では初めて東京近郊以外の地域*1でセッションしました。資料はこちらです。

www.slideshare.net

セッションで紹介した(しようとした)サンプルコードのGitHubリンクはこちらです。

まず、最初のリモートデバッグのところですが、後でお見せしたデモ動画の中でリモート接続していたアプリはこのリポジトリです。といっても、これはdotnet new mvcで作ってソリューションファイルを追加しただけのアプリです。この素のアプリでLinux containerの上でリモートデバッグもできます。

github.com

次の設定ファイルの注入はここにサンプルアプリがあります。OpenShift上で動かしてOpenShift(kubernetes)のconfigmapと組み合わせるデモなのですが、/etc/data/appsettings.jsonに設定ファイルを置けばどこでも動きます。

github.com

ファイルパスがunix前提なので変更したい場合はここを変更します。

dotnetcore-demo-app/Startup.cs at master · tanaka-takayoshi/dotnetcore-demo-app · GitHub

appsettings.jsonはこの形式を前提にしています。

{
  "Option1": "Ignite!!",
  "Option2": "2017",
  "subsection": {
    "SubOption1": "Container is Linux"
  }
}

HTTPセッションをRedisに格納するサンプルはこちらです。以前やったデモの一部なのでサブディレクトリに格納されています。

github.com

Redisですが、今回はAzure Redis Cacheをつかっています。それ以外に普通のどこかにRedisサーバーを動かしてもよいです。Redisの接続情報は環境変数REDIS_CONNECTION_STRINGに設定するとそれを使います。ConnectionStringはStackExchange.Redisの形式ですが、Azure Redis Cacheの場合はAzure Portalからコピーできる形式です。

f:id:tanaka733:20171021153315p:plain

f:id:tanaka733:20171021153327p:plain

具体的にはこんな形式です。

<name>.redis.cache.windows.net:<port>,password=<password>,ssl=True,abortConnect=False

最後に紹介した、ASP.NET CoreのBlog Templateですが、本家のサイトはこちらです。

github.com

このプロジェクトはプロジェクトテンプレートをインストールして、テンプレートとして実際に動かすプロジェクトを生成する仕組みなのですが、Linuxで動かせるように修正した状態のプロジェクトがこちらになります。

github.com

実際に動かして使いたい場合は、SQLiteの保存先(上では/etc/data/以下)と、ブログ投稿データの保存先(./BlogFiles)を永続化しておくのがよいでしょう。

あと肝心のOpenShift宣伝タイムでいい忘れていたのですが、OpenShiftに興味あるけどいきなり弊社営業に問い合わせるのはハードルが高すぎるという場合は昨日書いた、Windows/Mac/Linuxのシングルホストで動かせるContainer Development Kitを使ってみてください。

tech.tanaka733.net

質問などあればぜひTwitterなどでお寄せください。

*1:筑波を含む

Azure Container Service (AKS) でAzure Managed DiskをVolumeとして試してみる

$
0
0

Azureのマネージドなkubernetesサービス Azure Container Service (AKS) がpreviewとしてリリースされました。

azure.microsoft.com

デフォルトでkubernetes 1.7が使われるのですが、このバージョンからAzure Managed DiskがVolumeとして使えるはずなので試してみました*1

github.com

Azure PD (Managed/Blob) by khenidak · Pull Request #46360 · kubernetes/kubernetes · GitHub

AKSのセットアップ手順はこのドキュメントに従います。

docs.microsoft.com

注意事項として現時点では、ukwestとwestus2しか利用可能でないので、それ以外のlocationを指定するとエラーになります。

$ az group create --name myK8sGroup --location japaneast
$ az aks create --resource-group  myK8sGroup --name myK8sCluster --agent-count 1 --generate-ssh-keys
//中略
The provided location 'japaneast' is not available for resource type 'Microsoft.ContainerService/managedClusters'. List of available regions for the resource type is 'ukwest,westus2'.

locationが正しいのに、リソースタイプがーというエラーが出ることがあります。

$ az aks create --resource-group  myK8sGroup --name myK8sCluster --agent-count 1 --generate-ssh-keys
The subscription is not registered for the resource type 'managedClusters'. Please re-register for this provider in order to have access to this resource type.

この場合、Azure Portalで自分のsubscriptionのResource Providerを開き、Microsoft.Container*なプロバイダーをre-registerすると動きました。re-register押してもUIに変化がないのですが、AKSが作れるようにはなりました。

f:id:tanaka733:20171025171045p:plain

また、az aksコマンドは最新のAzure CLI 2.0でしか使えないのでアップデートするかCloud Shellを使いましょう。ただ、Cloud Shellで1回permissionエラーが出ましたが、2回目は出なかったので、何度か試すとよいかもしれません。

$ az --version
azure-cli (2.0.20)

$ az aks install-cli
Downloading client to /usr/local/bin/kubectl from https://storage.googleapis.com/kubernetes-release/release/v1.8.2/bin/linux/amd64/kubectl
Connection error while attempting to download client ([Errno 13] Permission denied: '/usr/local/bin/kubectl')

セットアップするとkubernetesのバージョンが1.7.7なことがわかります。

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.1", GitCommit:"f38e43b221d08850172a9a4ea785a86a3ffa3b3a", GitTreeState:"clean", BuildDate:"2017-10-11T23:27:35Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.7", GitCommit:"8e1552342355496b62754e61ad5f802a0f3f1fa7", GitTreeState:"clean", BuildDate:"2017-09-28T23:56:03Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}

また仮想マシン一覧を見ると以前のものとは違って、別のリソースグループでAgentのみが自分のサブスクリプションの仮想マシンとして起動していることがわかります。また所属するリソースグループは、AKSを作成するときに指定したリソースグループとは別のものです。

さて、Managed Diskの利用ですが、ここにexampleがあるのでつかってみます。

examples/staging/volumes/azure_disk/claim/managed-disk/managed-hdd at master · kubernetes/examples · GitHub

$ wget https://raw.githubusercontent.com/kubernetes/examples/master/staging/volumes/azure_disk/claim/managed-disk/managed-hdd/storageclass-managed-hdd.yaml
$ wget https://raw.githubusercontent.com/kubernetes/examples/master/staging/volumes/azure_disk/claim/managed-disk/managed-hdd/pvc-on-managed-hdd.yaml
$ wget https://raw.githubusercontent.com/kubernetes/examples/master/staging/volumes/azure_disk/claim/managed-disk/managed-hdd/pod-uses-managed-hdd.yaml

$ kubectl create -f storageclass-managed-hdd.yaml
storageclass "managedhdd" created
$ kubectl create -f pvc-on-managed-hdd.yaml
persistentvolumeclaim "dd-managed-hdd-5g" created
$ kubectl create -f pod-uses-managed-hdd.yaml
pod "pod-uses-managed-hdd-5g" created

$ kubectl get pod -w
NAME                                READY     STATUS    RESTARTS   AGE
azure-vote-back-4149398501-59g50    1/1       Running   0          15m
azure-vote-front-1874756303-3f2rw   1/1       Running   0          15m
pod-uses-managed-hdd-5g             0/1       Pending   0          6s
pod-uses-managed-hdd-5g   0/1       Pending   0         1m
pod-uses-managed-hdd-5g   0/1       ContainerCreating   0         1m
pod-uses-managed-hdd-5g   1/1       Running   0         1m

kubernetesのagentの仮想マシンが所属するリソースグループの一覧を見ていると、まず新たにDiskが作成され、PodのStatusがContainerCreatingになったところでそのDiskが仮想マシンにマウントされたことがわかります。

f:id:tanaka733:20171025170043p:plain

つまりこのPluginで必要に応じたDiskの自動生成とマウントまでしてくれることがわかりました。ではこのPodを削除してみましょう。

$ kubectl delete pod pod-uses-managed-hdd-5g 
$ kubectl get event -w

eventでKilling container with id docker://az-c-01:Need to kill Podといったメッセージが出た直後に仮想マシンのDiskを見ると、DiskがアンマウントされUpdatingの状態になっていることがわかります。

f:id:tanaka733:20171025170553p:plain

つまり、Podが削除され不要になったらDiskのアンマウントリクエストが開始されます。というわけでAzure Managed Diskが使えるようになって便利になったkubernetes 1.7がAKSで使えるようになりました。

*1:それ以前はunmanaged diskしかサポートしていないので、kubernetesをインストールする仮想マシンをunmanagedにしないと、Azure DiskをVolumeとして使えないのでした

ASP.NET CoreでプロキシサーバーでSSL terminateさせるときにRequest.Schemeをhttpsにしたい

$
0
0

ASP.NET Coreを特にLinuxなどで動かす場合、Kestrelを使うことが多いのですが、Kestrel自体はシンプルなサーバーなのでフロントにHAProxynginxなどのプロキシーサーバーを配置することが多くなります。さらにHTTPSでアクセスするようにする場合、証明書はKestrel側ではなくてプロキシサーバー側に配置して、プロキシサーバーからKestrelまでは(プライベートネットワークだし)HTTPで通信するケースもあるかと思います。その場合、ASP.NET Core側でRequest.Scheme*1httpになります。これをhttpsにしたい場合のお話です。

OpenID ConnectやAzure AD B2Cなどの認証などのために、リクエストをリダイレクトする場合、ユーザーがアプリにリクエストしたURLを基にcallbackするURLを生成するため、Request.Schemeが使われます。このとき、リバースプロキシ経由でHTTPリクエストをKestrelが受信している場合、当然のごとくRequest.Schemehttpになります。

f:id:tanaka733:20171119231146p:plain

認証サーバーに認証後にCallbackするURLも一緒に渡し場合、Request.Schemeを基にURLを構築している場合*2このURLがhttpになります。認証サービスプロバイダー側がこれを許可していれば別ですが、例えばAzure AD B2Cの場合httpsでないと許可されないため動きません。他にもうまくいかないプロバイダーや認証以外のサービスもあると思います。そこで、ASP.NET Core側にhttpsでユーザーからリクエストは送信されて、リバースプロキシ経由でhttpになっていることを伝える必要がでてきます。 実はこの設定については、タイトルがnginxなので自分はすっかり読み飛ばしていたのですが、ASP.NET Coreのドキュメントにも載っています。

docs.microsoft.com

まず前提条件として、リバースプロキシサーバーがHTTPリクエストをKestrelに送信する場合に、X-Forwarded-ProtoというHTTPヘッダーにオリジナルのリクエストのプロトコルを値にしたヘッダーを追加している必要があります。多くの場合、X-Forwarded-Forと併せて設定されているのではないかと思います。

developer.mozilla.org

この条件のもと次のようなミドルウェアを追加するコードをStartupクラスのConfigureメソッドに記述します。認証サービスで利用する場合は、サンプルのようにUseAuthenticationメソッドの前に記述する必要があります。

//usingusing Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpOverrides;
//

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

このメソッドはMicrosoft.AspNetCore.HttpOverridesというNuGetライブラリで提供されていますが、Microsoft.AspNetCore.Allが依存しているのでこれを参照している場合は明示的に追加する必要はありません。

www.nuget.org

これでこのミドルウェアを通った後は、HTTPヘッダーからX-Forwarded-Protoがなくなり、Request.Schemehttpsを返すようになるのでめでたし、ということになります。

*1:RequestはMicrosoft.AspNetCore.Mvc.ControllerBase クラスのプロパティ

*2:少なくとも現時点のAzure AD B2CのASP.NET Core向けライブラリはRequest.Schemeを内部で参照しており、変更不可だった

SQL Server をRHELのコンテナーで動かすDockerfileを公開しました

$
0
0

SQL Server on Linux がGAされたわけですが、Dockerで動かしたいとなった場合、Ubuntuベースのものしか公開されていなかったので、RHEL版のコンテナーを動かすためのDockerfileを作ってみました。

Microsoftが公開しているSQL Server on Linuxのdockerコンテナーはこれですが、Ubuntuベースのものとなっています。

https://hub.docker.com/r/microsoft/mssql-server-linux/

じゃあ元のDockerfileを見て他のディストリ版を作ろうと思っても./installというフォルダの中身が公開されておらず、お手上げ状態です。

mssql-docker/Dockerfile at 1efc4cf9b78fa5fccea682f26067189660af85c8 · Microsoft/mssql-docker · GitHub

無人インストールの手順は公開されているので、これを元にDockerfileを作ろうとも考えたのですが...

docs.microsoft.com

mssql-confを実行するとわかるのですが、GAのタイミングでmssql-confsudoコマンドを必須とするようになってしまいました*1。1,2箇所ならモンキーパッチでもあてようとおもったのですが、これスクリプトを検索すればわかるのですが、いたるところにsudoコマンドでの実行がハードコーディングされているので、ちょっとDockerfileの中でごにょごにょするのは無理がありました。

で、どうしたかというと、実はSQL Server on Linuxはmssql-confを実行せずとも環境変数を適切に設定すれば動きます。コンテナでの起動を前提に考えれば実行ユーザーもroot固定としてよいので*2、ユーザー作成なども考えなくてもよさそうです。環境変数の一覧はここに書いてあります。

docs.microsoft.com

というわけで以上を踏まえて、RHELをベースとしたdockerイメージを作るためのDockerfileを作ってみました。

github.com

RHELをベースとしたコンテナをビルドする際の一般的な注意事項として、適切なsubscriptionを持っているRHEL Serverをホストにしてdocker buildしないとパッケージのインストールでエラーになる可能性があります。また、なぜかMSSQL_LCIDの指定をしてdocker buildすると実行エラーになったので、ビルドしたコンテナを起動するときに環境変数で指定するようにしてください。

Unofficial でサポートされませんが、開発環境などでつかってみたいという場合にはぜひどうぞ。

*1:preview版ではroot権限があればsudoがなくても動いていた

*2:本当は任意のUIDで実行できるようになるのがいいのですが、そこまではまだできなそうなので

FedoraやRHELの.NET CoreでVisual Studio CodeでのC# コード編集支援機能が使えない場合の対処法

$
0
0

.NET Core 2.0でRHELもcsproj形式をサポートしたり、Fedoraもサポートされるようになったのですが、Red HatやFedoraコミュニティから提供されている.NET Core SDKを入れた状態でVisual Studio CodeでC#プロジェクトを開いてもプロジェクトをロードできないと言われることがあります。この現象についてわかっている範囲でまとめたいと思います。

これはRHEL Serverの画面ですが、dotnet new consoleで作成したプロジェクトをVisual Studio Codeで開いた時に警告メッセージが表示されます。

f:id:tanaka733:20171124004949p:plain

コンソールを開いてエラーメッセージを開くとこんなのが出ています。

[fail]: OmniSharp.MSBuild.ProjectFile.ProjectFileInfo
        The "Microsoft.NET.Build.Tasks.ReportAssetsLogMessages" task could not be loaded from the assembly /opt/rh/rh-dotnet20/root/usr/lib64/dotnet/sdk/2.0.3/Sdks/Microsoft.NET.Sdk/build/../tools/net46/Microsoft.NET.Build.Tasks.dll.  Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.

どうやらOmniSharp*1のライブラリがnet46とあるように、.NET Framework由来のライブラリを参照しようとしているが、RHEL用の.NET Core SDKにはそんなものはないのでプロジェクトのロードに失敗しているようです。

というわけで報告したissueがこちらになります。

github.com

どうもOmniSharpでは.NET Framework由来のライブラリを参照し、Linux上ではmono経由で動かしているようです。のですが、RHELやFedoraなど一部のディストリのみでこの問題が起きているようです。その辺の謎は派生したこちらのissueにあります。

github.com

.NET Core 2.0からは、.NET Core SDK自体をビルドする手順もオープンソースとして公開されています。が、どうやらこのリポジトリに従ってビルドしただけではnet46ターゲットの該当ライブラリが含まれていないようです。この問題が起きていないCentOSや他のディストリはおそらくMicrosoftがビルドしたバイナリそのものを利用していて、そちらには該当ライブラリが含まれているようです。

Fedoraに関して言うと、こちらの手順にしたがって2.0.2以降の.NET Core SDKをインストールすることで問題は修正されています。このパッケージはMicrosoftがビルドしたもので、インストールされたファイルの中身を見る限り、該当のライブラリも追加されているようです。

www.microsoft.com

このインストール手順、.NET Core 2.0が出たあとも何度か変更されており、自分の記憶が確かであれば、ある時期はコミュニティ版のパッケージのインストールが案内されていました。そのタイミングでインストールするとこの問題に遭遇したのではと推測しています。

一方のRHELの場合は、source-build側での対応ができていない、かつRHEL向けのパッケージはMicrosoftがビルドしていないため該当ライブラリが含まれていない状態が続いています。回避策としては、たぶん実体は同じだからsymlinkはればいいのでは?という方法が出ています。というわけで次のようなコマンドを実行してみます。

# /opt/rh/rh-dotnet20/root/usr/lib64/dotnet/sdk/2.0.3/Sdks/Microsoft.NET.Sdk/tools/
# ln -s netcoreapp1.0 net46

これで再度Visual Studio CodeでC# プロジェクトを開くと無事にプロジェクトが読み込め、コード編集支援機能が利用できる状態になっています。

f:id:tanaka733:20171124011305p:plain

根本的な解決にはまだ時間がかかりそうですが、いったんはこちらの方法で回避してみてください。ちなみに、JetBrainsのRiderではこのような問題が発生しないことを確かめています。

*1:Visual Studio CodeはC#のコード支援にOmniSharpを利用している

2017年の振り返り

$
0
0

大晦日なので2017年を振り返ってみたいと思います。

http://4.bp.blogspot.com/-in04qzs4RlQ/UYzZdO6l9eI/AAAAAAAAR6Q/rbSRaPRqpD4/s800/toshikoshisoba.png

やっていること

仕事は昨年転職してから引き続きなのですが、大きな追加事項としてはSQL Server on RHELのGAです。というわけで、最近仕事でやっていることとしては

  • OpenShift Container Platform
  • .NET Core on RHEL
  • Red Hat Products (RHEL, OpenShift etc) on Azure
  • SQL Server on RHEL

が主な項目になります*1

コミュニティ活動としてやっている内容としては、上の内容をRHELからLinux全般に広げている感じでしょうか。最近はMicrosoft Q#のリリースにあわせて量子コンピューター関連も見てたりします。が、量子コンピューターは一次ソースが論文であることが多い上に、それを編集した記事の中に微妙な誤りを見つけることが多く、じゃあこの記事全体信用できないのではと感じ、結局論文を読むという流れになっていて、がっつり中まで勉強するには覚悟を決めないといけないなあと思ってたりします。とりあえずQ#をさわり倒すところはやろうと思っています。Q#の勉強会とかもやってみたいですね。

https://1.bp.blogspot.com/-AWWkQisR46o/Wi4f_Acd_YI/AAAAAAABIsQ/wPCfzOpdaKAl_2RdFlEdOViQ71fWXnkbgCLcBGAs/s400/computer_ryoushi_quantum.png

オフライン活動

やっていることがいろんなカテゴリに渡っているので、最近は特定のコミュニティを運営するというよりは、いくつかのコミュニティにおじゃましています。Linux on Azureや量子コンピューター関連でJAZUGにおじゃますることが比較的多いのですが、

jazug.connpass.com

今年ははじめて東京圏以外*2の海外と福岡で登壇しました。

www.meetup.com

fukuten.connpass.com

海外というのは、もともと家族旅行で自分以外が別の用事で出掛けるので、自分だけなので参加できそうなmeetupでもないかなあと思って声をかけたら、話すことになりました。英語プレゼンは事前に話す内容を準備できるので、英会話するよりハードルが低いのではと思っています。

Fukuoka.NET Confは東京以外で話すなら、最初は地元の福岡がいいなあと思っていたところで、ちょうどいい機会を頂けました。普段話さない or SNSでしか話さない方とも話すことができるので、機会さえあれば来年もつづけたいですね。

あと大きめのものとしては、MIcrosoft Ignite 2017に弊社のブーススタッフとして参加してきました。ブーススタッフチケットだと展示会場しか入れないのですが、展示会場だけでもその規模の大きさに驚かされました。

Microsoft Ignite | Orlando, FL | September 25-29, 2017

今度はセッションにも参加できるような形がいいですね。

国内の有償イベントはde:code 2017には一般参加できましたが、内容があれだったこともあり来年以降の参加は難しいところです*3

オンライン活動

オンラインでは主にこのブログとBiulder Insiderさんでの連載ですが、ブログの方は今年はさぼり気味でPVも横這い状態が続いています。もともと、このブログは特にテーマなく気になったことを書き留めているので、来年以降もそのままのスタンスでほそぼそ続けていくつもりです。あと、URLのpathに公開日を入れていないので、PVランキングを2017年でフィルタリングできなかったので、来年はちゃんといれようと思いました。

Build Insiderさんでは、C# 7の新機能や.NET Core入門の連載などを書きました。

www.buildinsider.net

www.buildinsider.net

記事執筆は来年以降も機会があれば増やしていきたいなと思っています。

あとは、GitHub上での活動ですが、今年はコードを書くというよりはバグ報告をIssueであげたり、ドキュメント修正のためのPRを作るのが多かったです。コード書きたいなと思いつつも、今のところバグをみつけたり、ドキュメントが気になったりすることの方が多いので、しばらくはこのままな気がします。

という感じで、来年もよろしくお願い致します。来年最初の大きめのイベントは(NDAイベントですが)、3月のMicrosoft MVP Global Summitになりそうです。

*1:簡単にいうとRed HatとMicrosoftが技術提携している分野全般

*2:つくばは東京圏に含む

*3:一番つらかったのは、目玉の一つだと思って会社にも話していたセッションが有償申し込み締切直後にセッション内容を全く違うものに変えていて参加レポートに書けなくなってしまったことでした。アンケートでフィードバックしましたが、主催のマイクロソフトと登壇企業の方には改善を強く期待しています。


Visual Studio SDK でも ReactivePropertyを使いたい (bindingRedirect編)

$
0
0

Visual Studio SDKを使ってVisual Studio拡張を使っているのですが、UI部分をWPFで作成していて、じゃあReactivePropertyを使おうと思ったらこんなエラーが出ました。

f:id:tanaka733:20180129011635p:plain

というわけでこれに対処したいと思います。

勘のいい方だとすぐに気付くと思うのですが、NuGetできちんと依存関係解決しているのに、依存関係が見つからないということなので、bindingRedirectの問題です。実際にプロジェクトで参照しているDLLのバージョンを確認するうと、確かにパッチレベルが違う値になっています。

f:id:tanaka733:20180129175350p:plain

プロジェクトに追加されたファイルをよく見ると、app.configに次のような値が追加されています。

<?xml version="1.0" encoding="utf-8"?><configuration><runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Reactive.Core"publicKeyToken="94bc3704cddfc263"culture="neutral" /><bindingRedirect oldVersion="0.0.0.0-3.0.3000.0"newVersion="3.0.3000.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="System.Reactive.Interfaces"publicKeyToken="94bc3704cddfc263"culture="neutral" /><bindingRedirect oldVersion="0.0.0.0-3.0.1000.0"newVersion="3.0.1000.0" /></dependentAssembly></assemblyBinding></runtime></configuration>

というわけで、app.configに追加されているbindingRedirectが実際にはうまく解決されていないという問題になります。なぜかというと、Visual Studio SDKの場合、プロセス自体はdevenv.exeなのでこのプロセス起動時に渡すapp.configにこのbindingRedirectの設定が記載されていないといけないのに、Visual Studio SDKのプロジェクトのapp.configに記載があっても解決してくれないせいです。かといって、devenvはユーザー(あるいはマシン)グローバルな設定なので、Visual Studio 拡張の一パッケージが変更すべき値ではなさそうです。というわけでどうしようか悩んでいたらこんな記事を見つけました。

Redirecting Assembly Loads at Runtime – SLaks.Blog

AppDomain.CurrentDomain.AssemblyResolveイベントを登録することで、アセンブリの解決を実行時にリダイレクトしてやる方法です。このイベントに関する詳細はこちらを参照してください。

AppDomain.AssemblyResolve イベント (System)

というわけで、このコードを拝借してちょっと変えたものを、Visual Studio SDKのパッケージクラスのstaticコンストラクタから実行することにしました。

using System;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.Win32;

namespace MyVisualStudio.Vsix
{

    //この辺の属性は自動生成のままいじっていない
    [PackageRegistration(UseManagedResourcesOnly = true)]
    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About
    [Guid(MyVSPackage .PackageGuidString)]
    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]
    [ProvideMenuResource("Menus.ctmenu", 1)]
    [ProvideToolWindow(typeof(MyVisualStudio.Vsix.Views.MyProjectWindow))]
    publicsealedclass MyVSPackage : Package
    {
        //VS拡張に必要なコードは省略static MyVSPackage()
        {
            RedirectAssembly("System.Reactive.Core", new Version(3, 0, 3000, 0), "94bc3704cddfc263");
            RedirectAssembly("System.Reactive.Interfaces", new Version(3, 0, 1000, 0), "94bc3704cddfc263");
        }

        publicstaticvoid RedirectAssembly(string shortName, Version targetVersion, string publicKeyToken)
        {
            ResolveEventHandler handler = null;

            handler = (sender, args) => {
                var requestedAssembly = new AssemblyName(args.Name);
                if (requestedAssembly.Name != shortName)
                    returnnull;

                Debug.WriteLine($"Redirecting assembly load of {args.Name}, loaded by {args.RequestingAssembly?.FullName ?? "(unknown)"}");
                
                if (requestedAssembly.Version > targetVersion)
                {
                    Debug.WriteLine($"Request assemby's version {requestedAssembly.Version} is higher than the target version {targetVersion}. Stop to load the target assembly.");
                    returnnull;
                }
                requestedAssembly.Version = targetVersion;
                requestedAssembly.SetPublicKeyToken(new AssemblyName($"x, PublicKeyToken={publicKeyToken}").GetPublicKeyToken());
                requestedAssembly.CultureInfo = CultureInfo.InvariantCulture;

                AppDomain.CurrentDomain.AssemblyResolve -= handler;

                return Assembly.Load(requestedAssembly);
            };
            AppDomain.CurrentDomain.AssemblyResolve += handler;
        }
    }
}

一応、ターゲットとして読み込むバージョンより大きなバージョンがリクエストされた場合は読み込まないコードを追加しています。なお、一度ロードに失敗したアセンブリは結果がキャッシュされて実行中に再度読み込みが試行されることはないので、もし同じアセンブリを読み込もうとして失敗するVS拡張が別にインストールされていて、そちらが先にアセンブリの読み込みを実行する場合は、このコードは効果がないと思われます。

なお、bindingRedirectが発生してしまう問題はReactiveExtension側の問題で、次のバージョン(いつだ?)で解消される予定になっています。

github.com

kubernetes on Azure の1.7~1.9あたりの更新をまとめてみた

$
0
0

Release Notesにリンクされているものをみると、さらっと一文ですまされているところが実はいろいろ更新されていたのでまとめてみました。なお、すべて修正内容のコメントとソースを見ただけでまだ試してはないです。あと断定形で書いてますが、あやしいところがあればコメントもらえると助かります。

kubernetes 1.7

全体のリリースノートはこちら。

kubernetes/CHANGELOG-1.7.md at master · kubernetes/kubernetes · GitHub

Azure Managed Diskを永続化ディスクとして使用可能にする

いままではUnmanaged Diskしか使えなかったのをManaged Diskも利用可能になりました。コード的には大規模な変更になっています。 github.com

どうも説明を読んでいると、これ以前のバージョンではAzure Diskを利用するpodがnodeを移動するときに問題があったり、パフォーマンス的にいけてないとか書いてあったりします。これについては、AKS,OpenShift 3.7の両方でテスト済みです。AKSの記事はこちらをどうぞ。

tech.tanaka733.net

OpenShiftはアカウント登録が必要ですが、こちらにあります。

OpenShift Container Platform on Microsoft Azure with Azure Disk failed to create a pod with Persistent Volume - Red Hat Customer Portal

Azure Fileをglobal Azure(通常のpublic Azureクラウド)以外のAzure環境(Azure GermanyやChinaなど)でも利用可能にする

github.com

通常のglobal Azure region以外に、Azure GermanyなどもkubernetesやOpenShiftはサポートしています。azure configurationファイルにCLOUDというキーがあり、そこでAZUREGERMANCLOUDなどと指定することでAPIのエンドポイントの変更に対応できます。

kubernetes/azure.go at 1586823c9414a1f4db5553b964782326cfabde9b · clement-buchart/kubernetes · GitHub

kubernetes/azure.go at 1586823c9414a1f4db5553b964782326cfabde9b · clement-buchart/kubernetes · GitHub

のですが、Azure Fileだけエンドポイントがハードコードされていたのでその修正が入りました。

kubernetesが存在するresource group以外のVNetも許容する

github.com

いままではVNetはkubernetesが配置されているresource groupと同じresource groupに存在するのが前提でしたが、vnetResourceGroupというキーでAzure Configuration ファイルに指定すると、VNetが別のresource groupに存在してもいいようになりました。なお、VNetはAzure Load Balancerを作成するときに利用されるようです。

Azure Load Balancerのhealthprobeで名前とポートの両方をチェックするようにした

github.com

Azure Load Balancerリソースを使う際に、nodeportsの変更に追随するようにしました。

1.8

全体のリリースノートはこちら。

kubernetes/CHANGELOG-1.8.md at master · kubernetes/kubernetes · GitHub

Azure File/Diskをマウントする際のパーミッションを0755にする。

github.com

いままで0700だったのを0755に変更しました。

Standard_GRS, Standard_RAGRS をAzure Storageのオプションとしてサポート

github.com

Azure Diskを永続化ディスクとして利用する際のオプションとして、Standard_LRSとPremium_LRS に加えて Standard_GRSとStandard_RAGRSがサポートされるようになりました。指定する場所はstorageclassのstorageaccounttypeになります。

Azure Fileを永続化ディスクとして使う場合にマウントオプションをサポートする

github.com

Azure Fileを永続化ディスクとしてマウントする場合、LinuxのCIFSモジュールを使ってマウントするのですが、その際のマウントオプションをstorageclassの中で指定できるようになりました。これ使うとパスワードとか渡せるので、Linux側がSMB 3.0の暗号化プロトコルに対応していれば*1、Regionの異なるAzure Fileにもマウントできるのではと思います。

Azure DiskとFileをWindowsノードにもマウント可能にする

github.comgithub.com

Azure DiskとAzure FileをWindowsノードにもマウントできるよう、マウントパスにドライブレターが指定でき、Linux全体の制約がいくつか消えました。

インスタンスメタデータサービスのサポート

github.comgithub.com

インスタンスメタデータサービスからノードに関する情報を取得するようになりました。ノードのホスト名とプライベートIPとVMサイズなどの取得にまず使っているようです。useInstanceMetadataをAzure configurationファイルで有効にしておく必要があります。コードを見るかぎり、VM名とノード名が一致しないといけない制約はまだありそうです。

API実行時のリトライフローの改善

github.comgithub.com

仮想マシンの状態を取得するときなどにAPIを実行しますが、エラーが起きた際のリトライフローの改善が行われました。

Azure Fileの共有名を自動生成する際に妥当な名前を生成するようにした

github.com

Azure Fileの共有を自動生成する際に、Azure側の制約に沿った妥当な名前を生成するようにしました。

デバイス名の変更によるkubelet再起動時に発生する問題の対処

github.comgithub.com

デバイス名が変更されると、kubelet再起動時に起動しなくなる問題があったため、マウントパスのチェックと再マウント処理を追加しました。マウント先を/dev/sd*から/dev/disk/by-idに変え変更されないようにしています。

Azure FIleを利用したPVCの作成に失敗したときのエラーメッセージの改善

github.com

ストレージキーの不一致や、共有の作成失敗などの際もすべてfailed to find a matching storage accountと表示されていたのを変更しました。

ストレージアカウント初期化処理の改善

github.com

不要な初期化処理をなくし、on-demandで初期化するようにしました。

既存のノードが属するAvailability Setに存在しないノードを追加する際にクラッシュしないようにした

github.com

AKSでノードを手動追加する際に発生していたバグのようですが、原理としては、最初に構築したノードは1つのAvailabilitySetに属していて、そのAvailabilitySetに属さないノードを後から追加する際に、クラッシュしていたので、それを防止するコードを追加しています。

VolumeSource.ReadOnlyがnilの際にクラッシュしないようにした

github.com

nilの場合はデフォルト値としてfalseを設定するようにしました。

Azure Fileに接続する際に利用するsecretを別のnamespaceのものを参照できるようにした。

github.com

secretNamespaceを指定することで、別のnamespaceのsecretを利用できるようにしました。

kubectlの認証にAzure Active Directoryのプラグインが利用できるようにした

github.com

1.9

全体のリリースノートはこちら。

kubernetes/CHANGELOG-1.9.md at master · kubernetes/kubernetes · GitHub

[1.7から1.9へ変更]サービスプリンシパルをMSIから取得できるようにする

github.com

いままではAzure Configuration ファイルにAPIを実行するためのサービスプリンシパルのIDとかパスワードを指定していたのですが、それらをManaged Service Identity経由で受け取れるようになりました。

(2018/02/02 17:10 追記) 1.7で使える!と思って試したら動かなくて、じつはバグがあって1.9で修正されています。 github.com

ServiceをAzure DNS経由でpublic IPに解決するためのアノテーションを導入した

github.com

service.alpha.kubernetes.io/label-name: myserviceというアノテーションをkubernetesのサービスに設定すると、myservice.<azure-region>.cloudapp.azure.comというAzure DNSのレコード経由でpublic IPに解決してくれるようになります。

Azure FileをWindowsノードにマウントする際、上限を越えたらエラーを出すようにした

github.com

Windowsの場合、ネットワークドライブとしてマウントするので、ドライブレターの上限を超えたらマウントできなくなります。その際のエラメッセージを出すようになりました。

*1:RHELについては7.5 beta1で使用可能になっているので、このままいけば7.5で対応予定

Visual Studio SDK でも ReactivePropertyを使いたい (bindingRedirect編)

$
0
0

Visual Studio SDKを使ってVisual Studio拡張を使っているのですが、UI部分をWPFで作成していて、じゃあReactivePropertyを使おうと思ったらこんなエラーが出ました。

f:id:tanaka733:20180129011635p:plain

というわけでこれに対処したいと思います。

勘のいい方だとすぐに気付くと思うのですが、NuGetできちんと依存関係解決しているのに、依存関係が見つからないということなので、bindingRedirectの問題です。実際にプロジェクトで参照しているDLLのバージョンを確認するうと、確かにパッチレベルが違う値になっています。

f:id:tanaka733:20180129175350p:plain

プロジェクトに追加されたファイルをよく見ると、app.configに次のような値が追加されています。

<?xml version="1.0" encoding="utf-8"?><configuration><runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Reactive.Core"publicKeyToken="94bc3704cddfc263"culture="neutral" /><bindingRedirect oldVersion="0.0.0.0-3.0.3000.0"newVersion="3.0.3000.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="System.Reactive.Interfaces"publicKeyToken="94bc3704cddfc263"culture="neutral" /><bindingRedirect oldVersion="0.0.0.0-3.0.1000.0"newVersion="3.0.1000.0" /></dependentAssembly></assemblyBinding></runtime></configuration>

というわけで、app.configに追加されているbindingRedirectが実際にはうまく解決されていないという問題になります。なぜかというと、Visual Studio SDKの場合、プロセス自体はdevenv.exeなのでこのプロセス起動時に渡すapp.configにこのbindingRedirectの設定が記載されていないといけないのに、Visual Studio SDKのプロジェクトのapp.configに記載があっても解決してくれないせいです。かといって、devenvはユーザー(あるいはマシン)グローバルな設定なので、Visual Studio 拡張の一パッケージが変更すべき値ではなさそうです。というわけでどうしようか悩んでいたらこんな記事を見つけました。

Redirecting Assembly Loads at Runtime – SLaks.Blog

AppDomain.CurrentDomain.AssemblyResolveイベントを登録することで、アセンブリの解決を実行時にリダイレクトしてやる方法です。このイベントに関する詳細はこちらを参照してください。

AppDomain.AssemblyResolve イベント (System)

というわけで、このコードを拝借してちょっと変えたものを、Visual Studio SDKのパッケージクラスのstaticコンストラクタから実行することにしました。

using System;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.Win32;

namespace MyVisualStudio.Vsix
{

    //この辺の属性は自動生成のままいじっていない
    [PackageRegistration(UseManagedResourcesOnly = true)]
    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About
    [Guid(MyVSPackage .PackageGuidString)]
    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]
    [ProvideMenuResource("Menus.ctmenu", 1)]
    [ProvideToolWindow(typeof(MyVisualStudio.Vsix.Views.MyProjectWindow))]
    publicsealedclass MyVSPackage : Package
    {
        //VS拡張に必要なコードは省略static MyVSPackage()
        {
            RedirectAssembly("System.Reactive.Core", new Version(3, 0, 3000, 0), "94bc3704cddfc263");
            RedirectAssembly("System.Reactive.Interfaces", new Version(3, 0, 1000, 0), "94bc3704cddfc263");
        }

        publicstaticvoid RedirectAssembly(string shortName, Version targetVersion, string publicKeyToken)
        {
            ResolveEventHandler handler = null;

            handler = (sender, args) => {
                var requestedAssembly = new AssemblyName(args.Name);
                if (requestedAssembly.Name != shortName)
                    returnnull;

                Debug.WriteLine($"Redirecting assembly load of {args.Name}, loaded by {args.RequestingAssembly?.FullName ?? "(unknown)"}");
                
                if (requestedAssembly.Version > targetVersion)
                {
                    Debug.WriteLine($"Request assemby's version {requestedAssembly.Version} is higher than the target version {targetVersion}. Stop to load the target assembly.");
                    returnnull;
                }
                requestedAssembly.Version = targetVersion;
                requestedAssembly.SetPublicKeyToken(new AssemblyName($"x, PublicKeyToken={publicKeyToken}").GetPublicKeyToken());
                requestedAssembly.CultureInfo = CultureInfo.InvariantCulture;

                AppDomain.CurrentDomain.AssemblyResolve -= handler;

                return Assembly.Load(requestedAssembly);
            };
            AppDomain.CurrentDomain.AssemblyResolve += handler;
        }
    }
}

一応、ターゲットとして読み込むバージョンより大きなバージョンがリクエストされた場合は読み込まないコードを追加しています。なお、一度ロードに失敗したアセンブリは結果がキャッシュされて実行中に再度読み込みが試行されることはないので、もし同じアセンブリを読み込もうとして失敗するVS拡張が別にインストールされていて、そちらが先にアセンブリの読み込みを実行する場合は、このコードは効果がないと思われます。

なお、bindingRedirectが発生してしまう問題はReactiveExtension側の問題で、次のバージョン(いつだ?)で解消される予定になっています。

github.com

kubernetes on Azure の1.7~1.9あたりの更新をまとめてみた

$
0
0

Release Notesにリンクされているものをみると、さらっと一文ですまされているところが実はいろいろ更新されていたのでまとめてみました。なお、すべて修正内容のコメントとソースを見ただけでまだ試してはないです。あと断定形で書いてますが、あやしいところがあればコメントもらえると助かります。

kubernetes 1.7

全体のリリースノートはこちら。

kubernetes/CHANGELOG-1.7.md at master · kubernetes/kubernetes · GitHub

Azure Managed Diskを永続化ディスクとして使用可能にする

いままではUnmanaged Diskしか使えなかったのをManaged Diskも利用可能になりました。コード的には大規模な変更になっています。 github.com

どうも説明を読んでいると、これ以前のバージョンではAzure Diskを利用するpodがnodeを移動するときに問題があったり、パフォーマンス的にいけてないとか書いてあったりします。これについては、AKS,OpenShift 3.7の両方でテスト済みです。AKSの記事はこちらをどうぞ。

tech.tanaka733.net

OpenShiftはアカウント登録が必要ですが、こちらにあります。

OpenShift Container Platform on Microsoft Azure with Azure Disk failed to create a pod with Persistent Volume - Red Hat Customer Portal

Azure Fileをglobal Azure(通常のpublic Azureクラウド)以外のAzure環境(Azure GermanyやChinaなど)でも利用可能にする

github.com

通常のglobal Azure region以外に、Azure GermanyなどもkubernetesやOpenShiftはサポートしています。azure configurationファイルにCLOUDというキーがあり、そこでAZUREGERMANCLOUDなどと指定することでAPIのエンドポイントの変更に対応できます。

kubernetes/azure.go at 1586823c9414a1f4db5553b964782326cfabde9b · clement-buchart/kubernetes · GitHub

kubernetes/azure.go at 1586823c9414a1f4db5553b964782326cfabde9b · clement-buchart/kubernetes · GitHub

のですが、Azure Fileだけエンドポイントがハードコードされていたのでその修正が入りました。

kubernetesが存在するresource group以外のVNetも許容する

github.com

いままではVNetはkubernetesが配置されているresource groupと同じresource groupに存在するのが前提でしたが、vnetResourceGroupというキーでAzure Configuration ファイルに指定すると、VNetが別のresource groupに存在してもいいようになりました。なお、VNetはAzure Load Balancerを作成するときに利用されるようです。

Azure Load Balancerのhealthprobeで名前とポートの両方をチェックするようにした

github.com

Azure Load Balancerリソースを使う際に、nodeportsの変更に追随するようにしました。

1.8

全体のリリースノートはこちら。

kubernetes/CHANGELOG-1.8.md at master · kubernetes/kubernetes · GitHub

Azure File/Diskをマウントする際のパーミッションを0755にする。

github.com

いままで0700だったのを0755に変更しました。

Standard_GRS, Standard_RAGRS をAzure Storageのオプションとしてサポート

github.com

Azure Diskを永続化ディスクとして利用する際のオプションとして、Standard_LRSとPremium_LRS に加えて Standard_GRSとStandard_RAGRSがサポートされるようになりました。指定する場所はstorageclassのstorageaccounttypeになります。

Azure Fileを永続化ディスクとして使う場合にマウントオプションをサポートする

github.com

Azure Fileを永続化ディスクとしてマウントする場合、LinuxのCIFSモジュールを使ってマウントするのですが、その際のマウントオプションをstorageclassの中で指定できるようになりました。これ使うとパスワードとか渡せるので、Linux側がSMB 3.0の暗号化プロトコルに対応していれば*1、Regionの異なるAzure Fileにもマウントできるのではと思います。

Azure DiskとFileをWindowsノードにもマウント可能にする

github.comgithub.com

Azure DiskとAzure FileをWindowsノードにもマウントできるよう、マウントパスにドライブレターが指定でき、Linux全体の制約がいくつか消えました。

インスタンスメタデータサービスのサポート

github.comgithub.com

インスタンスメタデータサービスからノードに関する情報を取得するようになりました。ノードのホスト名とプライベートIPとVMサイズなどの取得にまず使っているようです。useInstanceMetadataをAzure configurationファイルで有効にしておく必要があります。コードを見るかぎり、VM名とノード名が一致しないといけない制約はまだありそうです。

API実行時のリトライフローの改善

github.comgithub.com

仮想マシンの状態を取得するときなどにAPIを実行しますが、エラーが起きた際のリトライフローの改善が行われました。

Azure Fileの共有名を自動生成する際に妥当な名前を生成するようにした

github.com

Azure Fileの共有を自動生成する際に、Azure側の制約に沿った妥当な名前を生成するようにしました。

デバイス名の変更によるkubelet再起動時に発生する問題の対処

github.comgithub.com

デバイス名が変更されると、kubelet再起動時に起動しなくなる問題があったため、マウントパスのチェックと再マウント処理を追加しました。マウント先を/dev/sd*から/dev/disk/by-idに変え変更されないようにしています。

Azure FIleを利用したPVCの作成に失敗したときのエラーメッセージの改善

github.com

ストレージキーの不一致や、共有の作成失敗などの際もすべてfailed to find a matching storage accountと表示されていたのを変更しました。

ストレージアカウント初期化処理の改善

github.com

不要な初期化処理をなくし、on-demandで初期化するようにしました。

既存のノードが属するAvailability Setに存在しないノードを追加する際にクラッシュしないようにした

github.com

AKSでノードを手動追加する際に発生していたバグのようですが、原理としては、最初に構築したノードは1つのAvailabilitySetに属していて、そのAvailabilitySetに属さないノードを後から追加する際に、クラッシュしていたので、それを防止するコードを追加しています。

VolumeSource.ReadOnlyがnilの際にクラッシュしないようにした

github.com

nilの場合はデフォルト値としてfalseを設定するようにしました。

Azure Fileに接続する際に利用するsecretを別のnamespaceのものを参照できるようにした。

github.com

secretNamespaceを指定することで、別のnamespaceのsecretを利用できるようにしました。

kubectlの認証にAzure Active Directoryのプラグインが利用できるようにした

github.com

1.9

全体のリリースノートはこちら。

kubernetes/CHANGELOG-1.9.md at master · kubernetes/kubernetes · GitHub

[1.7から1.9へ変更]サービスプリンシパルをMSIから取得できるようにする

github.com

いままではAzure Configuration ファイルにAPIを実行するためのサービスプリンシパルのIDとかパスワードを指定していたのですが、それらをManaged Service Identity経由で受け取れるようになりました。

(2018/02/02 17:10 追記) 1.7で使える!と思って試したら動かなくて、じつはバグがあって1.9で修正されています。 github.com

ServiceをAzure DNS経由でpublic IPに解決するためのアノテーションを導入した

github.com

service.alpha.kubernetes.io/label-name: myserviceというアノテーションをkubernetesのサービスに設定すると、myservice.<azure-region>.cloudapp.azure.comというAzure DNSのレコード経由でpublic IPに解決してくれるようになります。

Azure FileをWindowsノードにマウントする際、上限を越えたらエラーを出すようにした

github.com

Windowsの場合、ネットワークドライブとしてマウントするので、ドライブレターの上限を超えたらマウントできなくなります。その際のエラメッセージを出すようになりました。

*1:RHELについては7.5 beta1で使用可能になっているので、このままいけば7.5で対応予定

kubernetes on Azure の1.7~1.9あたりの更新をまとめてみた

$
0
0

Release Notesにリンクされているものをみると、さらっと一文ですまされているところが実はいろいろ更新されていたのでまとめてみました。なお、すべて修正内容のコメントとソースを見ただけでまだ試してはないです。あと断定形で書いてますが、あやしいところがあればコメントもらえると助かります。

kubernetes 1.7

全体のリリースノートはこちら。

kubernetes/CHANGELOG-1.7.md at master · kubernetes/kubernetes · GitHub

Azure Managed Diskを永続化ディスクとして使用可能にする

いままではUnmanaged Diskしか使えなかったのをManaged Diskも利用可能になりました。コード的には大規模な変更になっています。 github.com

どうも説明を読んでいると、これ以前のバージョンではAzure Diskを利用するpodがnodeを移動するときに問題があったり、パフォーマンス的にいけてないとか書いてあったりします。これについては、AKS,OpenShift 3.7の両方でテスト済みです。AKSの記事はこちらをどうぞ。

tech.tanaka733.net

OpenShiftはアカウント登録が必要ですが、こちらにあります。

OpenShift Container Platform on Microsoft Azure with Azure Disk failed to create a pod with Persistent Volume - Red Hat Customer Portal

Azure Fileをglobal Azure(通常のpublic Azureクラウド)以外のAzure環境(Azure GermanyやChinaなど)でも利用可能にする

github.com

通常のglobal Azure region以外に、Azure GermanyなどもkubernetesやOpenShiftはサポートしています。azure configurationファイルにCLOUDというキーがあり、そこでAZUREGERMANCLOUDなどと指定することでAPIのエンドポイントの変更に対応できます。

kubernetes/azure.go at 1586823c9414a1f4db5553b964782326cfabde9b · clement-buchart/kubernetes · GitHub

kubernetes/azure.go at 1586823c9414a1f4db5553b964782326cfabde9b · clement-buchart/kubernetes · GitHub

のですが、Azure Fileだけエンドポイントがハードコードされていたのでその修正が入りました。

kubernetesが存在するresource group以外のVNetも許容する

github.com

いままではVNetはkubernetesが配置されているresource groupと同じresource groupに存在するのが前提でしたが、vnetResourceGroupというキーでAzure Configuration ファイルに指定すると、VNetが別のresource groupに存在してもいいようになりました。なお、VNetはAzure Load Balancerを作成するときに利用されるようです。

Azure Load Balancerのhealthprobeで名前とポートの両方をチェックするようにした

github.com

Azure Load Balancerリソースを使う際に、nodeportsの変更に追随するようにしました。

1.8

全体のリリースノートはこちら。

kubernetes/CHANGELOG-1.8.md at master · kubernetes/kubernetes · GitHub

Azure File/Diskをマウントする際のパーミッションを0755にする。

github.com

いままで0700だったのを0755に変更しました。

Standard_GRS, Standard_RAGRS をAzure Storageのオプションとしてサポート

github.com

Azure Diskを永続化ディスクとして利用する際のオプションとして、Standard_LRSとPremium_LRS に加えて Standard_GRSとStandard_RAGRSがサポートされるようになりました。指定する場所はstorageclassのstorageaccounttypeになります。

Azure Fileを永続化ディスクとして使う場合にマウントオプションをサポートする

github.com

Azure Fileを永続化ディスクとしてマウントする場合、LinuxのCIFSモジュールを使ってマウントするのですが、その際のマウントオプションをstorageclassの中で指定できるようになりました。これ使うとパスワードとか渡せるので、Linux側がSMB 3.0の暗号化プロトコルに対応していれば*1、Regionの異なるAzure Fileにもマウントできるのではと思います。

Azure DiskとFileをWindowsノードにもマウント可能にする

github.comgithub.com

Azure DiskとAzure FileをWindowsノードにもマウントできるよう、マウントパスにドライブレターが指定でき、Linux全体の制約がいくつか消えました。

インスタンスメタデータサービスのサポート

github.comgithub.com

インスタンスメタデータサービスからノードに関する情報を取得するようになりました。ノードのホスト名とプライベートIPとVMサイズなどの取得にまず使っているようです。useInstanceMetadataをAzure configurationファイルで有効にしておく必要があります。コードを見るかぎり、VM名とノード名が一致しないといけない制約はまだありそうです。

API実行時のリトライフローの改善

github.comgithub.com

仮想マシンの状態を取得するときなどにAPIを実行しますが、エラーが起きた際のリトライフローの改善が行われました。

Azure Fileの共有名を自動生成する際に妥当な名前を生成するようにした

github.com

Azure Fileの共有を自動生成する際に、Azure側の制約に沿った妥当な名前を生成するようにしました。

デバイス名の変更によるkubelet再起動時に発生する問題の対処

github.comgithub.com

デバイス名が変更されると、kubelet再起動時に起動しなくなる問題があったため、マウントパスのチェックと再マウント処理を追加しました。マウント先を/dev/sd*から/dev/disk/by-idに変え変更されないようにしています。

Azure FIleを利用したPVCの作成に失敗したときのエラーメッセージの改善

github.com

ストレージキーの不一致や、共有の作成失敗などの際もすべてfailed to find a matching storage accountと表示されていたのを変更しました。

ストレージアカウント初期化処理の改善

github.com

不要な初期化処理をなくし、on-demandで初期化するようにしました。

既存のノードが属するAvailability Setに存在しないノードを追加する際にクラッシュしないようにした

github.com

AKSでノードを手動追加する際に発生していたバグのようですが、原理としては、最初に構築したノードは1つのAvailabilitySetに属していて、そのAvailabilitySetに属さないノードを後から追加する際に、クラッシュしていたので、それを防止するコードを追加しています。

VolumeSource.ReadOnlyがnilの際にクラッシュしないようにした

github.com

nilの場合はデフォルト値としてfalseを設定するようにしました。

Azure Fileに接続する際に利用するsecretを別のnamespaceのものを参照できるようにした。

github.com

secretNamespaceを指定することで、別のnamespaceのsecretを利用できるようにしました。

kubectlの認証にAzure Active Directoryのプラグインが利用できるようにした

github.com

1.9

全体のリリースノートはこちら。

kubernetes/CHANGELOG-1.9.md at master · kubernetes/kubernetes · GitHub

[1.7から1.9へ変更]サービスプリンシパルをMSIから取得できるようにする

github.com

いままではAzure Configuration ファイルにAPIを実行するためのサービスプリンシパルのIDとかパスワードを指定していたのですが、それらをManaged Service Identity経由で受け取れるようになりました。

(2018/02/02 17:10 追記) 1.7で使える!と思って試したら動かなくて、じつはバグがあって1.9で修正されています。 github.com

ServiceをAzure DNS経由でpublic IPに解決するためのアノテーションを導入した

github.com

service.alpha.kubernetes.io/label-name: myserviceというアノテーションをkubernetesのサービスに設定すると、myservice.<azure-region>.cloudapp.azure.comというAzure DNSのレコード経由でpublic IPに解決してくれるようになります。

Azure FileをWindowsノードにマウントする際、上限を越えたらエラーを出すようにした

github.com

Windowsの場合、ネットワークドライブとしてマウントするので、ドライブレターの上限を超えたらマウントできなくなります。その際のエラメッセージを出すようになりました。

*1:RHELについては7.5 beta1で使用可能になっているので、このままいけば7.5で対応予定

Viewing all 283 articles
Browse latest View live