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のドキュメントを参照してください。 。