前書き
Kubernetesは、コンテナ化されたアプリケーションを管理するためのオープンソースのコンテナオーケストレーションツールです。 このシリーズの前のチュートリアルhttps://www.digitalocean.com/community/tutorials/webinar-series-a-closer-look-at-kubernetes[Kubernetesの詳細]では、Kubernetesの構成要素を学習しました。
このチュートリアルでは、以前のチュートリアルの概念を適用して、Kubernetesでエンドツーエンドのマイクロサービスアプリケーションを構築、デプロイ、および管理します。 このチュートリアルで使用するサンプルWebアプリケーションは、MongoDBをデータベースとして使用するNode.jsで記述された「todoリスト」アプリケーションです。 これは、チュートリアルhttps://www.digitalocean.com/community/tutorials/webinar-series-building-containerized-applications [コンテナ化されたアプリケーションの構築]で使用したものと同じアプリケーションです。
このアプリのコンテナーイメージをDockerfileから構築し、そのイメージをDocker Hubにプッシュしてから、クラスターに展開します。 次に、需要の増加に合わせてアプリをスケーリングします。
前提条件
このチュートリアルを完了するには、次のものが必要です。
-
このチュートリアルシリーズの第3部で構成できるKubernetesクラスターhttps://www.digitalocean.com/community/tutorials/webinar-series-getting-started-with-kubernetes[Getting Started with Kubernetes]。
-
画像を保存するためのアクティブなhttps://hub.docker.com/[Docker Hub]アカウント。
-
ローカルマシンにインストールされたGit。 チュートリアルhttps://www.digitalocean.com/community/tutorials/contributing-to-open-source-getting-started-with-git [オープンソースへの貢献:Git入門]をインストールしてセットアップできます。コンピューターのGit。
ステップ1 – Dockerfileを使用してイメージを構築する
まず、WebアプリケーションをDockerイメージにパッケージ化してコンテナー化することから始めます。
ホームディレクトリに変更してから、Gitを使用して、このチュートリアルのサンプルWebアプリケーションをGitHubの公式リポジトリから複製します。
cd ~
git clone https://github.com/janakiramm/todo-app.git
Dockerfileからコンテナーイメージをビルドします。 -tスイッチを使用して、レジストリユーザー名、イメージ名、およびオプションのタグでイメージにタグを付けます。
docker build -t sammy/todo .
出力は、イメージが正常に構築され、適切にタグ付けされたことを確認します。
OutputSending build context to Docker daemon 8.238MB
Step 1/7 : FROM node:slim
---> 286b1e0e7d3f
Step 2/7 : LABEL maintainer = "[email protected]"
---> Using cache
---> ab0e049cf6f8
Step 3/7 : RUN mkdir -p /usr/src/app
---> Using cache
---> 897176832f4d
Step 4/7 : WORKDIR /usr/src/app
---> Using cache
---> 3670f0147bed
Step 5/7 : COPY ./app/ ./
---> Using cache
---> e28c7c1be1a0
Step 6/7 : RUN npm install
---> Using cache
---> 7ce5b1d0aa65
Step 7/7 : CMD node app.js
---> Using cache
---> 2cef2238de24
Successfully built 2cef2238de24
Successfully tagged sammy/todo-app:latest
docker imagesコマンドを実行して、イメージが作成されたことを確認します。
docker images
画像のサイズと作成後の時間を確認できます。
OutputREPOSITORY TAG IMAGE ID CREATED SIZE
sammy/todo-app latest 81f5f605d1ca 9 minutes ago 236MB
次に、Docker Hubのパブリックレジストリに画像をプッシュします。 これを行うには、Docker Hubアカウントにログインします。
docker login
資格情報を提供したら、Docker Hubのユーザー名を使用して画像にタグを付けます。
docker tag /todo-app
次に、画像をDocker Hubにプッシュします。
docker push
Webブラウザでhttps://hub.docker.com/[Docker Hub]を検索すると、新しいイメージが利用可能であることを確認できます。
Dockerイメージをレジストリにプッシュしたら、Kubernetes用にアプリケーションをパッケージ化しましょう。
ステップ2 – MongoDBポッドをKubernetesにデプロイする
アプリケーションは、MongoDBを使用して、Webアプリケーションで作成されたTo Doリストを保存します。 KubernetesでMongoDBを実行するには、Podとしてパッケージ化する必要があります。 このポッドを起動すると、MongoDBの単一のインスタンスが実行されます。
db-pod.yamlという新しいYAMLファイルを作成します。
nano db-pod.yaml
MongoDBに基づく1つのコンテナーでポッドを定義する次のコードを追加します。 MongoDBが使用する標準ポートであるポート `+ 27017 `を公開します。 定義には、ラベル「 name」と「+ app」が含まれていることに注意してください。 これらのラベルを使用して、特定のポッドを識別および構成します。
db-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: db
labels:
name: mongo
app: todoapp
spec:
containers:
- image: mongo
name: mongo
ports:
- name: mongo
containerPort: 27017
volumeMounts:
- name: mongo-storage
mountPath: /data/db
volumes:
- name: mongo-storage
hostPath:
path: /data/db
データは、ノードの「+ / data / db 」ロケーションにマッピングされる「 mongo-storage +」と呼ばれるボリュームに保存されます。 ボリュームの詳細については、公式のhttps://kubernetes.io/docs/concepts/storage/volumes[Kubernetesボリュームドキュメント]を参照してください。
次のコマンドを実行してポッドを作成します。
kubectl create -f db-pod.yml
次の出力が表示されます。
Outputpod "db" created
次に、ポッドの作成を確認します。
kubectl get pods
出力にはポッドが表示され、実行されていることが示されます。
OutputNAME READY STATUS RESTARTS AGE
db 1/1 0 2m
このポッドをクラスターの内部コンシューマーがアクセスできるようにします。
MongoDBのサービスを定義する次のコードを含む、「+ db-service.yaml +」という新しいファイルを作成します。
db-service.yaml
apiVersion: v1
kind: Service
metadata:
name: db
labels:
name: mongo
app:
spec:
selector:
name: mongo
type: ClusterIP
ports:
- name: db
port: 27017
targetPort: 27017
サービスは、同じ名前空間で、 `+ name:db `のラベルに一致するすべてのポッドを検出します。 YAMLファイルの ` selector +`セクションは、この関連付けを明示的に定義します。
`+ type:ClusterIP +`宣言により、クラスター内でサービスが表示されるように指定します。
ファイルを保存し、エディターを終了します。 次に、 `+ kubectl +`を使用してクラスターに送信します。
kubectl create -f db-service.yml
サービスが正常に作成されたことを示す次の出力が表示されます。
Outputservice "db" created
ポッドが利用可能なポートを取得しましょう。
kubectl get services
次の出力が表示されます。
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db ClusterIP 10.109.114.243 <none> 14s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47m
この出力から、サービスがポート `+ 27017 `で利用可能であることがわかります。 Webアプリケーションは、このサービスを通じてMongoDBに到達できます。 ホスト名「 db +」を使用する場合、Kubernetes内で実行されているDNSサービスは、アドレスをサービスに関連付けられたClusterIPに解決します。 このメカニズムにより、ポッドは相互に検出および通信できます。
データベースポッドとサービスを配置したら、Webアプリケーションのポッドを作成しましょう。
ステップ3 – Node.JS Webアプリをポッドとしてデプロイする
このチュートリアルの最初のステップで作成したDockerイメージをポッドとしてパッケージ化し、クラスターにデプロイします。 これは、エンドユーザーがアクセスできるフロントエンドWebアプリケーションレイヤーとして機能します。
`+ web-pod.yaml +`という新しいYAMLファイルを作成します。
nano web-pod.yaml
+ sammy / todo-app +
Dockerイメージに基づいて1つのコンテナーでポッドを定義する次のコードを追加します。 TCPプロトコルを介してポート「3000」で公開されます。
web-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
name: web
app:
spec:
containers:
- image: sammy/todo-app
name: myweb
ports:
- containerPort: 3000
定義には、ラベル「+ name」と「+ app」が含まれていることに注意してください。 サービスはこれらのラベルを使用して、着信トラフィックを適切なポートにルーティングします。
次のコマンドを実行してポッドを作成します。
kubectl create -f web-pod.yaml
Outputpod "web" created
ポッドの作成を確認しましょう:
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE
1/1 Running 0 8m
1/1 Running 0 9s
MongoDBデータベースとWebアプリの両方がPodsとして実行されていることに注意してください。
ここで、 `+ web +`ポッドをパブリックインターネットにアクセスできるようにします。
サービスは、一連のPodを内部または外部に公開します。 `+ web +`ポッドを公開するサービスを定義しましょう。 NodePortを介して公開します。これは、クラスターの各ノードで開かれた任意のポートを介してPodにアクセスできるようにするスキームです。
アプリのサービスを定義する次のコードを含む「+ web-service.yaml +」という新しいファイルを作成します。
apiVersion: v1
kind: Service
metadata:
name: web
labels:
name: web
app:
spec:
selector:
name: web
type: NodePort
ports:
- name: http
port: 3000
targetPort: 3000
protocol: TCP
サービスは、名前空間が「+ web +」のラベルと一致する同じ名前空間内のすべてのポッドを検出します。 YAMLファイルのセレクターセクションは、この関連付けを明示的に定義します。
`+ type:NodePort `宣言により、サービスが ` NodePort +`型であることを指定します。
`+ kubectl +`を使用して、これをクラスターに送信します。
kubectl create -f web-service.yml
サービスが正常に作成されたことを示す次の出力が表示されます。
Outputservice "web" created
ポッドが利用可能なポートを取得しましょう。
kubectl get services
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db ClusterIP 10.109.114.243 <none> 27017/TCP 12m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 59m
web NodePort 10.107.206.92 <none> 3000: 12s
この出力から、サービスがポート `+ 30770 +`で利用可能であることがわかります。 ワーカーノードの1つに接続してみましょう。
DigitalOceanコンソールを使用して、Kubernetesクラスターに関連付けられているワーカーノードのいずれかのパブリックIPアドレスを取得します。
image:https://assets.digitalocean.com/articles/webinar_3_kubernetes_stackpoint/w9acP7y.png [ワーカーノードを表示するDigitalOceanコンソール]
IPアドレスを取得したら、 `+ curl `コマンドを使用して、ポート ` 30770 +`上のノードの1つにHTTPリクエストを送信します。
curl http://:30770
次のような出力が表示されます。
Output<!DOCTYPE html>
<html>
<head>
<title>Containers Todo Example</title>
<link rel='stylesheet' href='/stylesheets/screen.css' />
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div id="layout">
<h1 id="page-title">Containers Todo Example</h1>
<div id="list">
<form action="/create" method="post" accept-charset="utf-8">
<div class="item-new">
<input class="input" type="text" name="content" />
</div>
</form>
</div>
<div id="layout-footer"></div>
</div>
<script src="/javascripts/ga.js"></script>
</body>
</html>
Webポッドとサービスを定義しました。 次に、レプリカセットを使用したスケーリングについて見てみましょう。
ステップ5-Webアプリケーションのスケーリング
レプリカセットは、常に最小数のポッドがクラスター内で実行されていることを確認します。 ポッドがレプリカセットとしてパッケージ化されると、Kubernetesは常に、仕様で定義されている最小数のポッドを実行します。
現在のポッドを削除し、レプリカセットを介して2つのポッドを再作成しましょう。 ポッドを実行したままにすると、レプリカセットの一部にはなりません。 したがって、カウントが1つだけであっても、レプリカセットを介してポッドを起動することをお勧めします。
まず、既存のポッドを削除します。
kubectl delete pod web
Outputpod "web" deleted
次に、新しいレプリカセット宣言を作成します。 レプリカセットの定義はポッドと同じです。 主な違いは、実行する必要があるPodの数を定義する `+ replica +`要素が含まれていることです。 ポッドと同様に、サービス検出に役立つメタデータとしてラベルも含まれています。
ファイル `+ web-rs.yaml +`を作成し、このコードをファイルに追加します。
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: web
labels:
name: web
app: todoapp
spec:
replicas: 2
template:
metadata:
labels:
name: web
spec:
containers:
- name: web
image: sammy/todo-app
ports:
- containerPort: 3000
ファイルを保存して閉じます。
次に、レプリカセットを作成します。
kubectl create -f web-rs.yaml
Outputreplicaset "web" created
次に、ポッドの数を確認します。
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE
db 1/1 Running 0 18m
web-n5l5h 1/1 Running 0 25s
web-wh6nf 1/1 Running 0 25s
NodePortを介してサービスにアクセスすると、リクエストはレプリカセットによって管理されるポッドの1つに送信されます。
ポッドの1つを削除して何が起こるかを見て、レプリカセットの機能をテストしましょう。
kubectl delete pod web-wh6nf
Outputpod "web-wh6nf" deleted
ポッドをもう一度見てください。
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE
db 1/1 Running 0 19m
web-n5l5h 1/1 Running 0 1m
web-wh6nf 1/1 Terminating 0 1m
web-ws59m 0/1 ContainerCreating 0 2s
ポッドが削除されるとすぐに、Kubernetesは別のポッドを作成して、目的のカウントが維持されるようにします。
レプリカセットを拡張して、追加のWebポッドを実行できます。
次のコマンドを実行して、Webアプリケーションを10ポッドにスケーリングします。
kubectl scale rs/web --replicas=
Outputreplicaset "web" scaled
ポッドカウントを確認します。
kubectl get pods
次の出力が表示されます。
OutputNAME READY STATUS RESTARTS AGE
db 1/1 Running 0 22m
web-4nh4g 1/1 Running 0 21s
web-7vbb5 1/1 Running 0 21s
web-8zd55 1/1 Running 0 21s
web-f8hvq 0/1 ContainerCreating 0 21s
web-ffrt6 1/1 Running 0 21s
web-k6zv7 0/1 ContainerCreating 0 21s
web-n5l5h 1/1 Running 0 3m
web-qmdxn 1/1 Running 0 21s
web-vc45m 1/1 Running 0 21s
web-ws59m 1/1 Running 0 2m
Kubernetesは、「+ web +」ポッドのスケーリングプロセスを開始しました。 NodePortを介してサービスにリクエストが届くと、レプリカセットのポッドの1つにルーティングされます。
トラフィックと負荷が落ち着いたら、2つのポッドの元の構成に戻すことができます。
kubectl scale rs/web --replicas=
Outputreplicaset "web" scaled
このコマンドは、2つを除くすべてのポッドを終了します。
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE
db 1/1 Running 0 24m
web-4nh4g 1/1 Terminating 0 2m
web-7vbb5 1/1 Terminating 0 2m
web-8zd55 1/1 Terminating 0 2m
web-f8hvq 1/1 Terminating 0 2m
web-ffrt6 1/1 Terminating 0 2m
web-k6zv7 1/1 Terminating 0 2m
web-n5l5h 1/1 Running 0 5m
web-qmdxn 1/1 Terminating 0 2m
web-vc45m 1/1 Terminating 0 2m
web-ws59m 1/1 Running 0 4m
レプリカセットの可用性を確認するには、ポッドの1つを削除して、カウントを確認してください。
kubectl delete pod web-ws59m
Outputpod "web-ws59m" deleted
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE
db 1/1 Running 0 25m
web-n5l5h 1/1 Running 0 7m
web-ws59m 1/1 Terminating 0 5m
web-z6r2g 0/1 ContainerCreating 0 5s
ポッドカウントが変更されるとすぐに、Kubernetesは、YAMLファイルで定義されたカウントに一致するようにポッドを調整します。 レプリカセット内のWebポッドの1つが削除されると、別のポッドがすぐに作成され、目的のカウントが維持されます。 これにより、常に最小数のPodが常に実行されるようになり、アプリケーションの高可用性が確保されます。
次のコマンドを使用して、このチュートリアルで作成したすべてのオブジェクトを削除できます。
kubectl delete -f db-pod.yaml -f db-service.yaml -f web-rs.yaml -f web-service.yaml
Outputpod "db" deleted
service "db" deleted
replicaset "web" deleted
service "web" deleted
結論
このチュートリアルでは、シリーズで説明したすべての概念を適用して、マイクロサービスアプリケーションのパッケージ化、デプロイ、およびスケーリングを行いました。
このシリーズの次のパートでは、MongoDBをStatefulSetとして実行することにより、MongoDBを高可用性にする方法を学習します。