Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?
@wasimaru

ASP.NET Core のWebアプリケーションを Kubernetes で構築する

More than 1 year has passed since last update.

概要

(※) ASP.NET Core のWebアプリケーションを docker-compose で Dockerアプリケーション として構築する
の続編になります。

ASP.NET CoreのサンプルWebアプリケーションを題材として、Kubernetes の動作環境を構築する例を紹介します。

筆者は単なるアプリ屋ですが、「そろそろ Kubernetes に入門しておかないとヤバイかな…」と思い、
Kubernetes初心者ながら、本記事を書くに至りました。

Kubernetesの概念やリソース等は、ドキュメントや文献を参考にしつつ記載していますが、
間違いや不備があれば、ご指摘いただけると助かります。

環境

  • Windows10
  • Visual Studio 2019
  • ASP.NET Core 3.1
  • Docker for Windows

サンプルアプリケーション

題材にしたサンプルアプリケーションです。
https://github.com/tYoshiyuki/dotnet-core-web-sample

docker-composeの際に利用したToDoのWebアプリケーションを今回も利用します。
トランザクションデータはデータベース (SQL Server) に保存しています。

システム構成

Docker for Windows を利用して、ローカルPC上にKubernetes環境を構築します。
ローカル開発時は、IIS Express と LocalDB で構成していました。これを、下記図のイメージで構築します。

image.png

「Nginx + ASP.NET Coreアプリケーション」 と 「SQL Server Express」 で2つのPodを作成します。

Podとは、Kubernetesにおけるコンテナ集合体の単位になります。
コンテナ単体では扱い辛いため、利用したいコンテナをグルーピングして利用するイメージになります。

次に、「Web + アプリケーション部分を担当する dotnet-core-web-sample」 と
「DB部分を担当する sqlexpress」 の2つのServiceを定義します。

Serviceは、Kubernetesクラスタ内において、Podに対してのアクセス経路を定義するリソースになります。

Kubernetesにおいて、コンテナが実際に動作する環境を Node と言います。
PodはNodeに対して分散配置されるため、Pod間で通信を行うことを考えた場合に、
Podの実IPアドレスを意識したアクセスを行うことは困難です。

そのため、Podに対するアクセスを抽象化して提供する仕組みが Service ということになります、

また、外部からのHTTPアクセス用に Ingress を導入します。
Ingressは、ServiceをL7層のレベルで外部に公開するためのリソースです。
今回は Nginx Ingress Controller を利用します。

解説

Docker for Windows の設定から、Kubernetesを有効化します。
image.png

またGUIツールとして、Visual Studio Codeの拡張機能を利用しました。
Kubernetesのリソースを視覚的に確認できるため、導入しておくと便利です。
image.png

1. app.yaml

まずは、Nginx、ASP.NET Coreアプリケーションの部分の定義を作成します。
Kubernetesのリソースは、YAMLで定義していきます。

app.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dotnet-core-web-sample
  labels:
    app: dotnet-core-web-sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dotnet-core-web-sample
  template:
    metadata:
      labels:
        app: dotnet-core-web-sample
    spec:
      containers:
      - name: web
        image: dotnet-core-web-sample_web
        imagePullPolicy: IfNotPresent
        env:
        - name: BACKEND_HOST
          value: localhost:5000  
        ports:
        - containerPort: 80
      - name: app
        image: dotnet-core-web-sample_app
        imagePullPolicy: IfNotPresent
        env:
        - name: ConnectionStrings__DefaultConnection
          value: "Server=sqlexpress;Database=master;User ID=sa;Password=P@ssw0rd;initial catalog=dotnetcorewebsample;MultipleActiveResultSets=True;App=EntityFramework;"
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: dotnet-core-web-sample
spec:
  selector:
    app: dotnet-core-web-sample
  ports:
  - name: http
    port: 80

前半部分はDeployment、後半部分はServiceの定義になります。

Deploymentは、Deployment > ReplicaSet > Pod というように、Podを管理するための上位概念になります。
ReplicaSetは、同じ仕様のPodを複数生成・管理するためのリソースになります。
Deploymentは、ReplicaSetを世代管理するためのリソースです。
本記事では触れませんが、デプロイ時のロールバックやRollingUpdateの機能を定義することが出来ます。

Podに配置するコンテナの定義は containers: の部分で記載しています。
Podで利用するdockerイメージは、前回の記事で作成したローカルのイメージを利用します。
imagePullPolicy: IfNotPresentを記載することで、ローカルイメージが存在する場合に、それを利用するようにしています。
dotnet-core-web-sample_webはNginxのdockerイメージ、dotnet-core-web-sample_appはASP.NET Coreのdockerイメージです。

各設定内容は docker-compose とほぼ同じですが、BACKEND_HOST に localhost:5000 を設定します。
これは、同一Podにおける宛先を localhost で解決出来るためです。

Serviceでは、dotnet-core-web-sampleという名称で、80番ポートを公開しています。

2. sqlexpress.yaml

次に、SQL Server Expressの定義です。

sqlexpress.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sqlexpress
  labels:
    app: sqlexpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sqlexpress
  template:
    metadata:
      labels:
        app: sqlexpress
    spec:
      containers:
      - name: sqlexpress
        image: dotnet-core-web-sample_sqlexpress
        imagePullPolicy: IfNotPresent        
        env:
        - name: ACCEPT_EULA
          value: "Y"
        - name: MSSQL_PID
          value: Express
        - name: SA_PASSWORD
          value: P@ssw0rd
        ports:
        - containerPort: 1433
---
apiVersion: v1
kind: Service
metadata:
  name: sqlexpress
spec:
  selector:
    app: sqlexpress
  ports:
  - name: "1433"
    port: 1433
    targetPort: 1433

前半部分はDeployment、後半部分はServiceの定義になります。
構成内容としては、app.yamlとほぼ同様になっています。
Serviceでは、sqlexpressという名称で、SQL Server用の1433番ポートを公開しています。

3. Nginx Ingress Controllerの導入

Ingressを使用するために、Nginx Ingress Controllerを導入します。

Githubのドキュメントを参考にコマンドを実行します。
https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/index.md

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml

ドキュメントには Docker for Mac と書かれていますが、Docker for Windowsでも大丈夫でした。

4. ingress.yaml

最後に、ingress.yamlを作成します。

ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: dotnet-core-web-sample
spec:
  rules:
  - host: dotnetcorewebsample.local
    http:
      paths:
      - path: /
        backend:
          serviceName: dotnet-core-web-sample
          servicePort: 80

host: dotnetcorewebsample.localは、バーチャルホスト名になります。
path: /は、httpアクセス時のパス情報になります。

5. 動作確認

これまで作成してきた定義を、Kubernetesに適用させます。
kubectlコマンドを利用します。

> kubectl apply -f .\sqlexpress.yaml
deployment.apps/sqlexpress created
service/sqlexpress created

> kubectl apply -f .\app.yaml       
deployment.apps/dotnet-core-web-sample created
service/dotnet-core-web-sample created

> kubectl apply -f .\ingress.yaml
ingress.extensions/dotnet-core-web-sample created

稼働確認のため、hostsファイルに下記を記載します。

127.0.0.1 dotnetcorewebsample.local

ブラウザでアクセスすると、無事アクセスすることが出来ました。

image.png

まとめ

Kubernetesの概念は当初複雑に感じていましたが、実際に触ってみると理解が進み易いと感じました。
また、コンテナ技術を扱っている関係上、docker や docker-compose に慣れておくと入門し易いと思います。

5
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
wasimaru
元Sier → 事業会社でシステムエンジニアやってます、社会人アカペラサークルで歌ってます。C#が大好き。(Azure/AWS/C#/Java/PHP/React/Angular)(IPA/DB,SC,NW)(PMP)(Azure Administrator Associate)(AWS SAA)
yowayowa-engineer
弱々エンジニア会とは駆け出しエンジニアやベテランエンジニアまで、弱々から強々まで幅広く集まるコミュニティのエンジニア集団です!!メンバー募集してますので気になる方は、URLよりSlackに参加ください!条件等は特にありません!

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
5
Help us understand the problem. What is going on with this article?