Developing & Deploying
.NET Core on Linux
#csugjp
Visual Studio 2017 リリース記念勉強会
レッドハット株式会社/Microsoft MVP for VSDT
田中孝佳 (@tanaka_733)
自己紹介
Red Hat K.K.
◦ .NET Core on RHEL, Red Hat on Azure, OpenShift
Microsoft MVP for VSDT (*)
◦ Build Insiderなどで執筆「C# 7.0新機能」など
◦ C#, .NET Core, Azure, Visual Studio SDKなどが最近の興味
◦ ブログ「銀の光と碧い空」「Silver Light and Blue Sky」
◦ 会社ブログ「Red Hat Developers」などでも書いてます
Contact
◦ @tanaka_733
本日の概要
Visual Studio 2017リリースでのLinux周りの新機能
新しい.NET CLIの使い方
LinuxやDocker環境を見据えた機能を知る
LinuxやDocker環境でのCI/CDで使える機能を知る
LinuxやDocker環境への配置方法を知る
コードはこちら
◦ https://github.com/tanaka-takayoshi/VS2017MemorialSession
.NET Core
4
.NET Core Inside
5
.NET Core App (C#/VB)
IL Assembly (exe, dll)
Roslyn
CoreFX
(.NET Core
Class Library)
ManagedUnmanaged
OS
Native ABI etc
(F#)
compiler
CoreCLR
(.NET Core Runtime)
.NET
Core
CLI
.NETCoreSDK
Linux関連新機能まとめ
.NET Core Tools 1.0 Release (ToolsはいままでPreviewだった)
◦ csprojサポート
◦ dotnet new の刷新
.NET Core 1.1.1, 1.0.4 Release
Visual Studio 2017の機能追加
◦ docker compose ファイルによるdockerイメージ作成とデバッグ
◦ App Service on Linuxへの配置
◦ ACS上のdockerへのリモートデバッグ
◦ Linuxホストへのリモートデバッグ
Linux関連新機能まとめ
.NET Core Tools 1.0 Release (ToolsはいままでPreviewだった)
◦ csprojサポート
◦ dotnet new の刷新
.NET Core 1.1.1, 1.0.4 Release
Visual Studio 2017の機能追加
◦ dockerイメージ作成とデバッグ
◦ App Service on Linuxへの配置
◦ ACS上のdockerへのリモートデバッグ
◦ Linuxホストへのリモートデバッグ
太字:今日のセッションで出てくるところ
.NET Core CLI 新機能
SDKとCLIの分離
MSBuildを利用した新しいプロジェクトシステムとビルド
NuGet関連コマンドの追加
新しいテンプレートシステム (donet new)
移行コマンド (dotnet migrate)
CLIの拡張
CLI First (RC2まで)
SDK First (RC3以降)
https://docs.microsoft.com/en-us/dotnet/articles/core/tools/cli-msbuild-architecture
csproj + MSBuild on Linux
project.json is dead
$ dotnet publish -o pub -C Release
は以下のコマンドと同じ
$ dotnet msbuild /t:Publish /p:OutputPath=pub /p:Configuration
dotnet NuGet
NuGetによるライブラリの追加は
◦ dotnet add package <package_name> [-v version]
◦ csprojを編集
dotnet CLIに用意されているのは主にNuGetパッケージ作成者向けコマンド
◦ dotnet pack プロジェクトからNuGetパッケージ作成
◦ dotnet nuget delete サーバーからNuGetパッケージ削除
◦ dotnet nuget publish サーバーにNuGetパッケージ発行
◦ dotnet nuget locals ローカルのNuGetキャッシュを一覧、削除
<PackageReference Include="Newtonsoft.Json">
<Version>9.0.1</Version>
</PackageReference>
Brand-new “dotnet new”
dotnet new コマンドが強化されて、さまざまなテンプレートに対応
将来的にはより自由にプロジェクトテンプレートを追加できるようにする計画も
参考:http://rehansaeed.com/custom-project-templates-using-dotnet-new/
dotnet migrate
project.json形式のプロジェクトをcsprojに移行
特に確認することなくいきなり変換する。以前のものはbackupフォルダに。
.NET Core CLIの拡張
dotnet XXX という自作のコマンドラインツールを開発できるようになった
◦ nuget とかmsbuildとかもそういう作り
配布はNuGet経由
MSBuildのタスクを拡張として作成することも可能
参考: https://docs.microsoft.com/en-us/dotnet/articles/core/tools/extensibility
Preview版での例ですが
◦ https://github.com/tanaka-takayoshi/MVPSummitHackathon2016/tree/hackathon-dotnet-add
LinuxやDocker環境を見据えた機能
環境ごとのEnvironmentの切り替え
Configurationを環境変数や外部ファイルから引き渡す
Sessionの扱い
環境ごとのConfigureの切り替え
本番と開発では利用する外部サービスの接続情報が違う
本番と開発のDB接続先を切り替えたい
本番はキャッシュ用のRedisありで、開発はなしで
ローカルではSQLite使って単独で動かしたい etc…
Environment による切り替え
DIしたIHostingEnvironment を見て切り替える
しかし、ConfigureService にはIHostingEnvironmentをDIできない
Configureメソッドごと切替
ConfigureXXXServices, ConfigureXXX という命名規則でEnvironmentごとに切り替えられる
Configureクラスごと切替
Environment間で差異が大きすぎる場合などはStartupXXXとクラス名ごと切り替えられる
この場合、WebHostBuilder.UseStartup でStartupXXXを含むアセンブリ名を指定
DEMO: Environment 切り替え
Visual Studio Codeでのデバッグ時の切り替え方
publishしたバイナリファイル実行時の切り替え方
◦ 起動スクリプトで環境変数指定
◦ コンテナ起動時に指定 (dockerコマンドのオプションに相当する各サービスの設定方法で)
設定の読み込みと外部ディスク
特定のクラスが利用する設定データを外部ファイルに管理したい
ソースコードリポジトリに格納したくない秘密データをConfigurationに渡したい
◦ 環境変数経由
◦ 外部ファイル経由
Kubernetes/OpenShiftには秘密データを管理して、
コンテナに環境変数もしくは外部ファイルとして渡すことができる
Configuration はASP.NET Coreだけでなく.NET Coreでも使えます
ControllerへのConfigurationのDI
ConfigurationそのものをDIすることはできず、必要なものをクラスに切り出す
環境変数からの読み込み
ASPNETCORE_で始まる環境変数
WebHostBuilderの設定に使われます
ASPNETCORE_ENVIRONMENT
◦ ENVIRONMENTの指定
ASPNETCORE_URLS
◦ リスニングポート(URL)の指定
◦ ASP.NET Core 2.0 から指定なしでの起動ができなくなる予定
◦ 環境変数経由かソースコード内での指定
外部ファイルからの読み込み
複数コンテナ環境でのセッション
複数Webサーバー構成で、セッションは共有したい
共有するセッションはRedisに格納したい
Webサーバーのライフサイクルとセッションのライフサイクルを独立させたい
= Webサーバーが1台死んだ後、次に別のWebサーバーにアクセスしても
セッションを維持したままにしたい
参考: http://tech.tanaka733.net/entry/session-sharing-in-aspnetcore
IDistributedCache と IDataProtection
IDistributedCache
◦ 名前の通り分散キャッシュを提供
◦ セッションの格納先に指定できる
◦ ASP.NET CoreチームからはRedisとSQLServer版を提供
◦ この設定だけではセッションは分散して格納されるが複数マシンから共有できない
IDataProtection
◦ 暗号化するときのキー管理を提供
◦ セッションを格納する際にこのキーを使って暗号化する
◦ デフォルト実装はマシンごとに一意なキーを発行してローカルファイルとして保存
◦ ASP.NET CoreチームからはNFSおよび、Redis、AzureStorage (Preview)を提供
machine A
machine B
machine C
ASP.NET Core
ASP.NET Core
ASP.NET Core
Session Data
A’
マシンごとに鍵が異なるので、
同じセッションデータを参照しても
復号できない=>セッションロスト
~/.aspnet
IDataProtectionのデフォルト実装
machine A
machine B
machine C
ASP.NET Core
ASP.NET Core
ASP.NET Core
Session Data
鍵自体をredisにおいて
複数マシンが同じ鍵を使うので
セッションデータを復号できる
DataProtection.Redisを使った場合
DEMO: セッション共有
https://goo.gl/fQhpWl
コンテナのビルドとデプロイ
dockerイメージ作成
private NuGetサーバーの活用
App Service on Linuxへの配置
Container プラットフォームへの配置例:OpenShift
dockerのビルド・デプロイイメージ
ビルドプロセス
DBの
イメージなども
直接登録
SCM
コンテナ
レジストリ
デプロイプロセス
コンテナ
稼働環境
※アイコンのサービスは一例
OpenShiftだと
builder pod
DBの
イメージなども
直接登録
SCM(git) internal registry
deplore pod
pod
deploymentConfigbuildConfig
DEMO: App Service on Linuxへの配置
ビルドはローカルで => スクリプトを書いてCIサービスで回せる
◦ dotnet publish したバイナリをDockerfileで渡してイメージ作成
コンテナレジストリーはAzure Container Registryを使用
◦ すぐに作れるプライベートリポジトリ
◦ publicでよければDockerhubへ。privateにする場合は有料
デプロイはポータルから
◦ Azure Container Registryを指定してdocker配置
◦ ソースコード指定して、App Serviceがビルドして配置することもできる
◦ どちらかというと、App Serviceはそれを目指している=ビルドプロセスを内包したい、のかもしれない
(例)Dockerfile
Runtimeのみのイメージ
作業フォルダ作成
ビルドバイナリのコピー
作業フォルダ指定
リスニングポートの指定と開放
起動コマンド指定
ASP.NET Core 2.0 からは明示的なポートの指定が必要
https://github.com/aspnet/Announcements/issues/224
DEMO: OpenShiftへの配置
GitHubのリポジトリを指定するだけでビルド・デプロイ設定してくれる(s2i-dotnet)
GitHubにコミットしたら開発環境のコンテナを自動で更新する(GitHub commit hook)
EF Coreのmigrationなどを起動時に実行したい (s2i script)
OpenShiftに配置したDB、Redisサーバーの情報を渡したい
private NuGetサーバーの活用
キャッシュとして利用したい
オフライン環境でビルドしたい or LAN内のみでビルドしたい
公開せずに認証つきのみでアクセスさせたい
Sonatype Nexus OSS: セルフホスト可能、キャッシュとしても利用可能
NuGet.Server: 最近更新がない…
ファイルを直に配置: 動くが管理が面倒
VSTS: クラウドサービスのみ
JFrog Artifactory: Nexusと同様だが商用のみ
Linuxとdotnetプロセス
SELinux
systemdによるサービス化
SELinuxとは
https://www.centos.org/docs/5/html/Deployment_Guide-en-US/ch-selinux.html
SELinuxと.NET Core
.NET Core on RHELでdotnetプロセスはSELinuxからどう扱われる?
docker上でdotnetプロセスを動かす場合SELinuxはどう設定する?
dotnetプロセスはunconfined
unconfined というのは実質制約をうけないラベル
https://access.redhat.com/documentation/en-
US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-
Security-Enhanced_Linux-Targeted_Policy-Unconfined_Processes.html
docker上でのSELinux
SELinuxを有効にしたホスト上のContainerで走るプロセスに
svirt_lxc_net_t ラベルが付与される
c655,c931というMCSが付与されている
◦ マルチテナント環境で自分のコンテナが他人のコンテナからアクセスされるのを防ぐ
OpenShiftではデフォルトでroot権限が必要なコンテナが起動できないなど、
セキュリティ面も考慮している
systemd によるサービス化
.NET CoreをLinuxでサービスとして動かしたい
参考: http://tech.tanaka733.net/entry/aspnet-core-with-systemd-script-simple
serviceファイル例(.NET Core)
serviceファイル例(ASP.NET Core)
デバッグ
なぜ、WindowsからLinuxへ、LinuxからWindowsにリモートデバッグできるのか
Visual Studio Codeを使ったローカルデバッグ
Visual Studio Codeからリモートのdockerで動くプロセスにリモートデバッグ
Visual Studio からリモートのdockerで動くプロセスにリモートデバッグ
Performance Tracing
49
windbg
sos
procmon
perfview
LLDB/GDB
libsosplugin.so
strace
perfcollect
Debugging Application
50
GDB/LLDB
MICore
MIDE/Engine.Impl
MIDE/AD7.Impl
VSCode Debugger
AD7 Interface
MIDE: MIDebugEngine
MIText
VS Debugger
VS Debugger
Engine clrdbg
from MIEngine
WINDBG
まとめ
Visual Studio 2017リリースでのLinux周りの新機能
新しい.NET CLIの使い方
LinuxやDocker環境を見据えた機能を知る
LinuxやDocker環境でのCI/CDで使える機能を知る
LinuxやDocker環境への配置方法を知る

20170311 Developing & Deploying .NET Core on Linux

Editor's Notes

  • #6 ABI: Application Binary Interface
  • #7 System.Runtime.Private.dllとかの話 A set of assemblies that represent the compile time surface area of the class library implemented by the runtime itself. ref https://github.com/dotnet/coreclr#relationship-with-the-corefx-repository
  • #13 <ProjectName>.csprojに移行。.NET Frameworkのものよりも単純化 ビルドツールもMSBuildに移行。MSBuildのxplat化 dotnet buildはMSBuildのフロントエンドに
  • #50  ref) https://github.com/dotnet/coreclr/blob/f6b0056c819b07ae053d3112299ade0990144d00/src/ToolBox/SOS/SOSAndICorDebug.md
  • #51 https://github.com/Microsoft/MIEngine