Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ASP.NET Core のお気に入りの機能たち (docker向け)

1,140 views

Published on

Fukuoka .NET Conf 2017での登壇資料

Published in: Technology
  • Be the first to comment

  • Be the first to like this

ASP.NET Core のお気に入りの機能たち (docker向け)

  1. 1. (主にdocker向けの) ASP.NET Coreの お気に入りの機能たち @tanaka_733 2017年10月23日 Fukuoka.NET Conf 2017
  2. 2. 自己紹介 Red Hat K.K. 勤務 ◦ Software Maintenance Engineer ◦ 担当はOpenShiftと(いつの間にか)Microsoftとの協業分野全般 ◦ .NET Core on RHEL, Red Hat solutions on Azure, SQL Server on RHEL ◦ 会社Blog: Red Hat Developers Personal ◦福岡県北九州市出身 ◦ Microsoft MVP for VSDT ◦ Blog: 銀の光と碧い空 ◦ Build Insiderで.NET Core連載中 VSDT: Visual Studio & Development Technologies
  3. 3. 今日のセッションのゴール Dockerをはじめとしたコンテナ環境で ASP.NET Coreを便利に使いたい そんな時に役立つ機能のご紹介 ※kubernetes (OpenShift)の機能とあわせて紹介していますが、 他のオーケストレーションツール/サービスでも 同じような機能があるはずです kubectl: kubernetsコマンド, oc: OpenShiftクライアントコマンド
  4. 4. Agenda ◦ Visual StudioでのDocker support ◦ 外部ファイルを使った設定の注入 ◦ 複数コンテナでのセッション管理 ◦ リモートデバッグ ◦ EF Core: コードファースト DB migration
  5. 5. Docker Support ◦ ASP.NET Core プロジェクトのテンプレート選択画面
  6. 6. Docker Support ◦ ASP.NET Core プロジェクトのテンプレート選択画面 テンプレートによっては 利用できない Windows/Linux コンテナ選択可 ソリューションフォルダを作らないと うまく動作しない (バージョンがあった)
  7. 7. 何が起きるのか? ◦ Dockerfileの追加 ◦ 単純なASP.NET Coreアプリのコンテナ だったのが15.5 Previewではちょっと手の込んだ方法に… ◦ docker-composeプロジェクトの追加 ◦ docker composerファイルの追加 ◦ ローカルのdockerへの配置とデバッグの支援 ◦ 機能自体はVisual Studio SDK側で実装されている ◦ Linux/Windowsコンテナの選択は docker-composeプロジェクトで設定してある
  8. 8. 新しいDockerfile FROM microsoft/aspnetcore:2.0 AS base WORKDIR /app EXPOSE 80 FROM microsoft/aspnetcore-build:2.0 AS build WORKDIR /src COPY *.sln ./ COPY WebApplication1/WebApplication1.csproj WebApplication1/ RUN dotnet restore COPY . . WORKDIR /src/WebApplication1 RUN dotnet build -c Release -o /app FROM build AS publish RUN dotnet publish -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "WebApplication1.dll"]
  9. 9. Docker imageの生成フロー microsoft/ aspnetcore:2.0 base port80 microsoft/ aspnetcore-build:2.0 build final port80entrypoint solutionをコピー build publish publish バイナリをコピー
  10. 10. 何がうれしい? ◦最終的なコンテナサイズが小さくなった ◦ 今までは.NET Core SDK (Runtime+ビルドに必要なもの) をベースにしていたので、最初からサイズがでかい ◦ Runtimeのみのコンテナではビルドできない ◦ ビルド用のコンテナを別にして、そちらはSDKこみで。 最終的な成果物のコンテナはRuntimeのみにした ◦ (おまけ)OpenShiftもTemplateとして提供しています セッション後のハイパー宣伝タイムで!
  11. 11. Dockerデバッグの仕組み
  12. 12. Docker for Windows Hyper-V Docker用仮想マシン コンテナ実行用軽量LinuxVM Docker Engine Docker クライアント Linux コンテナ プロセス
  13. 13. デバッグ用コンテナ起動 Hyper-V コンテナ実行用軽量LinuxVM ホストOS(Windows)と ファイル共有 vsdbgバイナリなど (Cドライブ) プロジェクトファイル (保存場所のドライブ)tail -f /dev/null で起動しっぱなし その他NuGetパッケージなども ファイル共有
  14. 14. ビルド Hyper-V コンテナ実行用軽量LinuxVM Windows側で プロジェクトをビルド tail -f /dev/null で起動しっぱなし app.dll
  15. 15. デバッグ開始 Hyper-V コンテナ実行用軽量LinuxVM dotnet app.dll tail -f /dev/null で起動しっぱなし app.dll ./vsdbg vsdbg コンテナ内でdotnetプロセスを開始 デバッガープロセス開始 SSHこしにリモートデバッグ接続
  16. 16. (Note) dockerの状態 PS C:Tools> docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e1e8b52cf67e aspnetcoreexample1:dev "tail -f /dev/null" About a minute ago Up About a minute 0.0.0.0:32768->80/tcp dockercompose9290894832686996463_aspnetcoreexample1_1 PS C:Tools> docker exec -i -t e1e8b52cf67e /bin/bash //なぜかpsコマンドが使えないので、/proc/<PID>を直接見る # cat /proc/1/cmdline tail -f /dev/null # cat /proc/5/cmdline /remote_debugger/vsdbg --interpreter=vscode # cat /proc/13/cmdline /usr/bin/dotnet --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages bin/Debug/netcoreapp2.0/AspNetCoreExample1.dll # cat /proc/820/cmdline /bin/bash
  17. 17. .NET Core Debugger概要 19 GDB/LLDB MICore MIDE/Engine.Impl MIDE(*)/AD7.Impl VSCode Debugger AD7 Interface *MIDE: MIDebugEngine: GitHub repository *vsdbg can be used only in VS products and might not be distributed. MIText VS Debugger VS Debugger Engine vsdbg (closed license*) windbg See more: Architecture of MIEngin
  18. 18. .NET CoreのDebuggerの特徴 ◦ 低レイヤーはwindbg(vsdbg?)、GDB/LLDBとOS固有 ◦ WindowsではVisual Studioがすべて面倒みてくれる ◦ Linux (Mac)ではMIEngineというツールが面倒をみる ◦ MS製OSSだけど、バイナリの利用はVS製品のみ許可 ◦ ツールは違えどインターフェースは共通 ◦ WindowsとLinux(Mac)の間で 相互にリモートデバッグが可能
  19. 19. リモートのDockerに接続したい ◦ 技術的には可能 ◦ vsdbgのバイナリを手動インストール (VSから使う用途はOKのはず) ◦ sshコマンドの代わりにkubectl exec/oc rshなどを使えばよい ◦ が、現状、機能としては存在しない ◦ クローズド部分なのでVSIX(VS拡張)も作れない模様 ◦ Azureはkubernetes推しなので、将来対応するのでは? ◦ composerを直接はサポートしていないのでそこも対応を期待
  20. 20. Visual Studio Code なら可能 ◦ launch.jsonに追加 ◦ SSHの代わりに任意のコマンドを指定できる ◦ 月曜の夜に会社ブログに書いた記事が公開されます { "name": ".NET Core OpenShift Pod Remote Attach", "type": "coreclr", "request": "attach", "processId": "", "pipeTransport": { "pipeProgram": "oc", "pipeArgs": [ "exec", "-it", "<pod_name>", "--"], "quoteArgs":false, "debuggerPath": "/opt/app-root/vsdbg/vsdbg", "pipeCwd": "${workspaceRoot}" }, "justMyCode":false, "sourceFileMap": { "/opt/app-root/src": "${workspaceRoot}"} }
  21. 21. 設定ファイルの取り扱い ◦ソースコード=バイナリを変更せずに、 設定ファイルの差し替えで動作を変更したい ◦Docker環境でどうやって外部ファイルを注入する? ◦ 1回アプリのコンテナイメージ作ったら、 設定ファイルの変更だけのためにイメージ作り直したくな いですよね?
  22. 22. Add***File メソッドで設定の注入
  23. 23. Dockerでの取り扱い ◦ 設定ファイルを含んだvolumeをDocker起動時にマウントさせる ◦ Docker使わない環境でも指定したパスにファイルを置けばよい ◦ kubernetesの場合はConfigMapを使えます $ kubectl create configmap myconfig --from-file=appsettings.json //pod.yaml spec: containers: - name: test-container volumeMounts: - name: config-volume mountPath: /opt/app-root/conf volumes: - name: config-volume configMap: name: myconfig
  24. 24. 機密情報を扱いたい場合 ◦ DBのパスワードなど ◦ ソースコードリポジトリには入れたくない ◦ アプリのコンテナイメージにも入れておきたくない ◦ ASP.NET CoreのUserSecret機能は開発用途なので使うべき ではない ◦ マシン固有の暗号キーでファイルに保存しておく機能 ◦ Azureの場合  Azure Key Vault と Managed Service Identity ◦ 今のところPreviewでApp ServiceとAzure Functionsのみ利用可 ◦ kubernetes/OpenShiftの場合  Secret機能
  25. 25. Secret機能 Base64エンコードした値を格納して、 dockerコンテナにファイルもしくは環境変数としてマウント ◦ 暗号化ではない。アクセスを制限できるという意味合いはある
  26. 26. 複数コンテナでHTTPセッション デフォルトでは: ◦ コンテナごとにHTTPセッションをメモリ内に格納 ◦ コンテナでない場合もプロセスごとに別々 つまり? ◦ コンテナへのロードバランシングがStickyセッションなら コンテナが生きている限り問題なし ◦ コンテナが死んだらセッションが維持できない ◦ Stickyじゃないとそもそもセッションが維持できない
  27. 27. container A cnotainer B container C ASP.NET Core ASP.NET Core ASP.NET Core それぞれのコンテナに 別々にセッションデータが格納される container AでHTTPセッション確立しても 次のHTTPリクエストがcontainer Bだと 確立したセッションの情報はない
  28. 28. IDistributedCache & IDataProtection IDistributedCache ◦ 名前からしてこれだけ設定すれば十分な気がする これがまちがい ◦ 分散キャッシュを提供 ◦ セッションの格納先に指定できる ◦ SQLServerとRedisを保存先とするライブラリASP.NET Coreチームが提供 IDataProtection ◦ 暗号化のキー管理を提供 ◦ HTTPセッションの暗号化にも利用されている ◦ デフォルトではコンテナ(マシン)ごとにキーを発行し、 ローカルファイルに保存 ◦ Network FilesystemとRedisとAzure Storage, Azure Fileを提供
  29. 29. container A container B container C ASP.NET Core ASP.NET Core ASP.NET Core Session Data A’ containerごとに異なるキー セッションデータ自体を 共有できても、キーが違うので 復号できず意味がない ~/.aspnet IDistributedCacheをRedisに設定するだけだと…
  30. 30. machine A machine B machine C ASP.NET Core ASP.NET Core ASP.NET Core Session Data IDataProtectionもRedisに設定 キー自体をRedisに保存して 共有するのでOK! Redisが死んだ場合の考慮は必要
  31. 31. Redisを設定しましょう public void ConfigureServices(IServiceCollection services) { var conn = Configuration["REDIS_CONNECTION_STRING"]; var redis = ConnectionMultiplexer.Connect(conn); services.AddDataProtection() .PersistKeysToRedis(redis, "DataProtection-Keys"); services.AddDistributedRedisCache(option => { option.Configuration = conn; option.InstanceName = "master"; }); services.AddSession(); } httpsession.redis.cache.windows.net:6380,password=<password>,ssl=True,abortConnect=False
  32. 32. BlogTemplateを題材にしてみます ASP.NET Coreで作られたブログテンプレート ◦ MSDN Blogで紹介 Welcome to the New Blog Template for ASP.NET Developers ◦ ブログのデータはFilesystem上にxmlファイルとして配置するので、 EF Coreは認証まわりで利用するのみ 修正する必要はあるけどクロスプラットフォームで動きます ◦ Local SQLServer  SQLite ◦ https://github.com/VenusInterns/BlogTemplate/issues/187 ◦ SQL Server on Linuxでもいいけど同じ1ファイルベースで扱えるので ◦ ファイルパスがWindows Style前提なのを共通化 ◦ https://github.com/VenusInterns/BlogTemplate/issues/188
  33. 33. EF Coreで必要なコード Entity (DBテーブルに対応する)クラス DBContextクラス Startupで接続先やDBの種類などをセットアップ 必要なところでDI経由で取得
  34. 34. コードからDBテーブル作ろう 必要な操作 ◦ コードはあらかじめ用意しておく ◦ 接続先情報も渡している状態 ◦ 環境変数やファイルから読む場合はアクセスできるように ◦ migrationコードを生成する ◦ [ここまで開発環境で生成しておいて、ビルド・展開する] ◦ dotnet コマンドで起動する前にupdateを実行する $ dotnet ef database update $ dotnet ef migrations add [好きな名前]
  35. 35. Development環境だと ブラウザから実行できたりする
  36. 36. おまけ: RDBはコンテナ上で動かすべき? コンテナで動かすことがメリットになるなら動かそう コンテナのメリット => 生成・破棄が簡単。再現性がある CI/CDでのテストやデモ用 自動復帰できればサービス断がある程度許せるアプリ (コンテナのHealth Checkがあれば容易に復旧できる場合) CPUやメモリを専有したい場合や、クラスタリング組む場合は 従来の方法がいいのでは?
  37. 37. まとめ Visual Studio Docker Support ◦ いろいろ進化中 ◦ kubernetes対応進むと嬉しいなあ |ω・)チラ 設定の注入 ◦ Volumeとか環境変数経由で注入できる機能がある ◦ のでご利用のツールの機能と併せて使いましょう セッション管理 ◦ セッションデータの格納先とASP.NET Core側の設定に注意 EF Core ◦ コードファーストもあります ◦ RDBもコンテナに置いているときは、コードファーストで初期化できるのは便利かも

×