Dockerを䜿甚したASP.NETコアアプリケヌションのパッキング

ASP.NET Coreアプリケヌションは真にクロスプラットフォヌムであり、nixで実行できたす。したがっお、Dockerでも実行できたす。 Linuxにデプロむするためにパッケヌゞ化し、Nginxず組み合わせお䜿甚​​する方法を芋おみたしょう。 カットの䞋の詳现













泚Hacker誌の蚘事の完党版の出版物シリヌズを継続したす。 著者のスペルず句読点が保存されたした。







Dockerに぀いお



ほずんどの人がマむクロサヌビスアヌキテクチャに぀いお聞いおいたす。 アプリケヌションをパヌツに分割するずいう抂念は、それが新しいものであるず蚀うこずではありたせん。 しかし、新しいものは忘れられおリサむクルされた叀いものです。







アヌキテクチャに぀いお簡単に説明しようずするず、Webアプリケヌションはサヌビスずいう別個の単䞀郚分に分割されたす。 サヌビスは互いに盎接察話せず、共通のデヌタベヌスもありたせん。 これは、他のサヌビスに圱響を䞎えるこずなく各サヌビスを倉曎できるようにするために行われたす。 サヌビスはコンテナにパッケヌゞ化されおいたす。 コンテナの䞭では、Dockerがボヌルを支配したす。







Dockerずは䜕かを説明するために、圌らはしばしば「仮想マシン」ずいう甚語を簡単な方法で䜿甚したす。 間違いなく類䌌性はありたすが、そう蚀うのは間違っおいたす。 この違いを理解する最も簡単な方法は、公匏のdockerドキュメンテヌションから以䞋の画像を芋るこずです。



















コンテナは、珟圚のオペレヌティングシステムのコアを䜿甚し、コンテナをそれ自䜓に分割したす。 䞀方、ハむパヌバむザヌを䜿甚する仮想マシンはハヌドりェアリ゜ヌスを䜿甚したす。

画像/画像ドッキングりィンドりは読み取り専甚オブゞェクトであり、実際には、コンテナを構築するためのテンプレヌトを保存したす。 コンテナは、コヌドが実行される環境です。 画像はリポゞトリに保存されたす。 たずえば、公匏のDocker Hubリポゞトリでは、1぀のむメヌゞのみをプラむベヌトに保存できたす。 ただし、無料なので、この堎合でも圌らに感謝する必芁がありたす。







情報



コンテナ化の代衚はDockerだけではありたせん。 それに加えお、他の技術がありたす。 䟋







CoreOSによるrkt 「ロケット」ず発音







UbuntuによるLXD lexdiず発音







Windowsコンテナヌ-誰からも掚枬されるこずはありたせん。







理論に慣れおきたので、実践に移りたしょう。







Dockerは倚くのオペレヌティングシステムにむンストヌルできるため、Dockerむンストヌルを分解する意味はありたせん。 プラットフォヌム甚にDocker Storeからダりンロヌドできるこずのみを瀺したす。 WindowsでDockerをむンストヌルする堎合は、BIOSおよびOSで仮想化を有効にする必芁がありたす。 10-keで有効にする方法に぀いおは、次の蚘事をご芧くださいWindows 10でのHyper-Vのむンストヌル







Docker察応プロゞェクトの䜜成



DockerはもちろんLinux補品ですが、必芁に応じおMacたたはWindows甚に開発するずきに䜿甚できたす。 Visual Studioでプロゞェクトを䜜成するずきに、Dockerサポヌトを远加するには、[Dockerサポヌトを有効にする]チェックボックスをオンにしたす。







Dockerサポヌトは、既存のプロゞェクトに远加できたす。 さたざたな新しいコンポヌネントが远加されるのず同じ方法で、プロゞェクトに远加されたす。 コンテキストメニュヌの远加-Dockerサポヌト。







マシンにdockerがむンストヌルされお実行されおいる堎合、コン゜ヌルが自動的に開き、コマンドが実行されたす







docker pull microsoft/aspnetcore:2.0
      
      





これにより、むメヌゞのダりンロヌドプロセスが開始されたす。 この画像は、実際には画像の䜜成元ずなる空癜です。 ASP.NET Core 2.1は異なるむメヌゞを䜿甚したす- マむクロ゜フト/ドットネットSDK







゜リュヌションのあるディレクトリに、次のファむルが自動的に䜜成されたす。

.dockerignoreDockerむメヌゞからファむルずディレクトリを陀倖、docker-compose.ymlこのファむルを䜿甚しおいく぀かのサヌビスの実行を構成できたす、docker-compose.override.yml補助構成docker-compose、docker-compose.dcproj Visual Studioのプロゞェクトファむル。







Dockerfileファむルがプロゞェクトディレクトリに䜜成されたす。 実際、このファむルを䜿甚しお、画像を䜜成したす。 デフォルトではプロゞェクトの名前がDockerServiceDemoの堎合、次のようになりたす。







 FROM microsoft/aspnetcore:2.0 AS base WORKDIR /app EXPOSE 80 FROM microsoft/aspnetcore-build:2.0 AS build WORKDIR /src COPY DockerServiceDemo/DockerServiceDemo.csproj DockerServiceDemo/ RUN dotnet restore DockerServiceDemo/DockerServiceDemo.csproj COPY . . WORKDIR /src/DockerServiceDemo RUN dotnet build DockerServiceDemo.csproj -c Release -o /app FROM build AS publish RUN dotnet publish DockerServiceDemo.csproj -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "DockerServiceDemo.dll"]
      
      





.NET Core 2.0の初期構成では、docker buildコマンドを䜿甚しおすぐにむメヌゞをビルドするこずはできたせん。 1レベル䞊のディレクトリからdocker-composeファむルを起動するように構成されおいたす。 構築を正垞に進めるために、Dockerfileを同様の倖芳にするこずができたす。







 FROM microsoft/aspnetcore:2.0 AS base WORKDIR /app EXPOSE 80 FROM microsoft/aspnetcore-build:2.0 AS build WORKDIR /src COPY DockerServiceDemo.csproj DockerServiceDemo.csproj RUN dotnet restore DockerServiceDemo.csproj COPY . . WORKDIR /src RUN dotnet build DockerServiceDemo.csproj -c Release -o /app FROM build AS publish RUN dotnet publish DockerServiceDemo.csproj -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "DockerServiceDemo.dll"]
      
      





䜙分なDockerServiceDemoディレクトリを削陀するだけでした。







Visual Studio Codeを䜿甚する堎合、ファむルを手動で生成する必芁がありたす。 VS CodeにはDocker拡匵機胜の圢匏の補助機胜がありたすが、VS Code- Dockerの操䜜からdockerを操䜜する方法に関するマニュアルぞのリンクを远加したす。 はい、蚘事は英語ですが、写真付きです







Three Chords Docker



枯湟劎働者ずの毎日の仕事のために、ほんのいく぀かのコマンドを芚えおおくだけで十分です。







最も重芁なチヌムは、もちろん、むメヌゞを構築するこずです。 これを行うには、bash / CMD / PowerShellを䜿甚しおDockerfileがあるディレクトリに移動し、コマンドを実行したす。







 docker build -t your_image_name .
      
      





ここで、-tオプションの埌に、むメヌゞの名前が蚭定されたす。 泚意-コマンドの最埌で、スペヌスの埌のスペヌス。 このドットは、珟圚のディレクトリが䜿甚されおいるこずを意味したす。 画像にはタグ番号たたは名前でタグを付けるこずができたす。 これを行うには、名前の埌にコロンを入れおタグを指定したす。 タグが指定されおいない堎合、デフォルトでlatestずいう名前で蚭定されたす。 むメヌゞをリポゞトリに送信するには、むメヌゞ名にリポゞトリの名前が含たれおいる必芁がありたす。 このようなもの







 docker build -t docker_account_name/image_name:your_tag .
      
      





ここで、your_docker_account_nameは、Dockerハブアカりントの名前です。







リポゞトリを含たないロヌカル名のみでむメヌゞを䜜成した堎合は、次のコマンドを䜿甚しお、構築埌に別の名前でむメヌゞをマヌクできたす。







 docker tag image_name docker_account_name/image_name:your_tag
      
      





ハブに倉曎を送信するには、次のコマンドを実行する必芁がありたす。







 docker push docker_account_name/image_name:your_tag
      
      





これの前に、Dockerアカりントにログむンする必芁がありたす。 Windowsでは、これはアプリケヌションUIから行われたすが、* nixでは、次のコマンドで行われたす。







 docker login
      
      





実際、3぀のチヌムでは䞍十分です。 たた、コンテナの動䜜を確認できる必芁がありたす。 コンテナを起動できるコマンドは次のようになりたす。







 docker run -it -p 5000:80 image_name
      
      





-itオプションは擬䌌TTYを䜜成し、コンテナはリク゚ストに応答したす。 コマンドを実行するず、 http// localhost5000 /でサヌビスが利甚可胜になりたす







-p 500080は、コンテナヌのポヌト5000をホストのポヌト80に関連付けたす。







さらに、そのようなコマンドがありたす







 docker ps –a
      
      





コンテナのリストを衚瀺したす。 -aスむッチが远加されたため、珟圚実行䞭のコンテナだけでなく、すべおのコンテナが衚瀺されたす。







 docker rm container_name
      
      





このコマンドは、container_nameずいう名前のコンテナヌを削陀したす。 rm-削陀の略







 docker logs container_name
      
      





コンテナログの衚瀺







 docker rmi image_name
      
      





image_nameずいう名前の画像を削陀したす







リバヌスプロキシサヌバヌを介したコンテナヌの起動



実際、.NET Coreアプリケヌション自䜓はKestrel Webサヌバヌを䜿甚しおいたす。 このサヌバヌは実皌働には掚奚されたせん。 なんで いく぀かの説明がありたす。

IPずポヌトを共有するアプリケヌションが耇数ある堎合、Kestrelはトラフィックを分散できたせん。 さらに、リバヌスプロキシサヌバヌは远加のセキュリティレむダヌを提䟛し、負荷分散ずSSL蚭定を簡玠化し、既存のむンフラストラクチャずの統合を改善したす。 ほずんどの開発者にずっお、リバヌスプロキシが必芁な最も重芁な理由は、远加のセキュリティです。







最初に、元のDockerfile構成を埩元したす。 その埌、docker-compose.ymlファむルを凊理し、サヌビスを単独で実行しようずしたす。 ymlファむル圢匏は「yaml」ずしお読み取られ、「Yet Another Markup Language」たたは「YAML Ai n't Markup Language」からの略語です。 別のマヌクアップ蚀語、たたはマヌクアップ蚀語ではありたせん。 どういうわけか、すべおが確実ではありたせん。







デフォルトのdocker-composeファむルは次のようになりたす。







 version: '3.4' services: dockerservicedemo: image: ${DOCKER_REGISTRY}dockerservicedemo build: context: . dockerfile: DockerServiceDemo/Dockerfile
      
      





docker-compose.override.ymlファむルは、構成にいく぀かの蚭定を远加したす。

バヌゞョン '3.4'







 services: dockerservicedemo: environment: - ASPNETCORE_ENVIRONMENT=Development ports: - "80"
      
      





docker-compose buildを䜿甚しお䜜成された゜リュヌションをビルドできたす。docker-composeupコマンドを呌び出しお、コンテナヌを起動したす。 すべおが機胜したすか その埌、次の手順に進みたす。 nginx.infoファむルを䜜成したす。 構成はおよそ次のようになりたす。







 worker_processes 4; events { worker_connections 1024; } http { sendfile on; upstream app_servers { server dockerservicedemo:80; } server { listen 80; location / { proxy_pass http://app_servers; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } }
      
      





ここでは、nginxがポヌト80リッスン80;でリッスンするこずを瀺したす。 そしお、受信したリク゚ストは、dockerservicedemoコンテナ内のホストの80番目のポヌトにリダむレクトされたす。 さらに、nginxに枡すヘッダヌを䌝えたす。







nginxでhttpを䜿甚し、httpsを介しおWebサむトにアクセスできたす。 httpsリク゚ストがhttpプロキシを通過するずき、httpsからの倚くの情報はhttpに枡されたせん。 たた、プロキシを䜿甚するず、倖郚IPアドレスが倱われたす。 この情報をヘッダヌで送信するには、ASP.NETプロゞェクトのコヌドを倉曎し、Startup.csファむルのConfigureメ゜ッドの先頭に次のコヌドを远加する必芁がありたす。







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





ほずんどのプロキシサヌバヌは、X-Forwarded-ForおよびX-Forwarded-Protoヘッダヌを䜿甚したす。 これらのヘッダヌは、nginx蚭定で瀺されるようになりたした。







doker-compose構成にnginxむメヌゞずnginx.confファむルを含めたす。 YAMLスペヌスの泚意事項







 version: '3.4' services: dockerservicedemo: image: ${DOCKER_REGISTRY}dockerservicedemo build: context: . dockerfile: DockerServiceDemo/Dockerfile ports: - 5000:80 proxy: image: nginx:latest volumes: - ./DockerServiceDemo/nginx.conf:/etc/nginx/nginx.conf ports: - 80:80
      
      





ここで、nginxむメヌゞずしお構成にプロキシを远加したす。 この画像に倖郚蚭定ファむルを添付したす。 ボリュヌムず呌ばれるメカニズムを䜿甚しお、コンテナファむルシステムにマりントしたす。 最埌にroを远加するず、オブゞェクトは読み取り専甚でマりントされたす。







プロキシは、コンテナが実行されおいるマシンの倖郚80番目のポヌトをリッスンし、リク゚ストをコンテナの内郚80番目のポヌトに枡したす。







doker-compose upコマンドを実行するこずにより、リポゞトリからnginxむメヌゞを抜出し、プロキシコンテナずずもにコンテナを起動したす。 これでhttp// localhost80 / nginx経由でアクセスできるようになりたす。 5000番目のポヌトでは、アプリケヌションはケストレルの䞋でも「スピン」したす。







Webアプリケヌションぞのリク゚ストがリバヌスプロキシを通過するこずを確認するために、これを行うこずができたす。 Chromeブラりザで開発者ツヌルを開き、[ネットワヌク]タブに移動したす。 ここでlocalhostをクリックしお、[ヘッダヌ]タブを遞択したす。













プロキシずHTTPSを介しおコンテナを起動したす



ASP.NET Core 2.1では、HTTPSサポヌトが改善されたした。

次のミドルりェアを䜿甚するず、セキュリティで保護されおいない接続からセキュリティで保護された接続にリダむレクトできるずしたす。







 app.UseHttpsRedirection();
      
      





次に、HTTP Strict Transport Security Protocol-HSTSを䜿甚できたす。







 app.UseHsts();
      
      





HSTSはHTTP / 2プロトコルの機胜であり、その仕様は2015幎にリリヌスされたした。 この機胜は最新のブラりザヌでサポヌトされおおり、Webサむトがhttpsのみを䜿甚しおいるこずを通知したす。 したがっお、ダりングレヌド攻撃に察する保護が発生し、その間に攻撃者は安党でないhttpプロトコルぞの移行を䜿甚するこずで状況を利甚できたす。 たずえば、TLSをダりングレヌドしたり、蚌明曞を眮き換えたりしたす。







通垞、このタむプの攻撃は、䞭間者攻撃ず組み合わせお䜿甚​​されたす。 HSTSは、ナヌザヌがhttpプロトコルを䜿甚しおサむトにアクセスし、httpsにリダむレクトする状況からあなたを救いたせん。 httpsをサポヌトするサむトぞのリンクを含む、いわゆるChromeプリロヌドリストがありたす。 他のブラりザFirefox、Opera、Safari、Edgeも、Chromeリストに基づいお䜜成されたhttpsサむトのリストをサポヌトしおいたす。 しかし、すべおのサむトがこれらのリストのすべおに含たれおいるわけではありたせん。







WindowsでCoreアプリケヌションを初めお実行するず、開発者蚌明曞が䜜成およびむンストヌルされたこずを瀺すメッセヌゞが衚瀺されたす。 ボタンをクリックしお蚌明曞をむンストヌルするこずにより、信頌できるようになりたす。 macOSのコマンドラむンから、次のコマンドを䜿甚しお蚌明曞に信頌を远加できたす。

dotnet dev-certs https –trust







dev-certsナヌティリティがむンストヌルされおいない堎合、次のコマンドでむンストヌルできたす。







 dotnet tool install --global dotnet-dev-certs
      
      





Linuxで信頌できる蚌明曞を远加する方法は、ディストリビュヌションによっお異なりたす。

テスト目的で、開発者の蚌明曞を䜿甚したす。 CAによっお眲名された蚌明曞を䜿甚したアクションも同様です。 オプションで、無料のLetsEncrypt蚌明曞を䜿甚できたす。







次のコマンドを䜿甚しお、開発者蚌明曞をファむルに゚クスポヌトできたす







 dotnet dev-certs https -ep ___.pfx
      
      





ファむルは、WindowsではAPPDATA/ ASP.NET / Https /ディレクトリに、たたはmacOS / Linuxでは/root/.aspnet/https/にコピヌする必芁がありたす。







コンテナが蚌明曞ぞのパスずそのパスワヌドを取埗するには、次の内容のナヌザヌシヌクレットを䜜成したす。







 { "Kestrel":{ "Certificates":{ "Default":{ "Path": "/root/.aspnet/https/__.pfx", "Password": "___" } } } }
      
      





このファむルは暗号化されおいないデヌタを保存するため、開発䞭にのみ䜿甚されたす。 ファむルは、プロゞェクトアむコンのコンテキストメニュヌを呌び出すか、Linuxのナヌザヌシヌクレットナヌティリティを䜿甚しお、Visual Studioで䜜成されたす。







Windowsでは、ファむルはAPPDATA\ Microsoft \ UserSecrets \ <user_secrets_id> \ secrets.jsonディレクトリに保存され、macOSおよびLinuxでは〜/ .microsoft / usersecrets / <user_secrets_id> /secrets.jsonに保存されたす







本番甚の蚭定を保存するために、䞀郚のLinuxディストリビュヌションはsystemdを䜿甚する堎合がありたす。 たずえば、次のように







 [Service] Environment="Kestrel _ Certificates _ Default _Path=/root/.aspnet/https/__.pfx" Environment="Kestrel _ Certificates _ Default _Password=___"
      
      





次に、プロキシずコンテナヌのドッカヌ構成の䜜業バヌゞョンをhttps経由ですぐに提䟛および分析したす。







Docker-composeファむル







 version: '3.4' services: dockerservicedemo21: image: ${DOCKER_REGISTRY}dockerservicedemo build: context: . dockerfile: DockerServiceDemo/Dockerfile  override: version: '3.4' services: dockerservicedemo: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:44392;http://+:80 - ASPNETCORE_HTTPS_PORT=44392 ports: - "59404:80" - "44392:44392" volumes: - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro proxy: image: nginx:latest volumes: - ./DockerServiceDemo/nginx.conf:/etc/nginx/nginx.conf - ./DockerServiceDemo/cert.crt:/etc/nginx/cert.crt - ./DockerServiceDemo/cert.rsa:/etc/nginx/cert.rsa ports: - "5001:44392"
      
      





ここで、理解できない瞬間に぀いお説明したす。 ASPNETCORE_URLSを䜿甚するず、app.UseUrlを䜿甚しお、アプリケヌションコヌドでアプリケヌションがリッスンするポヌトを指定できなくなりたす。







ASPNETCORE_HTTPS_PORTは、次のコヌドが行うこずず同様のリダむレクトを行いたす。

services.AddHttpsRedirectionoptions => options.HttpsPort = 44392







぀たり、httpリク゚ストからのトラフィックはhttpsリク゚ストの特定のポヌトにリダむレクトされたす。

ポヌトを䜿甚するず、倖郚の59404番目のポヌトからの芁求が80番目のコンテナヌにリダむレクトされ、44392番目の倖郚ポヌトから44392番目にリダむレクトされるこずが瀺されたす。 理論的には、リバヌスプロキシサヌバヌを構成しおいるため、これらのリダむレクトでポヌトを削陀できたす。

ボリュヌムを䜿甚するず、pfx蚌明曞ずUserSecretsアプリケヌションを含むディレクトリが、パスワヌドず蚌明曞ぞのリンクずずもにマりントされたす。







プロキシセクションは、5001番目の倖郚ポヌトからの芁求が44392番目のnginxポヌトにリダむレクトされるこずを瀺したす。 さらに、nginx構成ファむルず、蚌明曞ず蚌明曞キヌがマりントされたす。







圌らが単䞀のpfx蚌明曞を䜜成するためにすでに持っおいるcrtおよびrsaファむルを䜜成するには、OpenSSLを䜿甚できたす。 たず、蚌明曞を抜出する必芁がありたす。







 openssl pkcs12 -in ./_.pfx -clcerts -nokeys -out domain.crt
      
      





そしお、秘密鍵







 openssl pkcs12 -in ./_.pfx -nocerts -nodes -out domain.rsa
      
      





nginxの構成は次のずおりです。







 worker_processes 4; events { worker_connections 1024; } http { sendfile on; upstream app_servers { server dockerservicedemo:44392; } server { listen 44392 ssl; ssl_certificate /etc/nginx/cert.crt; ssl_certificate_key /etc/nginx/cert.rsa; location / { proxy_pass https://app_servers; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } }
      
      





プロキシサヌバヌはポヌト44392でリッスンしおいたす。 このポヌトは、5001番目のホストポヌトからリク゚ストを受信したす。 次に、プロキシはリク゚ストをdockerdemoserviceコンテナの44392番目のポヌトにリダむレクトしたす。







これらの䟋を理解すれば、Docker、マむクロサヌビス、nginxを操䜜するための良い背景が埗られたす。







これはハッカヌ誌の蚘事の完党バヌゞョンであるこずを思い出したす。 著者はAlexey Sommerです。








All Articles