マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

  • 運用環境へのデプロイについては、専任のエンジニアに相談する必要があるものと思われれる。

手順1

以下の手順で検証・評価した。

環境

  • Win 10 Pro
  • Hyper-Vの有効化
  • .NET Core 2.0
  • VS 2017 Community

プロジェクトの作成

ASP.NET Core MVCアプリケーションの作成

  • Dockerサポートなし
  • 認証なし

プロジェクトの設定

  • プロジェクトを作成した後にプロジェクトを右クリックしてDockerサポートを追加
手順1
  • Hyper-V コンテナ上で動作するOS(Windows or Linux)を選択(ここではLinuxを選択)。
手順2

インストレーション

  • Docker for Windowsのインストール(ダウンロードに少々時間がかかる)
手順3
  • Docker for Windowsのインストール・ウィザード
    Docker ≒ Linuxコンテナなので下のCheck Boxは外しておく)
手順4
手順5

デバッグ実行の準備

手順6
  • 再起動後、Hyper-V上にLinux VMを確認できる(MobyLinuxVM)。
手順7
  • 再度デバッグ実行を行うと、以下のエラー・メッセージが表示される。
手順8
  • エラー・メッセージが以下のように変更される(Dockerが実行されていないとのこと)。
手順9
  • 暫く経つと、以下のダイアログが表示された。
    OKを押下して再起動する(再起動に少々時間がかかる)。
手順10
  • 再起動を行うと、以下のダイアログボックスが表示される
    (なお、ココでサインアップ・サインインはしなくてもイイ)。
手順11
  • この時点で、以下のdockerコマンドをcmdから実行すると、
    dockerコマンドが適切に実行され結果が返り、Docker(のクライアント)が実行されていることを確認する。
    > docker version
    > docker run hello-world
  • デバッグ実行を開始すると、以下のcmdが起動し「何か」がダウンロードされ、
    手順12

※ 後々、「from microsoft/aspnetcore」でググって、
コンパイル済みのASP.NET Coreアプリケーションを実行するための
公式のDocker Imageをダウンロードしていたことが解った。
https://hub.docker.com/r/microsoft/aspnetcore/

  • 次いで、以下のエラー・メッセージが表示されるので、
手順13
  • メッセージ通り、Docker for Windowsの設定で、ボリューム共有を有効にする。
    Docker for Windowsの画面はタスクトレイ (Task tray) から起動する。
    手順14
  • 管理者アカウントのCredentialの入力を求められるので入力を行う。
  • 設定完了後、再度デバッグ実行を行うと、以下のダイアログが表示されるので、
    [アクセスを許可する]ボタンを押下し、VPNKitと言う組込みVPNツールのリスニング・ポートを開放する。
手順15
  • これにより、アプリケーションがHyper-V コンテナ内のDocker(Linuxコンテナ)で起動し、デバッグが開始される。

ブレークポイントを設定してデバッグ実行する。

設定の確認

  • ここまでの手順で、ソリューションに「docker-compose」が追加されているのを確認する。
  • この「docker-compose」が、スタートアップ・プロジェクトに設定されていることを確認する。

デバッグ実行

  • デバッグ実行を開始する(ドロップダウン・リストに「Docker」が選択されていることを確認する)。
  • ブレークポイントを設定して実行すると、
    以下のように、適切にデバッグ実行されていることを確認できる。
手順16
  • 本当にLinux上で動いているか心配なので、念のため、確認する。
    確認方法
    手順17

余談:PDBのタイプ

Docker側でライブラリのデバッグをする場合、ライブラリのPDBが、
「完全(full)」ではなくて、「ポータブル(portable)」である必要がある。

手順2

  • より実践的な開発環境を構成する。
    • Webサーバ:Docker側のKestrelで動作する。
    • DB:ホスト側のDBで動作させたい。
  • 後者のDBへのアクセスが可能かどうかDBMSアプリケーションを使用して確認する。
    (DBMSアプリケーションとしては、ASP.NET Core対応されたOpen棟梁テンプレートを使用する。)

設定ファイル読み込み方法の変更

  • 早速エラーが発生。DBアクセス以前に設定ファイルへのアクセスができない。
手順18
  • 以下のように調査すると、プロジェクト内のファイルがカレント・ディレクトリ(/app)にデプロイされることが解る。
手順19
  • 従って、
  • プロジェクト内にファイルを配置し、
    (「リンクとして追加」の設定はNG、「出力ディレクトリにコピー」の設定は不要)
    これを読み取る方向性で対応するか、
  • 旧Azure PaaS時と同様に、埋め込まれたリソースで対応できる。
    設定の仕方は、以下の「Azure Web Apps」で動作させる方法が参考になる。

SQL Serverへの接続

ホスト側のDBで動作させようとしたが、ハマりどころが多かったのでメモ。

接続文字列

  • ホストのIPアドレスは、10.0.75.1になる。
  • Windows認証ではなく、SQL Server認証の接続文字列を使用する。

Windows ファイアウォール

  • 必要時応じて設定する。
  • OFFにして通ったら絞るのがイイ。

SQL Server 構成マネージャー

Expressの場合は、SQL Server 構成マネージャーの設定も必要にある。

参考

変更点のスクショ

以下は、ASP.NET Core MVCのOpen棟梁テンプレートの変更点のスクショです。
(設定ファイル読み込み方法に「埋め込まれたリソース」を採用した場合)

手順20

手順3

  • 概要
    • Webサーバを、Kestrelからnginxプロキシ経由に変更する。
    • Docker Hubから、ASP.NET Core + nginx
      イメージ・ファイルを取得する(「nginx:latest」と「aspnetcore:latest」)。
    • 上記の2つのコンテナを作成を・管理する場合、docker-composeを利用する。
  • 構成
    • ホスト(VPNKit?の8888)-> nginx-proxyコンテナ(nginxの80) ->ASP.NET Coreコンテナ( Kestrelの5000)とブリッジする。
    • 各コンテナは、それぞれ独立したIPアドレスを持っており、dockerコマンドで調べることができる。

初期設定

手順1と同じ。

コンテナの管理

複数のコンテナを扱うので、そろそろ管理コマンド・ツールを理解する。

dockerコマンド

  • docker image
    • docker image ls
    • docker image rm image xxxxxxxxxxxx
  • docker ps
  • docker inspect id xxxxxxxxxxxx
  • , etc.

Kitematicのインストール

  • Windows環境からは、以下のようにDocker for Windows
    タスクトレイ (Task tray) の Context Menu からダウンロードする。
    手順21
    手順22
  • インストールはzip解凍でOK。
  • 解凍フォルダのexeを起動する。

Update-Package

Update-Packageを実行する。

Kestrelのポートを固定する。

Program.csに以下の行を追加する。

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseUrls("http://0.0.0.0:5000/") // ← ココを追加 localhost や 127.0.0.1 だとダメ。
        .Build();

Dockerfileファイルの編集

Dockerfileファイル(Dockerfile)の編集

ASP.NET Coreコンテナ

既定のDockerfileファイルを修正

  • 変更前
    FROM microsoft/aspnetcore:2.0 AS base
    WORKDIR /app
    EXPOSE 80
    
    FROM microsoft/aspnetcore-build:2.0 AS build
    WORKDIR /src
    COPY WebApplication1.sln ./
    COPY WebApplication1/WebApplication1.csproj WebApplication1/
    RUN dotnet restore -nowarn:msb3202,nu1503
    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"]
  • 変更後
    • aspnetcore:2.0 ---> latestと変更
    • EXPOSE 80 ---> 5000と変更
      FROM microsoft/aspnetcore:latest AS base
      WORKDIR /app
      EXPOSE 5000
      
      FROM microsoft/aspnetcore-build:latest AS build
      WORKDIR /src
      COPY WebApplication1.sln ./
      COPY WebApplication1/WebApplication1.csproj WebApplication1/
      RUN dotnet restore -nowarn:msb3202,nu1503
      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"]

nginxコンテナ

nginxフォルダにDockerfileファイルを作成する。
※ nginxフォルダは、Docker Composeファイル(docker-compose.yml)と同じ階層に作成。

FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/default.conf

nginx設定ファイルの追加

nginxフォルダにdefault.confを作成する。
※ nginxフォルダは、Docker Composeファイル(docker-compose.yml)と同じ階層に作成。

既定値

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $http_host;
        proxy_cache_bypass $http_upgrade;
    }
}

変更後

server {
    listen        80;
    server_name   localhost;
    location / {
        proxy_pass         http://xxx.xxx.xxx.xxx:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $http_host;
        proxy_cache_bypass $http_upgrade;
    }
}

※ xxx.xxx.xxx.xxxには、

  • 以下コマンドを使用して、
    ASP.NET CoreコンテナのIPAddressとして取得する。
    • docker ps
    • docker inspect id xxxxxxxxxxxx

Docker Composeファイルの編集

Docker Composeファイル(docker-compose.yml)の編集

既定値

version: '3'
services:
  webapplication1:
    image: webapplication1
    build:
      context: .
      dockerfile: /WebApplication1/Dockerfile

変更後

version: '3'
services:
  nginx-proxy:
    image: nginx-proxy
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - "8888:80"
    links:
      - webapplication1
  webapplication1:
    image: webapplication1
    build:
      context: ./WebApplication1
      dockerfile: Dockerfile
    ports:
      - "5000:5000"

補足

Dockerfile

Dockerfileには様々な設定が可能。

  • Dockerfileを使用する場合、
    buildにcontextとdockerfileを指定する。
  • Dockerfileが必要ない場合、
    buildはサボってimageをそのまま利用することも可能。

Docker Composeファイル

  • ports
    • ポートを公開(expose)する。
      • 「ホスト : コンテナ」で、ホストとポートを指定する。
      • コンテナのポートのみ指定(ホスト側のポートはランダム)。
    • 公式のイメージでは、記載がなくてもデフォルト・ポートが公開(expose)される。
  • links
    • コンテナ内の/etc/hostsに指定したサービス名が追加される。
    • サービス名とリンク・エイリアス(サービス : エイリアス)の指定も可能。
  • volumes
    • ホストのディレクトリをマウントする。
    • 再デプロイせずにローカルファイルの変更を反映できる。
    • また、データストアのデータファイルにも使用できる。

手順4

概要

手順3

  • SessionストアのKVS(Redis)と
  • DataストアのDBMS(PostgreSQL)の

コンテナを追加してみる。

永続化

  • 永続化の方法には、
  • ホストのディレクトリにマウントする方法
  • データコンテナを使う方法
  • 「起動時に都度、初期化する方法」

がある。

  • それぞれ、その用途から、
  • KVS(Redis)には、「ホストのディレクトリにマウントする方法」
    (1つの負荷分散クラスタのSessionストアとして利用するため)
  • DBMS(PostgreSQL)には、「起動時に都度、初期化する方法」
    (ココでは、主に、テスト自動化での利用を検討しているため)

を採用する。

構成図

構成図

初期設定

手順3と同じ。

Redis

構築

  • Docker Composeファイル(docker-compose.yml)へ追記
    以下のセクションを追加する。
    • redis:
      redis:
        image: redis
        volumes:
          - ./redis/data:/data
          - ./redis/redis.conf:/usr/local/etc/redis/redis.conf
        command: redis-server --appendonly yes
        ports:
          - "6379:6379"
        restart: always
  • /dataをマウントすると良い
  • appendonly yesがないとデータが作られない
  • webapplication1:
    linksにサービス名を記載する。
    links:
      - redis

接続確認

WSLから、redis-cliをインストールして確認する。

  • インストール
    sudo apt-get install redis-tools
  • 動作確認
    $ redis-cli -h 127.0.0.1
    127.0.0.1:6379> set mystr1 "abc"
    OK
    127.0.0.1:6379> get mystr1
    "abc"
    127.0.0.1:6379>

データ・アクセスの実装

  • NuGet
    (既定でMicrosoft.AspNetCore?.Allに含まれる)
    • Microsoft.AspNetCore?.Session
    • Microsoft.Extensions.Caching.Redis.Core
  • 以下を実装する。
    • Startup.cs
      using System;
      using Microsoft.AspNetCore.Builder;
      using Microsoft.AspNetCore.Hosting;
      using Microsoft.Extensions.Configuration;
      using Microsoft.Extensions.DependencyInjection;
      using Microsoft.AspNetCore.Http;
      
      namespace WebApplication1
      {
          public class Startup
          {
              public Startup(IConfiguration configuration)
              {
                  Configuration = configuration;
              }
      
              public IConfiguration Configuration { get; }
      
              // This method gets called by the runtime. Use this method to add services to the container.
              public void ConfigureServices(IServiceCollection services)
              {
                  // Redisを設定
                  services.AddDistributedRedisCache(option =>
                  {
                      option.Configuration = "redis";
                      option.InstanceName = "redis";
                  });
      
                  // Sessionを使用する。
                  services.AddSession(options =>
                  {
                      // Set a short timeout for easy testing.
                      options.IdleTimeout = TimeSpan.FromSeconds(10);
                      options.Cookie.HttpOnly = true;
                  });
      
                  services.AddMvc();
              }
      
              // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
              public void Configure(IApplicationBuilder app, IHostingEnvironment env)
              {
                  if (env.IsDevelopment())
                  {
                      app.UseBrowserLink();
                      app.UseDeveloperExceptionPage();
                  }
                  else
                  {
                      app.UseExceptionHandler("/Home/Error");
                  }
      
                  app.UseStaticFiles();
      
                  // Sessionを使用する。
                  app.UseSession();
      
                  app.UseMvc(routes =>
                  {
                      routes.MapRoute(
                          name: "default",
                          template: "{controller=Home}/{action=Index}/{id?}");
                  });
              }
          }
      }
  • HomeController?.cs
    public IActionResult Index()
    {
        HttpContext.Session.SetString("TestId", DateTime.Now.ToString());
        return View();
    }
    
    public IActionResult About()
    {
        ViewData["Message"] = "Your application description page. " + HttpContext.Session.GetString("TestId");
        return View();
    }

テスト

  • 画面
    手順23
  • redis-cli
    127.0.0.1:6379> keys *
    1) "redis69ed5ead-0115-372b-8ef7-665bc769e747"
    2) "mystr1"

PostgreSQL

構築

  • postgresフォルダにpostgres設定ファイルを追加
    ※ postgresフォルダは、Docker Composeファイル(docker-compose.yml)と同じ階層に作成。
    • 初期化用SQLを ./postgres/init/init.sh に作成
      psql -U postgres << "EOSQL"
      
      CREATE DATABASE postgres;
      \c postgres;
      
      --------------------
      -- TABLE: Shippers 
      --------------------
      CREATE TABLE Shippers(
          ShipperID      integer    NOT NULL,
          CompanyName    VARCHAR(40)    NOT NULL,
          Phone          VARCHAR(24),
          CONSTRAINT PK_Shippers PRIMARY KEY (ShipperID)
      );
      
      --------------------
      -- Sequence: ShipperID
      --------------------
      CREATE SEQUENCE TS_ShipperID;
      
      --------------------
      -- INSERT
      --------------------
      INSERT INTO Shippers (ShipperID, CompanyName, Phone) VALUES(nextval('TS_ShipperID'), 'Speedy Express', '(503) 555-9831');
      INSERT INTO Shippers (ShipperID, CompanyName, Phone) VALUES(nextval('TS_ShipperID'), 'United Package', '(503) 555-3199');
      INSERT INTO Shippers (ShipperID, CompanyName, Phone) VALUES(nextval('TS_ShipperID'), 'Federal Shipping', '(503) 555-9930');
      
      EOSQL
  • Docker Composeファイル(docker-compose.yml)へ追記
    以下のセクションを追加する。
    • postgres:
         image: postgres
         volumes:
           #- ./postgres/data:/var/lib/postgresql/data
           - ./postgres/init:/docker-entrypoint-initdb.d
         environment:
           - POSTGRES_USER=postgres
           - POSTGRES_PASSWORD=seigi@123
         ports:
             - "5432:5432"
         restart: always
  • webapplication1:
    linksにサービス名を記載する。
    links:
      - redis
      - postgres

接続確認

WSLから、postgresql-clientをインストールして確認する。

  • インストール
    sudo apt-get install postgresql-client
  • 動作確認
    $ psql -h 127.0.0.1 -d postgres -U postgres -c "select * from shippers"
    Password for user postgres:
     shipperid |   companyname    |     phone
    -----------+------------------+----------------
             1 | Speedy Express   | (503) 555-9831
             2 | United Package   | (503) 555-3199
             3 | Federal Shipping | (503) 555-9930
    (3 rows)

データ・アクセスの実装

  • 以下を実装する。
    • HomeController?.cs
      public IActionResult About()
      {
          string count = "";
          using (var con = new NpgsqlConnection("HOST=postgres;DATABASE=postgres;USER ID=postgres;PASSWORD=seigi@123;"))
          {
              con.Open();
              var cmd = new NpgsqlCommand(@"select count(*) from shippers", con);
              count = cmd.ExecuteScalar().ToString();
          }
          ViewData["Message"] = "Your application description page. " + count + "件";
          return View();
      }

テスト

  • 画面
    手順24

サンプル

MVC_Sample

https://github.com/daisukenishino2/EvaluateAspNetCoreOnDocker/tree/master/MVC_Sample

WebApplication1

https://github.com/daisukenishino2/EvaluateAspNetCoreOnDocker/tree/master/WebApplication1

参考

Microsoft Docs

きよくらの備忘録

ONE-RUN

銀の光と碧い空

データストア・コンテナ関連

Redis

外部から接続する場合、redis.confを修正する必要がある模様。

PostgreSQL

Visual Studio Kubernetes Tools


Tags: :.NET開発, :.NET Core, :Hyper-V, :仮想化


添付ファイル: filestructure.png 58件 [詳細] file24.png 50件 [詳細] file23.png 43件 [詳細] file22.png 51件 [詳細] file21.png 43件 [詳細] file20.png 55件 [詳細] file19.png 56件 [詳細] file18.png 70件 [詳細] file17.png 121件 [詳細] file16.png 42件 [詳細] file15.png 59件 [詳細] file14.png 54件 [詳細] file10.png 71件 [詳細] file13.png 52件 [詳細] file12.png 60件 [詳細] file11.png 58件 [詳細] file9.png 46件 [詳細] file8.png 64件 [詳細] file7.png 74件 [詳細] file6.png 72件 [詳細] file5.png 71件 [詳細] file4.png 51件 [詳細] file3.png 48件 [詳細] file2.png 71件 [詳細] file1.png 66件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-11-13 (火) 19:20:16 (34d)