GKE で .NET Core アプリを実行してみた

Mourad El Azhari
google-cloud-jp
Published in
7 min readDec 16, 2019

--

この記事は Google Cloud Japan Customer Engineer Advent Calendar 2019 の 15日目の記事です。

TL;DR

.NET Core の特徴の一つはクロスプラットフォームであり、Windows 以外に Linux でも実行できるランタイムです。.NET Core のアプリケーションをコンテナ化し、Google Kubernetes Engine (GKE) を実行環境として選ぶと Google Cloud Platform (GCP)のサービスを利用できるメリットがありますので、簡単な Web アプリを GKE と GCP が提供している HTTP(S) Load Balancer の特徴を活かした設定を紹介します。

.NET Core の簡単なアプリケーションを作成しコンテナ化

.NET Core は現時点で 3.1 になっており、3.0 以降にコンテナ化として使うためにいくつかのパフォーマンス改善がありました。

Web アプリもしくは Web API を利用するには、.NET Core でもいいですが、ASP .NET Core は Web アプリケーションを作成するためのライブラリーを集めたフレームワークになりますので、ASP .NET Core を使ったほうが早いです。

この記事では以下の構成で簡単な ASP .NET Core アプリケーションを GKE にホスティングします。

まずは .NET Core をインストールします。インストールされたら Version が 3.0 以降かを確認します。

dotnet --version

簡単な Web アプリケーションを作成します。

dotnet new webapp

※ API を作成するには :dotnet new webapi

上のコマンドでテンプレートからアプリケーションが作成され、好みの IDE でコーディング・デバッグし、ローカルで実行します。

dotnet run — urls=http://localhost:8080

Docker Container として作成したアプリをパッケージするための Dockerfile を作成します。
例として Dockerfile は以下のようになります。

# Use official image from Microsoft
FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
WORKDIR /app
COPY --from=build-env /app/out .
# App binds to port 8080
ENV ASPNETCORE_URLS http://*:8080
ENTRYPOINT ["dotnet", "dotnetwebapp.dll"]

Dockerfile には環境変数である ASPNETCORE_URLS を利用してポートを指定します。

次は Docker でビルドしたイメージを GCP が提供しているコンテナレジストリサービス GCR にプッシュします。
ProjectID を変数として取得

export PROJECT_ID=$(gcloud config get-value core/project)

Docker イメージをビルド

docker build -t gcr.io/${PROJECT_ID}/dotnet-app:v1 .

ここでローカル環境でコンテナが問題なく稼働できるかを確認

docker run -p 8080:8080 gcr.io/${PROJECT_ID}/dotnet-app:v1

curl localhost:8080 もしくはウェブブラウザに http://localhost:8080 にアクセスすると

GCR にプッシュ

docker push gcr.io/${PROJECT_ID}/dotnet-app:v1

これで GKE に Deployment を作成するために準備完了!

GKE クラスタを作成し、Deployment と Service を作成

GKE の詳細な作成方法はここに書きませんが、既存の GKE に対し Deployment や Service を作成するには Credentials が必要なので、取得します。

gcloud container clusters get-credentials <GKEクラスタ名>

そして Deployment と Service の作成はここに記載した同じ方法でできます。

今回は GKE Ingress と NodePort を使って外部にサービスを公開しますGKE では Ingress を作成すると HTTP(S) Load Balancer を作成してくれます。

例えば今回のサンプルで web という Service を NodePort タイプとして作成されているとします。Service が実行しているかを確認します。

kubectl get service web

Ingress リソースを以下の Ingress.yaml でデプロイします。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: basic-ingress
spec:
backend:
serviceName: web
servicePort: 8080

デプロイはこれで行います。

kubectl apply -f ingress.yaml

作成するには少し時間がかかりますが、作成されますと IP アドレスで作成した Web App にアクセスできます。

TLS 通信を行うために Load Balancer に SSL 証明書を設定

ここまでは HTTP 通信を HTTP(S) Load Balancer で実施しました。GCP で HTTPS を対応するのはとても簡単で、Load Balancer に SSL 証明書をアップロードするだけです。

所有しているドメインに対し DNS の設定が必要ですが、Google-managed SSL Certificate (現時点でベータ) で持っているドメインに対し証明書を発行できます。

gcloud beta compute ssl-certificates create mouradecert --domains mourade.com

証明書を Load Balancer にアタッチするには Ingress に Annotation として追加

networking.gke.io/managed-certificates: "mouradecert"

更新された Ingress をデプロイ

kubectl apply -f ingress.yaml

これで登録されているドメインで HTTPS 通信が可能になります。

まとめ

Webアプリケーションや API を .NET Core で作成するときホスティングサービスとして利用できるプラットフォームが多く提供されていますが、コンテナでパッケージし Kubernetes で提供するとスケーラビリティーを簡単に実現できます。GKE はマネージドサービスとして利用するメリットの他、GCP で提供されている HTTP(S) Load Balancer の特徴も活かせるので、TLS 通信を Load Balancer レベルでオフロードできるメリットがあります。

--

--

Mourad El Azhari
google-cloud-jp

Building too many stuff. Working as Customer Engineer in Google Cloud Japan.