[.NET, Kubernetes, Docker] Running .NET Core on the Oracle Container Engine for Kubernetes

原文はこちら。
https://blogs.oracle.com/cloudnative/dotnet-core-on-kubernetes

先日、Getting Function'l with Kubernetesイベントの参加者から.NET CoreアプリケーションをKubernetesで実行する件について質問をもらいました。
It's a Wrap! Getting Function'l with Kubernetes
https://blogs.oracle.com/cloudnative/its-a-wrap-getting-functionl-with-kubernetes
「直近では、クラウドネイティブアプリを稼働させることに関して、Windowsと.NETの世界はどうなっているのだろう」と思ったのですが、そのことをKubernetesに関するLinkedIn Learningチュートリアルを撮影したときに思い出しました。「WindowsでMinikubeを使ってKubernetesを実行するのはそれほど難しいことではないが、.NETアプリケーションを実行するのはどうなのだろう?」
Learning Kubernetes
https://www.linkedin.com/learning/learning-kubernetes
時間を掛けてエコシステムを調べました。このエントリでは、Oracle Container Engineでサンプルの.NETアプリケーションを実行する方法を説明します。
Container Engine for Kubernetes
https://cloud.oracle.com/containers/kubernetes-engine
コードに直接触れたい開発者は、以下のURLでコードを確認できます。
Running a dotnet app in Kubernetes
https://github.com/karthequian/dotnet-example
これらのすべてのサンプルをMac上に構築しましたが、どのプラットフォームを選択してもすべて実行できるはずです。何らかの理由で立ち往生した場合は、(原文のコメント欄に)コメントしてください。はまっている問題を再現して調査します。

以前.NETアプリケーションを書いたのは5年以上前なので、Macに必要なものを全てインストールする必要がありました。まず、.NET Core Web APIアプリケーションを作成するために、Microsoftが公開しているシンプルな.NETチュートリアルをはじめました。
.NET Tutorial - Hello World in 10 minutes
https://www.microsoft.com/net/learn/get-started-with-dotnet-tutorial
より多くのエンドポイントやコードを追加することを考えましたが、最終的にはチュートリアルでできあがるコードと同じように、シンプルにしました。読者を.NET REST APIの魔法で混乱させたかったのではなく、Kubernetesプラットフォームでアプリケーションを実行したかったからです。補足として、dotnetコマンドは非常にすばらしいです。開発、ビルド、テストを全て非常にシームレスに実現し、一日中dockerコマンドとkubectlコマンドを実行するクラウドネイティブ開発者にとって直覚的なコマンドです。

必要なもののインストールが終了したら、シンプルなASP.NET Core Web APIアプリケーションを以下のコマンドを使って作成しました。
~$ dotnet new webapi --auth None --no-https
本格的なアプリケーションの場合、機密データを扱っている場合は認証を設定し、httpsも有効にする必要があります。 このコマンドを実行すると、簡単なREST APIを作成する新しいwebappを作成します。以下のような出力が出ます。
~$ dotnet new webapi --auth None --no-https
The template "ASP.NET Core Web API" was created successfully.
Processing post-creation actions...
Running 'dotnet restore' on /Users/karthik/dev/src/github.com/karthequian/dotnet-example/dotnet-example.csproj...
  Restoring packages for /Users/karthik/dev/src/github.com/karthequian/dotnet-example/dotnet-example.csproj...
  Generating MSBuild file /Users/karthik/dev/src/github.com/karthequian/dotnet-example/obj/dotnet-example.csproj.nuget.g.props.
  Generating MSBuild file /Users/karthik/dev/src/github.com/karthequian/dotnet-example/obj/dotnet-example.csproj.nuget.g.targets.
  Restore completed in 1.42 sec for /Users/karthik/dev/src/github.com/karthequian/dotnet-example/dotnet-example.csproj.
Restore succeeded.
すばらしい!これで、この新規作成したアプリケーションを実行するために、 dotnet run をタイプできるようになりました。以下のようにAPIが起動するはずです。
~$ dotnet run
Using launch settings from /Users/karthik/dev/src/github.com/karthequian/dotnet-example/Properties/launchSettings.json...
: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
  User profile is available. Using '/Users/karthik/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Development
Content root path: /Users/karthik/dev/src/github.com/karthequian/dotnet-example
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
テストしたい場合には、エンドポイント /api/values/ を以下のように呼び出すことで可能でした。値リストを取得したら、アプリケーションが期待通りに動作していることがわかります。
~$ curl localhost:5000/api/values/

["value1","value2"]
Macで.NET webappが動作したので、ここからは楽しいこと、dockerizeとkubifyをやっていきましょう。

Docker対応のため、以下のDockerドキュメントにあるガイドラインに従って、.NETアプリケーションのDockerイメージを構築しました。
Create a Dockerfile for an ASP.NET Core application
https://docs.docker.com/engine/examples/dotnetcore/#create-a-dockerfile-for-an-aspnet-core-application
エントリポイントの名前がプロジェクト名だったので、 dotnet-example.dll に変更しました。最終的なDockerfileが以下にあります。
Dockerfile
https://github.com/karthequian/dotnet-example/blob/master/Dockerfile
再実行してcurlでテスト後、このアプリケーションを karthequian/dotnetexample としてDockerストアにプッシュしてありますので、テスト目的でこのサンプルアプリケーションを実行できます。
karthequian/dotnetexample
https://store.docker.com/community/images/karthequian/dotnetexample
最後に、これをKubernetesで実行するため、デプロイメントとサービスを作成しました。
Deployment.yaml
https://github.com/karthequian/dotnet-example/blob/master/Deployment.yaml
このyamlファイルは、ホスト上のポート32000上で実行中のnodePortサービスを使用して、コンテナをデプロイメントとして公開します。利便性のため、Kubernetesでデプロイメントとサービスを実行するために以下のコマンドをタイプしてください。
kubectl apply -f https://raw.githubusercontent.com/karthequian/dotnet-example/master/Deployment.yaml
今回は概念実証(Proof of Concept)としてOracle Container Engineでアプリケーションを実行することにしましたが、任意のKubernetesディストリビューションで動作するはずです。今回はKubernetes 1.9.7クラスタでテストしましたが、最新バージョンとの前方互換性もあります。

以下は実行例です。
~$ kubectl apply -f https://raw.githubusercontent.com/karthequian/dotnet-example/master/Deployment.yaml
deployment "dotnetworld" created
service "dotnetworld" created
 ~$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
dotnetworld 1 1 1 1 20s
 ~$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dotnetworld 10.96.79.93 80:32080/TCP 26s
kubernetes 10.96.0.1 443/TCP 30d
最後に、テストのために、以下に示すようにノードIPとポートに対して再度curlを使ってAPIを呼び出します。
~$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dotnetworld 10.96.79.93 80:32080/TCP 26s
kubernetes 10.96.0.1 443/TCP 30d
 ~/dev/src/github.com/karthequian/dotnet-example$ kubectl get nodes
NAME STATUS AGE VERSION
129.146.123.174 Ready 30d v1.9.7
129.146.133.234 Ready 30d v1.9.7
129.146.162.102 Ready 30d v1.9.7
 ~$ curl 129.146.162.102:32080/api/values
["value1","value2"]
Oracle Container Service for Kubernetesで管理されたKubernetes 1.9.7で動作する、Dockerコンテナ化され、Macでビルドされた.NET Core Webアプリケーションができあがりました。時間がかかりそうに思われるかもしれませんが、およそ1時間で全て完了しており、全く苦労はありませんでした。

問題に遭遇したり、質問があったりする場合には、(以下の原文の)コメント欄からコメントをお寄せいただくか、@iteration1 へのメンション、またはGitHubのリポジトリでIssueを立ててお知らせください。

0 件のコメント:

コメントを投稿