この記事は、クラウドでのコンテナー化されたワークロードのデプロイと管理に関するウェビナーシリーズを補足するものです。 このシリーズでは、コンテナライフサイクルの管理、マルチコンテナアプリケーションのデプロイ、ワークロードのスケーリング、Kubernetesの操作など、コンテナの基本事項について説明します。 また、ステートフルアプリケーションを実行するためのベストプラクティスについても説明します。
このチュートリアルには、シリーズの5番目のセッションであるKubernetesでのステートフルサービスのデプロイの概念とコマンドが含まれています。
###序章
Kubernetes は、コンテナー化されたアプリケーションを管理するためのオープンソースのコンテナーオーケストレーションツールです。 このシリーズの前のパートでは、Kubernetesのビルディングブロックとパッケージ化されたコンテナをKubernetesReplicaSetsとして学習しました。 ReplicaSetはステートレスポッドの可用性を保証しますが、データベースクラスターなどのステートフルワークロードでは使用できません。
Kubernetesで最新のクラウドネイティブアプリケーションをパッケージ化、デプロイ、管理、スケーリングするのは簡単かもしれませんが、コンテナ化された環境でデータベースやコンテンツ管理システムなどの従来のワークロードをデプロイおよび管理するには、別のアプローチが必要です。 StatefulSets は、KubernetesReplicaSetの柔軟性をステートフルワークロードにもたらします。
このチュートリアルシリーズの最終回では、Kubernetesの人気のあるオープンソースパッケージマネージャーである Helm を使用して、高可用性のMongoDBReplicaSetをStatefulSetとしてKubernetesにデプロイします。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- StackPointCloud を介してインストールされた、DigitalOceanで実行されているアクティブなKubernetesクラスター。これは、チュートリアル Getting Started withKubernetesに従って実行できます。
- チュートリアルKubernetesでのマイクロサービスのデプロイとスケーリングで紹介されたサンプルWebアプリケーションは、Node.jsとMongoDBに基づいており、データベースに高可用性をもたらすように拡張されています。 アプリケーション設計の詳細については、コンテナ化されたアプリケーションの構築チュートリアルを参照してください。
- アプリケーションのDockerイメージを保存するためのアクティブなDockerHubアカウント。
- Gitがインストールされているローカルマシン
- macOSを使用している場合は、Homebrewがインストールされていることを確認してください。
ステップ1-開発マシンへのHelmクライアントのインストール
Helmを使用すると、管理者は1つのコマンドで複雑なKubernetesアプリケーションをデプロイできます。 アプリケーションは、Kubernetesアプリケーションを定義、インストール、アップグレードするChartsとしてパッケージ化されています。 グラフは、ポッド、デプロイ、サービスなどのKubernetesオブジェクトを抽象化したものです。
Helmには、サーバーとクライアントの2つのコンポーネントがあります。 Helmのサーバー側は、Tillerと呼ばれるサービスとしてKubernetesで実行されます。 クライアントは、Tillerと対話するコマンドラインツールです。
MongoDB ReplicaSet Helm Chartをデプロイするため、Helmのサーバー側コンポーネントであるTillerと通信するCLIが必要です。 DigitalOceanでKubernetesをセットアップするために使用したStackPointCloudには、Tillerがプリインストールされています。
注:これらの手順はmacOS用です。 他のオペレーティングシステムを使用している場合は、ヘルムインストールガイドを参照してください。
MacにHomebrewがインストールおよび構成されていると仮定して、次のコマンドを実行してHelmをインストールします。
- brew install kubernetes-helm
Output==> Downloading https://homebrew.bintray.com/bottles/kubernetes-helm-2.8.2.high_sierra.bottle.tar.gz
...
==> Summary
🍺 /usr/local/Cellar/kubernetes-helm/2.8.2: 50 files, 121.7MB
Helmをインストールしたら、現在のバージョンを確認して、Helmを実行できることを確認します。
- helm version
OutputClient: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}
これにより、クライアントが正しくインストールされ、Tillerと通信できることが確認されます。
次のステップでは、Helmを使用してMongoDBReplicaSetをKubernetesにデプロイします。
ステップ2–KubernetesにMongoDBReplicaSetをデプロイする
KubernetesのStorageClassは、管理者が提供するストレージの「クラス」を説明する方法を提供します。 たとえば、ユーザーがストレージボリュームを要求すると、StorageClassは、ユーザーからプロビジョニングされるストレージバックエンドのクラスを決定します。 クラスには、標準のHDDとより高速なSSDが含まれる場合があります。 舞台裏では、StorageClassはクラウドプロバイダーのAPIなどの基盤となるインフラストラクチャと対話して、ストレージをプロビジョニングします。
MongoDBデータを保存するには永続ストレージが必要なため、DigitalOceanブロックストレージボリュームをワーカーノードに接続し、永続性のためにストレージボリュームを使用するようにMongoDBポッドを指定することをお勧めします。
この場合、StorageClassはポッドとDigitalOceanブロックストレージサービス間のインターフェイスとして機能します。 ブロックストレージのボリュームを要求すると、StorageClassは、ブロックストレージボリュームの割り当て方法を知っている事前構成されたドライバーと通信します。
StackPointCloudは、DigitalOceanストレージドライバーをインストールし、セットアップ中にStorageClassをKubernetesに登録します。 これにより、ドライバーとStorageClassのインストールと構成に関連する手順を省くことができます。
MongoDBクラスターをデプロイする前に、DigitalOceanボリュームのStorageClassが構成されていることを確認しましょう。
- kubectl get storageclass
出力は、StorageClassが構成されて準備ができていることを確認します。
[secondary_label Output
NAME PROVISIONER AGE
digitalocean (default) digitalocean/flex-volume-provisioner 1d
次に、DigitalOceanStorageClassに基づいてMongoDBReplicaSetを構成してデプロイします。
プロジェクトの新しいディレクトリを作成し、新しいディレクトリに切り替えます。
- mkdir ~/mongo-rs
- cd ~/mongo-rs
GitHubからHelmChartリポジトリのクローンを作成します。
- git clone https://github.com/kubernetes/charts.git
MongoDB ReplicaSetディレクトリに移動します(charts/stable/mongodb-replicaset/
)ファイルを確認します values.yaml
存在します。
- cd charts/stable/mongodb-replicaset/
- ls values.yaml
Outputvalues.yaml
このファイルには、チャートのパラメーターと構成が含まれています。 DigitalOceanStorageClassを使用するようにMongoDBReplicaSetを構成するには、このファイルを変更する必要があります。
編集 values.yaml
:
- nano values.yaml
次のセクションを見つけてコメントを外します。
...
# storageClass: "-"
...
交換 "-"
と "digitalocean"
、 このような:
...
storageClass: "digitalocean"
...
ファイルを保存して、エディターを終了します。
次に、に移動します ~/mongo-rs
フォルダ。
- cd ~/mongo-rs
これで、DigitalOceanのブロックストレージを利用して、MongoDBReplicaSetをKubernetesクラスターにデプロイする準備が整いました。 次のコマンドを実行して、データベースクラスターを起動します。
- helm install --name=todo -f charts/stable/mongodb-replicaset/values.yaml stable/mongodb-replicaset
上記のコマンドでは、 --name
ヘルムチャートの名前を指します。 スイッチ -f
に保存されている構成設定を指します values.yaml
.
チャートの作成が開始されたことを確認する出力がすぐに表示されます。
OutputNAME: todo
LAST DEPLOYED: Sat Mar 31 10:37:06 2018
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
todo-mongodb-replicaset ClusterIP None <none> 27017/TCP 1s
==> v1beta1/StatefulSet
NAME DESIRED CURRENT AGE
todo-mongodb-replicaset 3 1 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
todo-mongodb-replicaset-0 0/1 Init:0/2 0 0s
==> v1/ConfigMap
NAME DATA AGE
todo-mongodb-replicaset 1 1s
todo-mongodb-replicaset-tests 1 1s
NOTES:
1. After the statefulset is created completely, one can check which instance is primary by running:
$ for ((i = 0; i < 3; ++i)); do kubectl exec --namespace default todo-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; done
2. One can insert a key into the primary instance of the mongodb replica set by running the following:
MASTER_POD_NAME must be replaced with the name of the master found from the previous step.
$ kubectl exec --namespace default MASTER_POD_NAME -- mongo --eval="printjson(db.test.insert({key1: 'value1'}))"
3. One can fetch the keys stored in the primary or any of the slave nodes in the following manner.
POD_NAME must be replaced by the name of the pod being queried.
$ kubectl exec --namespace default POD_NAME -- mongo --eval="rs.slaveOk(); db.test.find().forEach(printjson)"
次に、一連のコマンドを実行して、クラスターのステータスを追跡しましょう。
まず、StatefulSetを見てください。
- kubectl get statefulset
このコマンドは、MongoDBReplicaSetがKubernetesStatefulSetとして作成されたことを確認します。
OutputNAME DESIRED CURRENT AGE
todo-mongodb-replicaset 3 2 2m
次に、ポッドを探索します。
- kubectl get pods
ポッドの数とその命名規則は、MongoDBReplicaSetが正常に構成されていることを示しています。
OutputNAME READY STATUS RESTARTS AGE
todo-mongodb-replicaset-0 1/1 Running 0 3m
todo-mongodb-replicaset-1 1/1 Running 0 1m
todo-mongodb-replicaset-2 1/1 Running 0 54s
各ポッドには、StatefulSetの特徴的な機能である連番で終わる接尾辞があることに注意してください。
次に、MongoDBインスタンスが相互に通信しているかどうかを確認しましょう。 これを行うには、ポッドの1つにあるMongoDBシェルでコマンドを実行します。
使用する kubectl
を起動するには mongo
ホストの1つでコンソール:
- kubectl exec -it todo-mongodb-replicaset-0 mongo
接続すると、MongoDBシェルが表示されます。
OutputMongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
Welcome to the MongoDB shell.
For interactive help, type "help".
...
2018-03-31T05:08:20.239+0000 I CONTROL [initandlisten]
次のコマンドを使用して、ReplicaSetの構成を確認します。
- rs.conf()
出力は、ReplicaSetとして実行されているMongoDBの3つのインスタンスがあることを確認します。
Output{
"_id" : "rs0",
"version" : 3,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "todo-mongodb-replicaset-0.todo-mongodb-replicaset.default.svc.cluster.local:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "todo-mongodb-replicaset-1.todo-mongodb-replicaset.default.svc.cluster.local:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "todo-mongodb-replicaset-2.todo-mongodb-replicaset.default.svc.cluster.local:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5abdb4f61d952afc4b0b8218")
}
}
MongoDBコンソールを終了します。
- exit
これにより、リモートホストからも切断されます。
ギアを切り替えて、DigitalOceanコントロールパネルでクラスターに関連付けられているブロックストレージボリュームを確認しましょう。 DigitalOceanアカウントにログインし、Volumesタブを選択します。
それぞれ10GBの3つのボリュームがKubernetesワーカーノードに接続されていることがわかります。 MongoDB StatefulSetの各ポッドは、ブロックストレージボリュームの1つにデータを保存しています。 10GBのサイズはで定義されています values.yaml
下 persistentVolume
セクション。
persistentVolume:
enabled: true
## mongodb-replicaset data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
storageClass: digitalocean
accessModes:
- ReadWriteOnce
size: 10Gi
annotations: {}
これで、Kubernetesで実行される可用性の高いMongoDBReplicaSetが正常に構成されました。
次に、MongoDBクラスターと通信するWebアプリケーションをデプロイしましょう。
ステップ3–KubernetesでのWebアプリケーションのデプロイとスケーリング
このチュートリアルシリーズの前の部分で使用したToDoNode.jsアプリケーションを拡張して、MongoDBクラスターを利用してみましょう。
注:ソースコードからコンテナイメージをビルドしたり、KubernetesファイルのYAMLファイルを直接使用したりすることもできます。 イメージをビルドしてアプリケーションをKubernetesにデプロイする手順については、チュートリアルKubernetesでのマイクロサービスのデプロイとスケーリングを参照してください。
新しい作業ディレクトリを作成することから始めます。
- mkdir ~/web-app
- cd ~/web-app
次に、コードとKubernetesアーティファクトを含むToDoアプリケーションのリポジトリのクローンを作成します。
- git clone https://github.com/janakiramm/todo.git
に切り替えます todo-app/kubernetes
Kubernetes構成ファイルを含むディレクトリ。
- cd todo-app/kubernetes
ファイルを開く web-rs-ss.yaml
エディターで。
- nano web-rs-ss.yaml
に注意してください env
YAMLファイルのセクション。
containers:
- name: web
image: janakiramm/todo
env:
- name: "DBHOST"
value: "mongodb://todo-mongodb-replicaset-0.todo-mongodb-replicaset,todo-mongodb-replicaset-1.todo-mongodb-replicaset,todo-mongodb-replicaset-2.todo-mongodb-replicaset:27017"
ports:
- containerPort: 3000
これにより、データベース接続文字列が実行時に環境変数としてアプリケーションに渡されます。 このバージョンのアプリは、アプリケーションを単純なMongoDBポッドにポイントする代わりに、作成したStatefulSetを使用します。 の各エントリ value
セクションは、MongoDBStatefulSetのポッドの1つを参照します。
使用する kubectl
を展開するには web
と一緒にReplicaSet web
サービス
- kubectl create -f web-rs-ss.yaml -f web-service.yaml
両方が作成されていることがわかります。
Outputreplicaset "web" created
service "web" created
ポッドを再度リストします。
- kubectl get pods
これで、MongoDBとWebアプリに属するすべてのポッドが表示されます。
OutputNAME READY STATUS RESTARTS AGE
todo-mongodb-replicaset-0 1/1 Running 0 26m
todo-mongodb-replicaset-1 1/1 Running 0 24m
todo-mongodb-replicaset-2 1/1 Running 0 23m
web-t5zzk 1/1 Running 0 17s
web-x6dh8 1/1 Running 0 17s
Let’s check out the Kubernetes services
```command
kubectl get svc
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.3.0.1 <none> 443/TCP 1d
todo-mongodb-replicaset ClusterIP None <none> 27017/TCP 27m
web NodePort 10.3.0.167 <none> 3000:31201/TCP 14s
The web
ポッドは、 todo-mongodb-replicaset
サービス。 Webアプリケーションは、 web
NodePortのサービス 31201
.
いずれかのワーカーノードでこのポートにアクセスすると、Webアプリケーションが表示されます。
ReplicaSet内のポッドの数を増やすことで、Webアプリケーションをスケーリングできます。
- kubectl scale rs/web --replicas=10
Outputreplicaset "web" scaled
その後、アプリケーションを2つのポッドにスケールバックできます。
- kubectl scale rs/web --replicas=2
Outputreplicaset "web" scaled
それでは、可用性についていくつかのテストを実行してみましょう。
ステップ4–高可用性についてMongoDBReplicaSetをテストする
StatefulSetを実行する利点の1つは、ワークロードの高可用性です。 MongoDB StatefulSetのポッドの1つを削除して、これをテストしてみましょう。
- kubectl delete pod todo-mongodb-replicaset-2
Outputpod "todo-mongodb-replicaset-2" deleted
ポッドの数を確認します。
- kubectl get pods
あなたはそれを見るでしょう todo-mongodb-replicaset-2
終了しています:
OutputNAME READY STATUS RESTARTS AGE
todo-mongodb-replicaset-0 1/1 Running 0 33m
todo-mongodb-replicaset-1 1/1 Running 0 32m
todo-mongodb-replicaset-2 0/1 Terminating 0 31m
web-t5zzk 1/1 Running 0 8m
web-x6dh8 1/1 Running 0 8m
数分以内に、Kubernetesが別のポッドを初期化して削除されたポッドを置き換えることがわかります。
- kubectl get pods
わかるでしょ todo-mongodb-replicaset-2
初期化中:
NAME READY STATUS RESTARTS AGE
todo-mongodb-replicaset-0 1/1 Running 0 34m
todo-mongodb-replicaset-1 1/1 Running 0 33m
todo-mongodb-replicaset-2 0/1 Init:0/2 0 29s
web-t5zzk 1/1 Running 0 8m
web-x6dh8 1/1 Running 0 8m
すべてが機能することがわかったので、物事をクリーンアップできます。
次のコマンドを使用して、このチュートリアル中に作成されたすべてのオブジェクトを削除します。
- helm delete --purge todo
- kubectl delete -f web-rs-ss.yaml -f web-service.yaml
Outputreplicaset "web" deleted
service "web" deleted
Kubernetesクラスタ自体を削除するには、StackPointCloudにアクセスし、コントロールパネルから削除します。
結論
このチュートリアルでは、耐久性があり、永続的で、可用性の高いMonogDBReplicaSetをKubernetesStatefulSetとしてデプロイしました。 また、同じKubernetesクラスターにデプロイされた他のアプリケーションからStatefulSetにアクセスする方法も学びました。