ウェビナーシリーズ:Kubernetesでのステートフルサービスの展開

前書き

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にアクセスする方法も学びました。

Related