前書き
Kubernetesは、コンテナ化されたアプリケーションを管理するためのオープンソースのコンテナオーケストレーションツールです。 このシリーズの前のパートでは、KubernetesのビルディングブロックとパッケージコンテナーをKubernetes ReplicaSetとして学習しました。 ReplicaSetはステートレスポッドの可用性を保証しますが、データベースクラスターなどのステートフルワークロードでは使用できません。
Kubernetesの現代的なクラウドネイティブアプリケーションのパッケージ化、デプロイ、管理、およびスケーリングは簡単ですが、コンテナー化された環境でデータベースやコンテンツ管理システムなどの従来のワークロードをデプロイおよび管理するには、異なるアプローチが必要です。 StatefulSetsは、Kubernetes ReplicaSetの柔軟性をステートフルワークロードにもたらします。
このチュートリアルシリーズの最終回では、Kubernetesの一般的なオープンソースパッケージマネージャーであるhttps://helm.sh/[Helm]を使用して、可用性の高いMongoDB ReplicaSetをStatefulSetとしてKubernetesにデプロイします。
前提条件
このチュートリアルを完了するには、次のものが必要です。
-
StackPointCloudを介してインストールされたDigitalOceanで実行されているアクティブなKubernetesクラスター。チュートリアルhttps://www.digitalocean.com/community/tutorials/webinar-series-getting- started-with-kubernetes [Kubernetesスタートガイド]。
-
チュートリアルhttps://www.digitalocean.com/community/tutorials/webinar-series-deploying-and-scaling-microservices-in-kubernetes[Kubernetesでのマイクロサービスのデプロイとスケーリング]で紹介されているサンプルWebアプリケーションNode.jsとMongoDBは、データベースの高可用性を実現するために拡張されています。 アプリケーション設計の詳細については、https://www.digitalocean.com/community/tutorials/webinar-series-building-containerized-applications [コンテナ化されたアプリケーションの構築]チュートリアルを参照してください。
-
アプリケーションのDockerイメージを保存するアクティブなhttps://hub.docker.com/[Docker Hub]アカウント。
-
Gitがインストールされたローカルマシン
-
macOSを使用している場合は、https://brew.sh/ [Homebrew]がインストールされていることを確認してください。
ステップ1 –開発マシンへのHelmクライアントのインストール
Helmを使用すると、管理者は1つのコマンドで複雑なKubernetesアプリケーションを展開できます。 アプリケーションは、Kubernetesアプリケーションを定義、インストール、およびアップグレードするhttps://github.com/kubernetes/charts[Charts]としてパッケージ化されています。 チャートは、ポッド、デプロイメント、サービスなどのKubernetesオブジェクトの抽象化を提供します。
Helmには、サーバーとクライアントの2つのコンポーネントがあります。 Helmのサーバー側は、Tillerと呼ばれるサービスとしてKubernetesで実行されます。 クライアントは、Tillerと対話するコマンドラインツールです。
MongoDB ReplicaSet Helm Chartをデプロイするため、Helmのサーバー側コンポーネントであるTillerと通信するCLIが必要です。 DigitalOceanでKubernetesをセットアップするために使用したStackPointCloudには、Tillerがプリインストールされています。
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 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を使用してMongoDB ReplicaSetをKubernetesにデプロイします。
ステップ2 – KubernetesでのMongoDB ReplicaSetの展開
KubernetesのStorageClassは、管理者が提供するストレージの「クラス」を記述する方法を提供します。 たとえば、ユーザーがストレージボリュームを要求すると、StorageClassはユーザーからプロビジョニングされるストレージバックエンドのクラスを決定します。 クラスには、標準HDDと高速SSDが含まれる場合があります。 背後では、StorageClassはクラウドプロバイダーのAPIなどの基盤となるインフラストラクチャと対話して、ストレージをプロビジョニングします。
MongoDBデータを保存するには永続ストレージが必要なので、DigitalOceanブロックストレージボリュームをワーカーノードに接続し、MongoDBポッドが永続性のためにストレージボリュームを使用するようにポイントすることができます。
この場合、StorageClassはPodとDigitalOceanブロックストレージサービス間のインターフェイスとして機能します。 ブロックストレージのボリュームを要求すると、StorageClassは、ブロックストレージボリュームの割り当て方法を知っている事前構成済みのドライバーと通信します。
StackPointCloudは、セットアップ中にDigitalOceanストレージドライバーをインストールし、KubernetesにStorageClassを登録します。 これにより、ドライバーとStorageClassのインストールと構成に必要な手順が不要になります。
MongoDBクラスターを展開する前に、DigitalOceanボリュームのStorageClassが構成されていることを確認しましょう。
kubectl get storageclass
出力は、StorageClassが構成され準備が整っていることを確認します。
[secondary_label Output
NAME PROVISIONER AGE
digitalocean (default) digitalocean/flex-volume-provisioner 1d
次に、DigitalOcean StorageClassに基づいてMongoDB ReplicaSetを構成および展開します。
プロジェクトの新しいディレクトリを作成し、新しいディレクトリに切り替えます。
mkdir ~/mongo-rs
cd ~/mongo-rs
GitHubからHelm Chartリポジトリを複製します。
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
このファイルには、チャートのパラメーターと構成が含まれています。 DigitalOcean StorageClassを使用するようにMongoDB ReplicaSetを構成するには、このファイルを変更する必要があります。
`+ values.yaml +`を編集します:
nano values.yaml
次のセクションを見つけてコメント解除します。
values.yaml
...
# storageClass: "-"
...
次のように、 `"-"`を `" digitalocean "`に置き換えます。
values.yaml
...
storageClass:
...
ファイルを保存して、エディターを終了します。
次に、 `+〜/ mongo-rs +`フォルダーに移動します。
cd ~/mongo-rs
これで、DigitalOceanのブロックストレージを利用して、MongoDB ReplicaSetをKubernetesクラスターに展開する準備が整いました。 次のコマンドを実行して、データベースクラスターを起動します。
helm install --name= -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:
RESOURCES:
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ClusterIP None <none> 27017/TCP 1s
==> v1beta1/StatefulSet
NAME DESIRED CURRENT AGE
3 1 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
0/1 Init:0/2 0 0s
==> v1/ConfigMap
NAME DATA AGE
1 1s
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
このコマンドは、MongoDB ReplicaSetがKubernetes StatefulSetとして作成されたことを確認します。
OutputNAME DESIRED CURRENT AGE
3 2 2m
次に、ポッドを探索します。
kubectl get pods
ポッドの数とその命名規則は、MongoDB ReplicaSetが正常に構成されていることを示しています。
OutputNAME READY STATUS RESTARTS AGE
1/1 Running 0 3m
1/1 Running 0 1m
1/1 Running 0 54s
各Podには、連続番号で終わるサフィックスがあります。これは、StatefulSetの特徴的な機能です。
次に、MongoDBインスタンスが相互に通信しているかどうかを確認します。 これを行うには、いずれかのPod内のMongoDBシェルでコマンドを実行します。
ホストの1つで + mongo`コンソールを起動するには、
+ kubectl`を使用します。
kubectl exec -it 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()
出力は、MongoDBの3つのインスタンスがReplicaSetとして実行されていることを確認します。
Output{
"_id" : "rs0",
"version" : 3,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : ",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "",
"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 *タブを選択します。
image:https://assets.digitalocean.com/articles/webinar_6_stateful_services/IcNUFQb.jpg [ボリュームを表示するダッシュボード]
それぞれ10GBの3つのボリュームがKubernetesワーカーノードに接続されていることがわかります。 MongoDB StatefulSetの各Podは、ブロックストレージボリュームの1つにデータを格納しています。 10GBのサイズは、「+ persistentVolume 」セクションの下の「 values.yaml +」で定義されます。
values.yaml
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
annotations: {}
Kubernetesで実行される高可用性MongoDB ReplicaSetを正常に構成しました。
次に、MongoDBクラスターと通信するWebアプリケーションをデプロイしましょう。
ステップ3 – KubernetesでのWebアプリケーションの展開とスケーリング
このチュートリアルシリーズの前のパートで使用したToDo Node.jsアプリケーションを拡張して、MongoDBクラスターを活用しましょう。
新しい作業ディレクトリを作成することから始めます。
mkdir ~/web-app
cd ~/web-app
次に、コードとKubernetesアーティファクトを含むToDoアプリケーションのリポジトリを複製します。
git clone https://github.com/janakiramm/todo.git
Kubernetes設定ファイルが含まれる `+ todo-app / kubernetes +`ディレクトリに切り替えます。
cd todo-app/kubernetes
エディターでファイル `+ web-rs-ss.yaml +`を開きます。
nano web-rs-ss.yaml
YAMLファイルの `+ env +`セクションに注意してください。
web-rs-ss.yaml
containers:
- name: web
image: janakiramm/todo
ports:
- containerPort: 3000
これにより、実行時にデータベース接続文字列が環境変数としてアプリケーションに渡されます。 アプリケーションを単純なMongoDBポッドにポイントする代わりに、このバージョンのアプリは作成したStatefulSetを使用します。 `+ value +`セクションの各エントリは、MongoDB StatefulSetのポッドの1つを参照します。
+ web +`サービスとともに `+ web +
ReplicaSetをデプロイするには、 `+ kubectl +`を使用します
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
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 `ポッドは、 ` todo-mongodb-replicaset `サービスを通じてMongoDBクラスターと通信します。 Webアプリケーションは、NodePortの「 web 」サービス「+31201」から利用できます。
任意のワーカーノードでこのポートにアクセスすると、Webアプリケーションが表示されます。
image:https://assets.digitalocean.com/articles/webinar_6_stateful_services/b6yZ4sD.jpg [ライブTodoリストアプリ]
ReplicaSetのPodの数を増やすことで、Webアプリケーションをスケーリングできます。
kubectl scale rs/web --replicas=10
Outputreplicaset "web" scaled
その後、アプリケーションを2つのポッドにスケールバックできます。
kubectl scale rs/web --replicas=2
Outputreplicaset "web" scaled
それでは、可用性についていくつかのテストを実行しましょう。
ステップ4 –高可用性のためのMongoDB ReplicaSetのテスト
StatefulSetを実行する利点の1つは、ワークロードの高可用性です。 MongoDB StatefulSetのポッドの1つを削除して、これをテストしてみましょう。
kubectl delete pod todo-mongodb-replicaset-2
Outputpod "todo-mongodb-replicaset-2" deleted
ポッドの数を確認します。
kubectl get pods
`+ todo-mongodb-replica set-2 +`が終了していることがわかります。
OutputNAME READY STATUS RESTARTS AGE
todo-mongodb-replicaset-0 1/1 Running 0 33m
todo-mongodb-replicaset-1 1/1 Running 0 32m
web-t5zzk 1/1 Running 0 8m
web-x6dh8 1/1 Running 0 8m
数分以内に、Kubernetesが別のポッドを初期化して、削除されたポッドを置き換えることがわかります。
kubectl get pods
「+ todo-mongodb-replica set-2 +」が初期化されているのがわかります。
NAME READY STATUS RESTARTS AGE
todo-mongodb-replicaset-0 1/1 Running 0 34m
todo-mongodb-replicaset-1 1/1 Running 0 33m
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にアクセスし、コントロールパネルから削除します。
結論
このチュートリアルでは、永続的で永続的で可用性の高いMongoDBレプリカセットをKubernetes StatefulSetとしてデプロイしました。 また、同じKubernetesクラスターにデプロイされた他のアプリケーションからStatefulSetにアクセスする方法も学びました。