概要
(※) 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 で構成していました。これを、下記図のイメージで構築します。
「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を有効化します。
またGUIツールとして、Visual Studio Codeの拡張機能を利用しました。
Kubernetesのリソースを視覚的に確認できるため、導入しておくと便利です。
1. app.yaml
まずは、Nginx、ASP.NET Coreアプリケーションの部分の定義を作成します。
Kubernetesのリソースは、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の定義です。
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を作成します。
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
ブラウザでアクセスすると、無事アクセスすることが出来ました。
まとめ
Kubernetesの概念は当初複雑に感じていましたが、実際に触ってみると理解が進み易いと感じました。
また、コンテナ技術を扱っている関係上、docker や docker-compose に慣れておくと入門し易いと思います。