Helmを使用してKubernetesでMongoDBを使用してNode.jsアプリケーションをスケーリングする方法
序章
Kubernetes は、最新のコンテナ化されたアプリケーションを大規模に実行するためのシステムです。 これにより、開発者はマシンのクラスター全体にアプリケーションを展開および管理できます。 また、単一インスタンスのアプリケーションセットアップで効率と信頼性を向上させるために使用できますが、Kubernetesは、マシンのグループ間でアプリケーションの複数のインスタンスを実行するように設計されています。
Kubernetesを使用してマルチサービスデプロイメントを作成する場合、多くの開発者はHelmパッケージマネージャーを使用することを選択します。 Helmは、これらのオブジェクトの相互作用を調整するチャートとテンプレートを提供することにより、複数のKubernetesリソースを作成するプロセスを合理化します。 また、人気のあるオープンソースプロジェクト用にパッケージ化されたチャートも提供しています。
このチュートリアルでは、Helmチャートを使用して、MongoDBデータベースを備えたNode.jsアプリケーションをKubernetesクラスターにデプロイします。 公式HelmMongoDBレプリカセットチャートを使用して、3つのポッド、ヘッドレスサービス、および3つのStatefulSetオブジェクトを作成します。 PersistentVolumeClaims。 また、カスタムアプリケーションイメージを使用してマルチレプリカNode.jsアプリケーションをデプロイするためのグラフを作成します。 このチュートリアルで構築するセットアップは、 Docker Compose を使用したNode.jsアプリケーションのコンテナー化で説明されているコードの機能を反映し、MongoDBを使用して復元力のあるNode.jsアプリケーションを構築するための良い出発点になります。ニーズに合わせて拡張できるデータストア。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- ロールベースのアクセス制御(RBAC)が有効になっているKubernetes1.10+クラスター。 このセットアップではDigitalOceanKubernetesクラスターを使用しますが、別の方法を使用してクラスターを自由に作成できます。
kubectl
コマンドラインツールがローカルマシンまたは開発サーバーにインストールされ、クラスターに接続するように構成されています。kubectl
のインストールの詳細については、公式ドキュメントを参照してください。- Helm Package Manager を使用してKubernetesクラスターにソフトウェアをインストールする方法の手順1と2に概説されている手順に従って、ローカルマシンまたは開発サーバーにHelmをインストールし、クラスターにTillerをインストールします。
- Dockerがローカルマシンまたは開発サーバーにインストールされています。 Ubuntu 18.04を使用している場合は、 Ubuntu18.04にDockerをインストールして使用する方法の手順1と2に従ってください。 それ以外の場合は、他のオペレーティングシステムへのインストールについて、公式ドキュメントに従ってください。 リンクされたチュートリアルのステップ2で説明されているように、root以外のユーザーを
docker
グループに必ず追加してください。 - DockerHubアカウント。 これを設定する方法の概要については、DockerHubのこの紹介を参照してください。
ステップ1—アプリケーションのクローン作成とパッケージ化
アプリケーションをKubernetesで使用するには、kubeletエージェントがイメージをプルできるようにアプリケーションをパッケージ化する必要があります。 ただし、アプリケーションをパッケージ化する前に、アプリケーションコードのMongoDB接続URIを変更して、Helmmongodb-replicaset
チャート。
最初のステップは、 DigitalOceanCommunityGitHubアカウントからnode-mongo-docker-devリポジトリのクローンを作成することです。 このリポジトリには、DockerComposeを使用した開発用のNode.jsアプリケーションのコンテナ化で説明されているセットアップのコードが含まれています。 DockerCompose。 アプリケーション自体の詳細については、Node.jsを使用したコンテナーからKubernetesへのシリーズを参照してください。
リポジトリをnode_project
というディレクトリに複製します。
git clone https://github.com/do-community/node-mongo-docker-dev.git node_project
node_project
ディレクトリに移動します。
cd node_project
node_project
ディレクトリには、ユーザー入力で動作するサメ情報アプリケーションのファイルとディレクトリが含まれています。 コンテナーで動作するように最新化されました。機密性の高い特定の構成情報がアプリケーションコードから削除され、実行時に注入されるようにリファクタリングされ、アプリケーションの状態がMongoDBデータベースにオフロードされました。
最新のコンテナ化されたアプリケーションの設計の詳細については、Kubernetes用アプリケーションのアーキテクチャおよびKubernetes用アプリケーションの最新化を参照してください。
Helm mongodb-replicaset
チャートを展開すると、次のようになります。
- 3つのポッドを持つStatefulSetオブジェクト—MongoDBレプリカセットのメンバー。 各ポッドには、関連付けられたPersistentVolumeClaimがあり、スケジュールが変更された場合でも固定IDを維持します。
- StatefulSetのポッドで構成されるMongoDBレプリカセット。 セットには、1つのプライマリと2つのセカンダリが含まれます。 データはプライマリからセカンダリに複製され、アプリケーションデータの高可用性を維持します。
アプリケーションがデータベースレプリカと対話するには、コード内のMongoDB接続URIに、レプリカセットメンバーのホスト名とレプリカセット自体の名前の両方を含める必要があります。 したがって、これらの値をURIに含める必要があります。
データベース接続情報を指定するクローンリポジトリ内のファイルは、db.js
と呼ばれます。 nano
またはお気に入りのエディターを使用して、そのファイルを今すぐ開きます。
nano db.js
現在、ファイルには、実行時にデータベース接続URIで参照される定数が含まれています。 これらの定数の値は、ノードの process.env プロパティを使用して挿入されます。このプロパティは、実行時にユーザー環境に関する情報を含むオブジェクトを返します。 アプリケーションコードで動的に値を設定すると、動的なステートレス環境で必要な、基盤となるインフラストラクチャからコードを切り離すことができます。 この方法でのアプリケーションコードのリファクタリングの詳細については、DockerComposeを使用した開発用のNode.jsアプリケーションのコンテナ化のステップ2および12ファクターの関連する説明を参照してください。 App。
接続URIとURI文字列自体の定数は、現在次のようになっています。
〜/ node_project / db.js
... const { MONGO_USERNAME, MONGO_PASSWORD, MONGO_HOSTNAME, MONGO_PORT, MONGO_DB } = process.env; ... const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`; ...
12FAのアプローチに従い、レプリカインスタンスのホスト名またはレプリカセット名をこのURI文字列にハードコーディングする必要はありません。 既存のMONGO_HOSTNAME
定数を拡張して、複数のホスト名(レプリカセットのメンバー)を含めることができるため、そのままにしておきます。 ただし、URI文字列のオプションセクションにレプリカセット定数を追加する必要があります。
MONGO_REPLICASET
をURI定数オブジェクトと接続文字列の両方に追加します。
〜/ node_project / db.js
... const { MONGO_USERNAME, MONGO_PASSWORD, MONGO_HOSTNAME, MONGO_PORT, MONGO_DB, MONGO_REPLICASET } = process.env; ... const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?replicaSet=${MONGO_REPLICASET}&authSource=admin`; ...
URIのオプションセクションでreplicaSetオプションを使用すると、レプリカセットの名前を渡すことができます。これにより、MONGO_HOSTNAME
定数で定義されたホスト名とともに、次のことが可能になります。セットメンバーに接続します。
編集が終了したら、ファイルを保存して閉じます。
レプリカセットで機能するようにデータベース接続情報を変更すると、アプリケーションをパッケージ化し、 docker build コマンドを使用してイメージをビルドし、DockerHubにプッシュできるようになります。
docker build
と-t
フラグを使用してイメージを作成します。これにより、イメージに覚えやすい名前を付けることができます。 この場合、イメージにDocker Hubユーザー名のタグを付け、node-replicas
または自分で選択した名前を付けます。
docker build -t your_dockerhub_username/node-replicas .
コマンドの.
は、ビルドコンテキストが現在のディレクトリであることを指定します。
イメージの作成には1〜2分かかります。 完了したら、画像を確認します。
docker images
次の出力が表示されます。
OutputREPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/node-replicas latest 56a69b4bc882 7 seconds ago 90.1MB node 10-alpine aa57b0242b33 6 days ago 71MB
次に、前提条件で作成したDockerHubアカウントにログインします。
docker login -u your_dockerhub_username
プロンプトが表示されたら、DockerHubアカウントのパスワードを入力します。 この方法でログインすると、ルート以外のユーザーのホームディレクトリにDockerHubの資格情報を使用して~/.docker/config.json
ファイルが作成されます。
dockerpushコマンドを使用してアプリケーションイメージをDockerHubにプッシュします。 your_dockerhub_username
を独自のDockerHubユーザー名に置き換えることを忘れないでください。
docker push your_dockerhub_username/node-replicas
これで、Kubernetesでレプリケートされたアプリケーションを実行するためにプルできるアプリケーションイメージができました。 次のステップは、MongoDBHelmチャートで使用する特定のパラメーターを構成することです。
ステップ2—MongoDBレプリカセットのシークレットを作成する
stable/mongodb-replicaset
チャートは、シークレットの使用に関してさまざまなオプションを提供します。チャートの展開で使用する2つを作成します。
- レプリカセットキーファイルのシークレット。レプリカセットメンバー間で共有パスワードとして機能し、他のメンバーを認証できるようにします。
admin
データベースにrootユーザーとして作成されるMongoDB管理者ユーザーの秘密。 この役割により、アプリケーションを本番環境にデプロイするときに、権限が制限された後続のユーザーを作成できます。
これらのシークレットを設定すると、専用の値ファイルに優先パラメーター値を設定し、Helmチャートを使用してStatefulSetオブジェクトとMongoDBレプリカセットを作成できるようになります。
まず、キーファイルを作成しましょう。 opensslコマンドとrand
オプションを使用して、キーファイルの756バイトのランダムな文字列を生成します。
openssl rand -base64 756 > key.txt
コマンドによって生成される出力は、 base64 でエンコードされ、均一なデータ送信を保証し、 mongodb-replicasetチャート認証ドキュメントに記載されているガイドラインに従って、key.txt
というファイルにリダイレクトされます。 。 キー自体は、6〜1024文字の長さで、base64セットの文字のみで構成されている必要があります。
これで、 kubectl create でこのファイルを使用して、keyfilesecret
というシークレットを作成できます。
kubectl create secret generic keyfilesecret --from-file=key.txt
これにより、default
namespace にシークレットオブジェクトが作成されます。これは、セットアップ用の特定の名前空間を作成していないためです。
シークレットが作成されたことを示す次の出力が表示されます。
Outputsecret/keyfilesecret created
key.txt
を削除します:
rm key.txt
または、ファイルを保存する場合は、必ずアクセス許可を制限し、.gitignoreファイルに追加してバージョン管理されないようにしてください。
次に、MongoDB管理者ユーザーのシークレットを作成します。 最初のステップは、希望するユーザー名とパスワードをbase64に変換することです。
データベースのユーザー名を変換します。
echo -n 'your_database_username' | base64
出力に表示される値を書き留めます。
次に、パスワードを変換します。
echo -n 'your_database_password' | base64
ここでも出力の値に注意してください。
シークレットのファイルを開きます。
nano secret.yaml
注:Kubernetesオブジェクトは通常でYAML を使用して定義されます。これはタブを厳密に禁止し、インデントに2つのスペースを必要とします。 YAMLファイルのフォーマットを確認したい場合は、 linter を使用するか、kubectl create
と--dry-run
および[ X174X] フラグ:
kubectl create -f your_yaml_file.yaml --dry-run --validate=true
一般に、kubectl
を使用してリソースを作成する前に、構文を検証することをお勧めします。
次のコードをファイルに追加して、作成したエンコード値でuser
とpassword
を定義するシークレットを作成します。 ここのダミー値は、必ず独自のエンコードされたユーザー名とパスワードに置き換えてください。
〜/ node_project / secret.yaml
apiVersion: v1 kind: Secret metadata: name: mongo-secret data: user: your_encoded_username password: your_encoded_password
ここでは、mongodb-replicaset
チャートが期待するキー名user
およびpassword
を使用しています。 シークレットオブジェクトにはmongo-secret
という名前を付けましたが、好きな名前を付けることができます。
編集が終了したら、ファイルを保存して閉じます。
次のコマンドを使用してSecretオブジェクトを作成します。
kubectl create -f secret.yaml
次の出力が表示されます。
Outputsecret/mongo-secret created
ここでも、secret.yaml
を削除するか、そのアクセス許可を制限して.gitignore
ファイルに追加することができます。
シークレットオブジェクトを作成したら、mongodb-replicaset
チャートで使用するパラメーター値の指定とMongoDBデプロイメントの作成に進むことができます。
ステップ3—MongoDBヘルムチャートの構成とデプロイメントの作成
Helmには、使用するチャートmongodb-replicaset
を含むstableと呼ばれるアクティブに保守されているリポジトリが付属しています。 作成したシークレットでこのチャートを使用するには、mongodb-values.yaml
という構成パラメーター値を使用してファイルを作成し、このファイルを使用してチャートをインストールします。
mongodb-values.yaml
ファイルは、mongodb-replicaset
チャートリポジトリのデフォルトのvalues.yamlファイルをほぼ反映します。 ただし、ファイルには次の変更を加えます。
auth
パラメーターをtrue
に設定して、データベースインスタンスが認証を有効で開始するようにします。 これは、すべてのクライアントがデータベースのリソースと操作にアクセスするために認証する必要があることを意味します。- 前のステップで作成したシークレットに関する情報を追加して、チャートがこれらの値を使用してレプリカセットのキーファイルと管理者ユーザーを作成できるようにします。
- StatefulSetの各ポッドに関連付けられているPersistentVolumeのサイズを小さくして、最小実行可能DigitalOceanブロックストレージユニット、1GBを使用しますが、ストレージ要件に合わせてこれを自由に変更できます。
ただし、mongodb-values.yaml
ファイルを作成する前に、まず StorageClass が作成され、ストレージリソースをプロビジョニングするように構成されていることを確認する必要があります。 データベースStatefulSet内の各ポッドには、スティッキーIDと関連する PersistentVolumeClaim があり、ポッドのPersistentVolumeを動的にプロビジョニングします。 ポッドが再スケジュールされた場合、PersistentVolumeは、ポッドがスケジュールされているノードにマウントされます(ただし、関連付けられたポッドまたはStatefulSetが完全に削除される場合は、各ボリュームを手動で削除する必要があります)。
DigitalOcean Kubernetes を使用しているため、デフォルトのStorageClassprovisioner
はdobs.csi.digitalocean.com
— DigitalOcean Block Storage —に設定されています。
kubectl get storageclass
DigitalOceanクラスターを使用している場合は、次の出力が表示されます。
OutputNAME PROVISIONER AGE do-block-storage (default) dobs.csi.digitalocean.com 21m
DigitalOceanクラスターを使用していない場合は、StorageClassを作成し、選択したprovisioner
を構成する必要があります。 これを行う方法の詳細については、公式ドキュメントを参照してください。
StorageClassが構成されていることを確認したので、mongodb-values.yaml
を開いて編集します。
nano mongodb-values.yaml
このファイルには、次のような値を設定します。
- 承認を有効にします。
keyfilesecret
およびmongo-secret
オブジェクトを参照します。- PersistentVolumesに
1Gi
を指定します。 - レプリカセット名を
db
に設定します。 - セットの
3
レプリカを指定します。 mongo
イメージを、執筆時点で最新バージョン4.1.9
に固定します。
次のコードをファイルに貼り付けます。
〜/ node_project / mongodb-values.yaml
replicas: 3 port: 27017 replicaSetName: db podDisruptionBudget: {} auth: enabled: true existingKeySecret: keyfilesecret existingAdminSecret: mongo-secret imagePullSecrets: [] installImage: repository: unguiculus/mongodb-install tag: 0.7 pullPolicy: Always copyConfigImage: repository: busybox tag: 1.29.3 pullPolicy: Always image: repository: mongo tag: 4.1.9 pullPolicy: Always extraVars: {} metrics: enabled: false image: repository: ssalaues/mongodb-exporter tag: 0.6.1 pullPolicy: IfNotPresent port: 9216 path: /metrics socketTimeout: 3s syncTimeout: 1m prometheusServiceDiscovery: true resources: {} podAnnotations: {} securityContext: enabled: true runAsUser: 999 fsGroup: 999 runAsNonRoot: true init: resources: {} timeout: 900 resources: {} nodeSelector: {} affinity: {} tolerations: [] extraLabels: {} persistentVolume: enabled: true #storageClass: "-" accessModes: - ReadWriteOnce size: 1Gi annotations: {} serviceAnnotations: {} terminationGracePeriodSeconds: 30 tls: enabled: false configmap: {} readinessProbe: initialDelaySeconds: 5 timeoutSeconds: 1 failureThreshold: 3 periodSeconds: 10 successThreshold: 1 livenessProbe: initialDelaySeconds: 30 timeoutSeconds: 5 failureThreshold: 3 periodSeconds: 10 successThreshold: 1
persistentVolume.storageClass
パラメーターはここでコメント化されています。コメントを削除してその値を"-"
に設定すると、動的プロビジョニングが無効になります。 この場合、この値を未定義のままにしているため、チャートはデフォルトのprovisioner
を選択します—この場合はdobs.csi.digitalocean.com
です。
また、persistentVolume
キーに関連付けられているaccessMode
にも注意してください。ReadWriteOnce
は、プロビジョニングされたボリュームが単一ノードによってのみ読み取り/書き込みされることを意味します。 さまざまなアクセスモードの詳細については、ドキュメントを参照してください。
ファイルに含まれている他のパラメーターの詳細については、リポジトリに含まれている構成テーブルを参照してください。
編集が終了したら、ファイルを保存して閉じます。
mongodb-replicaset
チャートを展開する前に、stableリポジトリをhelmrepoupdateコマンドで更新する必要があります。
helm repo update
これにより、stableリポジトリから最新のチャート情報が取得されます。
最後に、次のコマンドを使用してチャートをインストールします。
helm install --name mongo -f mongodb-values.yaml stable/mongodb-replicaset
注:チャートをインストールする前に、--dry-run
および--debug
オプションを指定してhelm install
を実行し、リリース用に生成されたマニフェストを確認できます。
helm install --name your_release_name -f your_values_file.yaml --dry-run --debug your_chart
Helmにreleasemongo
という名前を付けていることに注意してください。 この名前は、指定した構成オプションを使用したチャートのこの特定の展開を示します。 -f
フラグとmongodb-values.yaml
ファイルを含めることで、これらのオプションを示しました。
また、helm install
に--namespace
フラグが含まれていないため、チャートオブジェクトはdefault
名前空間に作成されることに注意してください。
リリースを作成すると、作成されたオブジェクトに関する情報とそれらを操作するための手順とともに、そのステータスに関する出力が表示されます。
OutputNAME: mongo LAST DEPLOYED: Tue Apr 16 21:51:05 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/ConfigMap NAME DATA AGE mongo-mongodb-replicaset-init 1 1s mongo-mongodb-replicaset-mongodb 1 1s mongo-mongodb-replicaset-tests 1 0s ...
これで、次のコマンドを使用してポッドの作成を確認できます。
kubectl get pods
ポッドが作成されると、次のような出力が表示されます。
OutputNAME READY STATUS RESTARTS AGE mongo-mongodb-replicaset-0 1/1 Running 0 67s mongo-mongodb-replicaset-1 0/1 Init:0/3 0 8s
ここでのREADY
およびSTATUS
出力は、StatefulSet内のポッドの準備が完全に整っていないことを示しています。ポッドのコンテナーに関連付けられた InitContainersはまだ実行中です。 StatefulSetメンバーは順番に作成されるため、次のポッドが作成される前に、StatefulSetの各ポッドはRunning
およびReady
である必要があります。
ポッドが作成され、関連するすべてのコンテナが実行されると、次の出力が表示されます。
OutputNAME READY STATUS RESTARTS AGE mongo-mongodb-replicaset-0 1/1 Running 0 2m33s mongo-mongodb-replicaset-1 1/1 Running 0 94s mongo-mongodb-replicaset-2 1/1 Running 0 36s
Running
STATUS
は、ポッドがノードにバインドされており、それらのポッドに関連付けられているコンテナーが実行されていることを示します。 READY
は、ポッド内で実行されているコンテナーの数を示します。 詳細については、ポッドライフサイクルに関するドキュメントを参照してください。
注: STATUS
列に予期しないフェーズが表示された場合は、次のコマンドを使用してポッドのトラブルシューティングを行うことができることに注意してください。
kubectl describe pods your_pod kubectl logs your_pod
StatefulSet内の各ポッドには、StatefulSetの名前とポッドの序数インデックスを組み合わせた名前が付いています。 3つのレプリカを作成したため、StatefulSetメンバーには0〜2の番号が付けられ、それぞれに次の要素で構成される安定したDNSエントリがあります:$(statefulset-name)-$(ordinal).$(service name).$(namespace).svc.cluster.local
。
この場合、mongodb-replicaset
チャートによって作成されたStatefulSetとHeadlessServiceの名前は同じです。
kubectl get statefulset
OutputNAME READY AGE mongo-mongodb-replicaset 3/3 4m2s
kubectl get svc
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 42m mongo-mongodb-replicaset ClusterIP None <none> 27017/TCP 4m35s mongo-mongodb-replicaset-client ClusterIP None <none> 27017/TCP 4m35s
これは、StatefulSetの最初のメンバーが次のDNSエントリを持つことを意味します。
mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local
アプリケーションは各MongoDBインスタンスに接続する必要があるため、サービスではなくポッドと直接通信できるように、この情報を持っていることが不可欠です。 カスタムアプリケーションのヘルムチャートを作成するとき、環境変数を使用して各ポッドのDNSエントリをアプリケーションに渡します。
データベースインスタンスが稼働していると、ノードアプリケーションのグラフを作成する準備が整います。
ステップ4—カスタムアプリケーションチャートの作成とパラメーターの構成
Nodeアプリケーション用のカスタムHelmチャートを作成し、標準チャートディレクトリのデフォルトファイルを変更して、アプリケーションが作成したばかりのレプリカセットで動作できるようにします。 また、アプリケーションのConfigMapオブジェクトとSecretオブジェクトを定義するファイルも作成します。
まず、次のコマンドを使用して、nodeapp
という新しいチャートディレクトリを作成します。
helm create nodeapp
これにより、~/node_project
フォルダにnodeapp
というディレクトリが作成され、次のリソースが使用されます。
- チャートに関する基本情報を含む
Chart.yaml
ファイル。 - MongoDBデプロイメントで行ったように、特定のパラメーター値を設定できる
values.yaml
ファイル。 - チャートをパッケージ化するときに無視されるファイルとディレクトリのパターンを含む
.helmignore
ファイル。 - Kubernetesマニフェストを生成するテンプレートファイルを含む
templates/
ディレクトリ。 - テストファイル用の
templates/tests/
ディレクトリ。 - このチャートが依存するチャートの
charts/
ディレクトリ。
これらのデフォルトファイルから変更する最初のファイルはvalues.yaml
です。 今すぐそのファイルを開きます:
nano nodeapp/values.yaml
ここで設定する値は次のとおりです。
- レプリカの数。
- 使用したいアプリケーションイメージ。 この場合、これはステップ1で作成した
node-replicas
イメージになります。 - ServiceType。 この場合、 LoadBalancer を指定して、テスト目的でアプリケーションへのアクセスポイントを作成します。 DigitalOcean Kubernetesクラスターを使用しているため、チャートをデプロイすると DigitalOcean LoadBalancerが作成されます。 本番環境では、入力リソースおよび入力コントローラーを使用してトラフィックをサービスにルーティングするようにグラフを構成できます。
- targetPort は、アプリケーションが公開されるポッドのポートを指定します。
このファイルには環境変数を入力しません。 代わりに、ConfigMapオブジェクトとSecretオブジェクトのテンプレートを作成し、これらの値を~/node_project/nodeapp/templates/deployment.yaml
にあるアプリケーションDeploymentマニフェストに追加します。
values.yaml
ファイルで次の値を構成します。
〜/ node_project / nodeapp / values.yaml
# Default values for nodeapp. # This is a YAML-formatted file. # Declare variables to be passed into your templates. replicaCount: 3 image: repository: your_dockerhub_username/node-replicas tag: latest pullPolicy: IfNotPresent nameOverride: "" fullnameOverride: "" service: type: LoadBalancer port: 80 targetPort: 8080 ...
編集が終了したら、ファイルを保存して閉じます。
次に、nodeapp/templates
ディレクトリにあるsecret.yaml
ファイルを開きます。
nano nodeapp/templates/secret.yaml
このファイルで、MONGO_USERNAME
およびMONGO_PASSWORD
アプリケーション定数の値を追加します。 これらは、データベース接続ファイルであるdb.js
で指定されているように、アプリケーションが実行時にアクセスすることを期待する定数です。 これらの定数の値を追加するときは、mongo-secret
オブジェクトを作成するときにステップ2で使用したbase64-エンコードされた値を使用することを忘れないでください。 これらの値を再作成する必要がある場合は、ステップ2に戻って、関連するコマンドを再度実行できます。
次のコードをファイルに追加します。
〜/ node_project / nodeapp / templates / secret.yaml
apiVersion: v1 kind: Secret metadata: name: {{ .Release.Name }}-auth data: MONGO_USERNAME: your_encoded_username MONGO_PASSWORD: your_encoded_password
このシークレットオブジェクトの名前は、アプリケーションチャートをデプロイするときに指定するHelmリリースの名前によって異なります。
終了したら、ファイルを保存して閉じます。
次に、ファイルを開いて、アプリケーションのConfigMapを作成します。
nano nodeapp/templates/configmap.yaml
このファイルでは、アプリケーションが期待する残りの変数MONGO_HOSTNAME
、MONGO_PORT
、MONGO_DB
、およびMONGO_REPLICASET
を定義します。 MONGO_HOSTNAME
変数には、レプリカセット内の each インスタンスのDNSエントリが含まれます。これは、MongoDB接続URIがに必要なものだからです。
Kubernetesのドキュメントによると、アプリケーションが活性と準備のチェックを実装する場合、ポッドに接続するときにSRVレコードを使用する必要があります。 ステップ3で説明したように、ポッドSRVレコードは$(statefulset-name)-$(ordinal).$(service name).$(namespace).svc.cluster.local
のパターンに従います。 MongoDB StatefulSetは活性と準備のチェックを実装しているため、MONGO_HOSTNAME
変数の値を定義するときに、これらの安定した識別子を使用する必要があります。
次のコードをファイルに追加して、MONGO_HOSTNAME
、MONGO_PORT
、MONGO_DB
、およびMONGO_REPLICASET
変数を定義します。 MONGO_DB
データベースには別の名前を自由に使用できますが、MONGO_HOSTNAME
およびMONGO_REPLICASET
の値は次のように記述する必要があります。
〜/ node_project / nodeapp / templates / configmap.yaml
apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-config data: MONGO_HOSTNAME: "mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local,mongo-mongodb-replicaset-1.mongo-mongodb-replicaset.default.svc.cluster.local,mongo-mongodb-replicaset-2.mongo-mongodb-replicaset.default.svc.cluster.local" MONGO_PORT: "27017" MONGO_DB: "sharkinfo" MONGO_REPLICASET: "db"
StatefulSetオブジェクトとレプリカセットはすでに作成されているため、ここにリストされているホスト名は、この例に示されているとおりにファイルにリストされている必要があります。 これらのオブジェクトを破棄してMongoDBHelmリリースの名前を変更する場合は、このConfigMapに含まれる値を変更する必要があります。 MongoDBリリースでレプリカセット名を指定したため、MONGO_REPLICASET
にも同じことが当てはまります。
また、ここにリストされている値は引用符で囲まれていることに注意してください。これは、Helmの環境変数の期待値です。
編集が終了したら、ファイルを保存して閉じます。
チャートパラメーター値を定義し、SecretマニフェストとConfigMapマニフェストを作成したら、アプリケーションデプロイメントテンプレートを編集して環境変数を使用できます。
ステップ5—環境変数をHelmデプロイメントに統合する
アプリケーションSecretとConfigMapのファイルを配置したら、アプリケーションDeploymentがこれらの値を使用できることを確認する必要があります。 また、展開マニフェストですでに定義されているライブネスおよび準備プローブをカスタマイズします。
編集用にアプリケーションデプロイメントテンプレートを開きます。
nano nodeapp/templates/deployment.yaml
これはYAMLファイルですが、Helmテンプレートはマニフェストを生成するために標準のKubernetesYAMLファイルとは異なる構文を使用します。 テンプレートの詳細については、ヘルムのドキュメントを参照してください。
ファイルで、最初にenv
キーをアプリケーションコンテナの仕様に追加します。imagePullPolicy
キーの下、ports
の上にあります。
〜/ node_project / nodeapp / templates / deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: ... spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: ports:
次に、env
変数のリストに次のキーを追加します。
〜/ node_project / nodeapp / templates / deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: ... spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: - name: MONGO_USERNAME valueFrom: secretKeyRef: key: MONGO_USERNAME name: {{ .Release.Name }}-auth - name: MONGO_PASSWORD valueFrom: secretKeyRef: key: MONGO_PASSWORD name: {{ .Release.Name }}-auth - name: MONGO_HOSTNAME valueFrom: configMapKeyRef: key: MONGO_HOSTNAME name: {{ .Release.Name }}-config - name: MONGO_PORT valueFrom: configMapKeyRef: key: MONGO_PORT name: {{ .Release.Name }}-config - name: MONGO_DB valueFrom: configMapKeyRef: key: MONGO_DB name: {{ .Release.Name }}-config - name: MONGO_REPLICASET valueFrom: configMapKeyRef: key: MONGO_REPLICASET name: {{ .Release.Name }}-config
各変数には、シークレット値の場合は secretKeyRef key で定義され、ConfigMap値の場合はconfigMapKeyRefで定義された値への参照が含まれます。 これらのキーは、前のステップで作成したシークレットファイルとConfigMapファイルを指します。
次に、ports
キーの下で、containerPort
定義を変更して、アプリケーションが公開されるコンテナーのポートを指定します。
〜/ node_project / nodeapp / templates / deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: ... spec: containers: ... env: ... ports: - name: http containerPort: 8080 protocol: TCP ...
次に、このデプロイメントマニフェストにデフォルトで含まれている活性と準備のチェックを変更しましょう。 これらのチェックにより、アプリケーションポッドが実行され、トラフィックを処理する準備ができていることが確認されます。
- 準備プローブは、ポッドがトラフィックを処理する準備ができているかどうかを評価し、チェックが成功するまでポッドへのすべての要求を停止します。
- 活性プローブは、基本的なアプリケーションの動作をチェックして、コンテナー内のアプリケーションが実行され、期待どおりに動作しているかどうかを判断します。 ライブネスプローブが失敗した場合、Kubernetesはコンテナを再起動します。
両方の詳細については、Kubernetes用アプリケーションのアーキテクチャの関連するディスカッションを参照してください。
この例では、Helmがデフォルトで提供する httpGet request に基づいて構築し、アプリケーションが/sharks
エンドポイントでリクエストを受け入れているかどうかをテストします。 kubeletサービスは、アプリケーションポッドのコンテナで実行されているノードサーバーにGETリクエストを送信し、ポート8080
でリッスンすることでプローブを実行します。 応答のステータスコードが200〜400の場合、kubelet
はコンテナが正常であると判断します。 それ以外の場合、ステータスが400または500の場合、kubelet
は、準備プローブの場合はコンテナーへのトラフィックを停止するか、活性プローブの場合はコンテナーを再起動します。
活気と準備のプローブについて、記載されているpath
に次の変更を追加します。
〜/ node_project / nodeapp / templates / deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: ... spec: containers: ... env: ... ports: - name: http containerPort: 8080 protocol: TCP livenessProbe: httpGet: path: /sharks port: http readinessProbe: httpGet: path: /sharks port: http
編集が終了したら、ファイルを保存して閉じます。
これで、Helmを使用してアプリケーションリリースを作成する準備が整いました。 次のhelminstallコマンドを実行します。これには、リリースの名前とチャートディレクトリの場所が含まれます。
helm install --name nodejs ./nodeapp
ステップ3で説明したように、最初に--dry-run
および--debug
オプションを指定してhelm install
を実行し、リリース用に生成されたマニフェストを確認できることを忘れないでください。
ここでも、helm install
に--namespace
フラグが含まれていないため、チャートオブジェクトはdefault
名前空間に作成されます。
リリースが作成されたことを示す次の出力が表示されます。
OutputNAME: nodejs LAST DEPLOYED: Wed Apr 17 18:10:29 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/ConfigMap NAME DATA AGE nodejs-config 4 1s ==> v1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE nodejs-nodeapp 0/3 3 0 1s ...
この場合も、出力には、作成されたオブジェクトとそれらを操作する方法に関する情報とともに、リリースのステータスが示されます。
ポッドのステータスを確認します。
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE mongo-mongodb-replicaset-0 1/1 Running 0 57m mongo-mongodb-replicaset-1 1/1 Running 0 56m mongo-mongodb-replicaset-2 1/1 Running 0 55m nodejs-nodeapp-577df49dcc-b5fq5 1/1 Running 0 117s nodejs-nodeapp-577df49dcc-bkk66 1/1 Running 0 117s nodejs-nodeapp-577df49dcc-lpmt2 1/1 Running 0 117s
ポッドが稼働したら、サービスを確認します。
kubectl get svc
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 96m mongo-mongodb-replicaset ClusterIP None <none> 27017/TCP 58m mongo-mongodb-replicaset-client ClusterIP None <none> 27017/TCP 58m nodejs-nodeapp LoadBalancer 10.245.33.46 your_lb_ip 80:31518/TCP 3m22s
nodejs-nodeapp
サービスに関連付けられているEXTERNAL_IP
は、クラスターの外部からアプリケーションにアクセスできるIPアドレスです。 EXTERNAL_IP
列に<pending>
ステータスが表示されている場合は、ロードバランサーがまだ作成中であることを意味します。
その列にIPが表示されたら、ブラウザでhttp://your_lb_ip
に移動します。
次のランディングページが表示されます。
レプリケートされたアプリケーションが機能しているので、いくつかのテストデータを追加して、レプリカセットのメンバー間でレプリケーションが機能していることを確認しましょう。
ステップ6—MongoDBレプリケーションのテスト
アプリケーションが実行され、外部IPアドレスを介してアクセスできるようになったら、テストデータを追加して、MongoDBレプリカセットのメンバー間で複製されていることを確認できます。
まず、ブラウザをアプリケーションのランディングページに移動したことを確認します。
Get SharkInfoボタンをクリックします。 サメの名前とそのサメの一般的な性格の説明を入力できる入力フォームのあるページが表示されます。
フォームに、選択した最初のサメを追加します。 実例を示すために、Megalodon Shark
をShark Name フィールドに追加し、Ancient
をSharkCharacterフィールドに追加します。
送信ボタンをクリックします。 このサメの情報が表示されたページが表示されます。
次に、上部のナビゲーションバーにある Sharks をクリックして、サメ情報フォームに戻ります。
お好みの新しいサメを入力してください。 Whale Shark
とLarge
を使用します。
送信をクリックすると、新しいサメがデータベースのサメコレクションに追加されたことがわかります。
入力したデータがレプリカセットのプライマリメンバーとセカンダリメンバーの間で複製されていることを確認しましょう。
ポッドのリストを取得します。
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE mongo-mongodb-replicaset-0 1/1 Running 0 74m mongo-mongodb-replicaset-1 1/1 Running 0 73m mongo-mongodb-replicaset-2 1/1 Running 0 72m nodejs-nodeapp-577df49dcc-b5fq5 1/1 Running 0 5m4s nodejs-nodeapp-577df49dcc-bkk66 1/1 Running 0 5m4s nodejs-nodeapp-577df49dcc-lpmt2 1/1 Running 0 5m4s
ポッドのmongoshell にアクセスするには、kubectlexecコマンドとステップ2でmongo-secret
を作成するために使用したユーザー名を使用できます。 ]。 次のコマンドを使用して、StatefulSetの最初のポッドのmongo
シェルにアクセスします。
kubectl exec -it mongo-mongodb-replicaset-0 -- mongo -u your_database_username -p --authenticationDatabase admin
プロンプトが表示されたら、このユーザー名に関連付けられているパスワードを入力します。
OutputMongoDB shell version v4.1.9 Enter password:
管理シェルにドロップされます:
OutputMongoDB server version: 4.1.9 Welcome to the MongoDB shell. ... db:PRIMARY>
プロンプト自体にこの情報が含まれていますが、 rs.isMaster()メソッドを使用して、どのレプリカセットメンバーがプライマリであるかを手動で確認できます。
rs.isMaster()
プライマリのホスト名を示す次のような出力が表示されます。
Outputdb:PRIMARY> rs.isMaster() { "hosts" : [ "mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local:27017", "mongo-mongodb-replicaset-1.mongo-mongodb-replicaset.default.svc.cluster.local:27017", "mongo-mongodb-replicaset-2.mongo-mongodb-replicaset.default.svc.cluster.local:27017" ], ... "primary" : "mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local:27017", ...
次に、sharkinfo
データベースに切り替えます。
use sharkinfo
Outputswitched to db sharkinfo
データベース内のコレクションを一覧表示します。
show collections
Outputsharks
コレクション内のドキュメントを出力します。
db.sharks.find()
次の出力が表示されます。
Output{ "_id" : ObjectId("5cb7702c9111a5451c6dc8bb"), "name" : "Megalodon Shark", "character" : "Ancient", "__v" : 0 } { "_id" : ObjectId("5cb77054fcdbf563f3b47365"), "name" : "Whale Shark", "character" : "Large", "__v" : 0 }
MongoDBシェルを終了します。
exit
プライマリのデータを確認したので、セカンダリにデータが複製されていることを確認しましょう。 次のコマンドを使用して、kubectl exec
をmongo-mongodb-replicaset-1
に挿入します。
kubectl exec -it mongo-mongodb-replicaset-1 -- mongo -u your_database_username -p --authenticationDatabase admin
管理シェルに入ったら、db.setSlaveOk()
メソッドを使用して、セカンダリインスタンスからの読み取り操作を許可する必要があります。
db.setSlaveOk(1)
sharkinfo
データベースに切り替えます。
use sharkinfo
Outputswitched to db sharkinfo
sharks
コレクション内のドキュメントの読み取り操作を許可します。
db.setSlaveOk(1)
コレクション内のドキュメントを出力します。
db.sharks.find()
これで、プライマリインスタンスでこのメソッドを実行したときに表示されたのと同じ情報が表示されます。
Outputdb:SECONDARY> db.sharks.find() { "_id" : ObjectId("5cb7702c9111a5451c6dc8bb"), "name" : "Megalodon Shark", "character" : "Ancient", "__v" : 0 } { "_id" : ObjectId("5cb77054fcdbf563f3b47365"), "name" : "Whale Shark", "character" : "Large", "__v" : 0 }
この出力は、アプリケーションデータがレプリカセットのメンバー間で複製されていることを確認します。
結論
これで、Helmチャートを使用して、複製された高可用性のサメ情報アプリケーションをKubernetesクラスターにデプロイしました。 このデモアプリケーションとこのチュートリアルで概説されているワークフローは、アプリケーションのカスタムチャートを作成し、Helmのstableリポジトリと他のチャートリポジトリを利用する際の出発点として機能します。
本番環境に移行するときは、次の実装を検討してください。
- 一元化されたロギングとモニタリング。 一般的な概要については、Kubernetes用アプリケーションの最新化の関連するディスカッションを参照してください。 KubernetesでElasticsearch、Fluentd、Kibana(EFK)のログスタックを設定する方法を参照して、 Elasticsearch 、Fluentdでログスタックを設定する方法を学ぶこともできます。 、およびKibana。 Istio のようなサービスメッシュがこの機能を実装する方法については、サービスメッシュの概要も確認してください。
- トラフィックをクラスターにルーティングするための入力リソース。 これは、それぞれが独自のLoadBalancerを必要とする複数のサービスを実行している場合、またはアプリケーションレベルのルーティング戦略(A / Bおよびカナリアテストなど)を実装する場合に、LoadBalancerの優れた代替手段です。 詳細については、 DigitalOcean KubernetesでCert-Managerを使用してNginxIngressを設定する方法と、はじめにのサービスメッシュコンテキストでのルーティングに関する関連のディスカッションをご覧ください。サービスメッシュ。
- Kubernetesオブジェクトのバックアップ戦略。 DigitalOceanのKubernetes製品でVelero(以前のHeptio Ark)を使用してバックアップを実装するためのガイダンスについては、 HeptioArkを使用してDigitalOceanでKubernetesクラスターをバックアップおよび復元する方法を参照してください。
Helmの詳細については、 Helmの概要、Kubernetesのパッケージマネージャー、 Helm Package Manager を使用してKubernetesクラスターにソフトウェアをインストールする方法、およびHelmのドキュメントを参照してください。 。