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クラスターを使用しますが、別の方法を使用してクラスターを自由に作成できます。
- The
kubectl
ローカルマシンまたは開発サーバーにインストールされ、クラスターに接続するように構成されたコマンドラインツール。 インストールについてもっと読むことができますkubectl
公式ドキュメントにあります。 - Helm Package Manager を使用してKubernetesクラスターにソフトウェアをインストールする方法の手順1と2に概説されている手順に従って、ローカルマシンまたは開発サーバーにHelmをインストールし、クラスターにTillerをインストールします。
- Dockerがローカルマシンまたは開発サーバーにインストールされています。 Ubuntu 18.04を使用している場合は、 Ubuntu18.04にDockerをインストールして使用する方法の手順1と2に従ってください。 それ以外の場合は、他のオペレーティングシステムへのインストールについて、公式ドキュメントに従ってください。 必ず非rootユーザーをに追加してください
docker
リンクされたチュートリアルのステップ2で説明されているように、グループ。 - DockerHubアカウント。 これを設定する方法の概要については、DockerHubのこの紹介を参照してください。
ステップ1—アプリケーションのクローン作成とパッケージ化
アプリケーションをKubernetesで使用するには、kubeletエージェントがイメージをプルできるようにアプリケーションをパッケージ化する必要があります。 ただし、アプリケーションをパッケージ化する前に、アプリケーションコードのMongoDB接続URIを変更して、Helmで作成するレプリカセットのメンバーにアプリケーションが接続できるようにする必要があります。 mongodb-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
The node_project
ディレクトリには、ユーザー入力で動作するサメ情報アプリケーションのファイルとディレクトリが含まれています。 コンテナーで動作するように最新化されました。機密性の高い特定の構成情報がアプリケーションコードから削除され、実行時に注入されるようにリファクタリングされ、アプリケーションの状態がMongoDBデータベースにオフロードされました。
最新のコンテナ化されたアプリケーションの設計の詳細については、Kubernetes用アプリケーションのアーキテクチャおよびKubernetes用アプリケーションの最新化を参照してください。
ヘルムを配備するとき 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文字列自体の定数は、現在次のようになっています。
...
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定数オブジェクトと接続文字列の両方に:
...
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 .
The .
コマンドで、ビルドコンテキストが現在のディレクトリであることを指定します。
イメージの作成には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アカウントのパスワードを入力します。 この方法でログインすると、 ~/.docker/config.json
ルート以外のユーザーのホームディレクトリに、DockerHubのクレデンシャルを使用してファイルします。
dockerpushコマンドを使用してアプリケーションイメージをDockerHubにプッシュします。 交換することを忘れないでください your_dockerhub_username
独自のDockerHubユーザー名を使用:
- docker push your_dockerhub_username/node-replicas
これで、Kubernetesでレプリケートされたアプリケーションを実行するためにプルできるアプリケーションイメージができました。 次のステップは、MongoDBHelmチャートで使用する特定のパラメーターを構成することです。
ステップ2—MongoDBレプリカセットのシークレットを作成する
The stable/mongodb-replicaset
チャートは、シークレットの使用に関してさまざまなオプションを提供します。チャートの展開で使用する2つを作成します。
- レプリカセットキーファイルのシークレット。レプリカセットメンバー間で共有パスワードとして機能し、他のメンバーを認証できるようにします。
- MongoDB管理者ユーザーの秘密。このユーザーはrootユーザーとして作成されます。
admin
データベース。 この役割により、アプリケーションを本番環境にデプロイするときに、権限が制限された後続のユーザーを作成できます。
これらのシークレットを設定すると、専用の値ファイルに優先パラメーター値を設定し、Helmチャートを使用してStatefulSetオブジェクトとMongoDBレプリカセットを作成できるようになります。
まず、キーファイルを作成しましょう。 opensslコマンドを rand
キーファイルの756バイトのランダムな文字列を生成するオプション:
- openssl rand -base64 756 > key.txt
コマンドによって生成された出力は、 base64 でエンコードされ、均一なデータ送信を保証し、次のファイルにリダイレクトされます。 key.txt
、mongodb-replicasetチャート認証ドキュメントに記載されているガイドラインに従います。 キー自体は、6〜1024文字の長さで、base64セットの文字のみで構成されている必要があります。
これで、というシークレットを作成できます keyfilesecret
このファイルをkubectlcreate で使用する:
- 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
と --validate
フラグ:
- kubectl create -f your_yaml_file.yaml --dry-run --validate=true
一般に、リソースを作成する前に構文を検証することをお勧めします。 kubectl
.
次のコードをファイルに追加して、 user
と password
作成したエンコードされた値を使用します。 ここのダミー値は、必ず独自のエンコードされたユーザー名とパスワードに置き換えてください。
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には、使用するチャートを含むstableと呼ばれるアクティブに保守されているリポジトリが付属しています。 mongodb-replicaset
. 作成したシークレットでこのチャートを使用するには、次のような構成パラメーター値を持つファイルを作成します。 mongodb-values.yaml
次に、このファイルを使用してチャートをインストールします。
私たちの mongodb-values.yaml
ファイルは主にデフォルトのvalues.yamlファイルをミラーリングします mongodb-replicaset
チャートリポジトリ。 ただし、ファイルには次の変更を加えます。
- 設定します
auth
パラメータからtrue
データベースインスタンスが認証が有効で始まることを確認します。 これは、すべてのクライアントがデータベースのリソースと操作にアクセスするために認証する必要があることを意味します。 - 前のステップで作成したシークレットに関する情報を追加して、チャートがこれらの値を使用してレプリカセットのキーファイルと管理者ユーザーを作成できるようにします。
- StatefulSetの各ポッドに関連付けられているPersistentVolumeのサイズを小さくして、最小実行可能DigitalOceanブロックストレージユニット、1GBを使用しますが、ストレージ要件に合わせてこれを自由に変更できます。
書く前に mongodb-values.yaml
ただし、最初に StorageClass が作成され、ストレージリソースをプロビジョニングするように構成されていることを確認する必要があります。 データベースStatefulSet内の各ポッドには、スティッキーIDと関連する PersistentVolumeClaim があり、ポッドのPersistentVolumeを動的にプロビジョニングします。 ポッドが再スケジュールされた場合、PersistentVolumeは、ポッドがスケジュールされているノードにマウントされます(ただし、関連付けられたポッドまたはStatefulSetが完全に削除される場合は、各ボリュームを手動で削除する必要があります)。
DigitalOcean Kubernetes を使用しているため、デフォルトのStorageClass provisioner
に設定されています 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
オブジェクト。 - 特定
1Gi
PersistentVolumes用。 - レプリカセット名をに設定します
db
. - 特定
3
セットのレプリカ。 - ピン留め
mongo
執筆時点での最新バージョンへの画像:4.1.9
.
次のコードをファイルに貼り付けます。
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
The persistentVolume.storageClass
パラメータはここでコメント化されています:コメントを削除し、その値をに設定します "-"
動的プロビジョニングを無効にします。 この場合、この値を未定義のままにしているため、グラフはデフォルトを選択します provisioner
– 私たちの場合には、 dobs.csi.digitalocean.com
.
また、 accessMode
に関連付けられている persistentVolume
鍵: ReadWriteOnce
プロビジョニングされたボリュームは、単一のノードによってのみ読み取り/書き込みが行われることを意味します。 さまざまなアクセスモードの詳細については、ドキュメントを参照してください。
ファイルに含まれている他のパラメーターの詳細については、リポジトリに含まれている構成テーブルを参照してください。
編集が終了したら、ファイルを保存して閉じます。
展開する前に mongodb-replicaset
チャートでは、 stableリポジトリをhelmリポジトリ更新コマンドで更新する必要があります。
- helm repo update
これにより、stableリポジトリから最新のチャート情報が取得されます。
最後に、次のコマンドを使用してチャートをインストールします。
- helm install --name mongo -f mongodb-values.yaml stable/mongodb-replicaset
注:チャートをインストールする前に、実行できます helm install
とともに --dry-run
と --debug
リリース用に生成されたマニフェストをチェックするオプション:
- helm install --name your_release_name -f your_values_file.yaml --dry-run --debug your_chart
Helm releaseに名前を付けていることに注意してください mongo
. この名前は、指定した構成オプションを使用したチャートのこの特定の展開を示します。 これらのオプションを含めることで、これらのオプションを示しました。 -f
旗と私たち mongodb-values.yaml
ファイル。
また、含まれていなかったため、 --namespace
フラグ helm install
、チャートオブジェクトはで作成されます 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
The 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
The 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
.
私たちの場合、StatefulSetと Headless Service は、 mongodb-replicaset
チャートの名前は同じです。
- 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
これにより、というディレクトリが作成されます nodeapp
あなたの中で ~/node_project
次のリソースを含むフォルダ:
- A
Chart.yaml
チャートに関する基本情報を含むファイル。 - A
values.yaml
MongoDBデプロイメントで行ったように、特定のパラメーター値を設定できるファイル。 - A
.helmignore
チャートをパッケージ化するときに無視されるファイルとディレクトリのパターンを含むファイル。 - A
templates/
Kubernetesマニフェストを生成するテンプレートファイルを含むディレクトリ。 - A
templates/tests/
テストファイルのディレクトリ。 - A
charts/
このチャートが依存するチャートのディレクトリ。
これらのデフォルトファイルから変更する最初のファイルは values.yaml
. 今すぐそのファイルを開きます:
- nano nodeapp/values.yaml
ここで設定する値は次のとおりです。
- レプリカの数。
- 使用したいアプリケーションイメージ。 私たちの場合、これは
node-replicas
ステップ1で作成した画像。 - ServiceType。 この場合、 LoadBalancer を指定して、テスト目的でアプリケーションへのアクセスポイントを作成します。 DigitalOcean Kubernetesクラスターを使用しているため、チャートをデプロイすると DigitalOcean LoadBalancerが作成されます。 本番環境では、入力リソースおよび入力コントローラーを使用してトラフィックをサービスにルーティングするようにグラフを構成できます。
- targetPort は、アプリケーションが公開されるポッドのポートを指定します。
このファイルには環境変数を入力しません。 代わりに、ConfigMapオブジェクトとSecretオブジェクトのテンプレートを作成し、これらの値を次の場所にあるアプリケーションのDeploymentマニフェストに追加します。 ~/node_project/nodeapp/templates/deployment.yaml
.
で次の値を構成します 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
...
編集が終了したら、ファイルを保存して閉じます。
次に、 secret.yaml
のファイル nodeapp/templates
ディレクトリ:
- nano nodeapp/templates/secret.yaml
このファイルに、 MONGO_USERNAME
と MONGO_PASSWORD
アプリケーション定数。 これらは、で指定されているように、アプリケーションが実行時にアクセスできると期待する定数です。 db.js
、データベース接続ファイル。 これらの定数の値を追加するときは、作成時にステップ2で以前に使用したbase64-エンコードされた値を使用することを忘れないでください。 mongo-secret
物体。 これらの値を再作成する必要がある場合は、ステップ2に戻って、関連するコマンドを再度実行できます。
次のコードをファイルに追加します。
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
値は、ここに表示されているとおりに記述する必要があります。
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に含まれる値を変更する必要があります。 同じことが当てはまります MONGO_REPLICASET
、MongoDBリリースでレプリカセット名を指定したため。
また、ここにリストされている値は引用符で囲まれていることに注意してください。これは、Helmの環境変数の期待値です。
編集が終了したら、ファイルを保存して閉じます。
チャートパラメーター値を定義し、SecretマニフェストとConfigMapマニフェストを作成したら、アプリケーションデプロイメントテンプレートを編集して環境変数を使用できます。
ステップ5—環境変数をHelmデプロイメントに統合する
アプリケーションSecretとConfigMapのファイルを配置したら、アプリケーションDeploymentがこれらの値を使用できることを確認する必要があります。 また、展開マニフェストですでに定義されているライブネスおよび準備プローブをカスタマイズします。
編集用にアプリケーションデプロイメントテンプレートを開きます。
- nano nodeapp/templates/deployment.yaml
これはYAMLファイルですが、Helmテンプレートはマニフェストを生成するために標準のKubernetesYAMLファイルとは異なる構文を使用します。 テンプレートの詳細については、ヘルムのドキュメントを参照してください。
ファイルに、最初にを追加します env
以下のアプリケーションコンテナ仕様の鍵 imagePullPolicy
キー以上 ports
:
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
変数:
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
アプリケーションが公開されるコンテナのポートを指定するための定義:
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
活気と準備の調査のために:
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
実行できることを忘れないでください helm install
とともに --dry-run
と --debug
ステップ3で説明されているように、最初にオプションを選択して、リリース用に生成されたマニフェストを確認します。
繰り返しますが、 --namespace
フラグ helm install
、チャートオブジェクトはで作成されます 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
The EXTERNAL_IP
に関連付けられている nodejs-nodeapp
サービスは、クラスターの外部からアプリケーションにアクセスできるIPアドレスです。 あなたが見たら <pending>
のステータス EXTERNAL_IP
列の場合、これはロードバランサーがまだ作成中であることを意味します。
その列にIPが表示されたら、ブラウザでそのIPに移動します。 http://your_lb_ip
.
次のランディングページが表示されます。
レプリケートされたアプリケーションが機能しているので、いくつかのテストデータを追加して、レプリカセットのメンバー間でレプリケーションが機能していることを確認しましょう。
ステップ6—MongoDBレプリケーションのテスト
アプリケーションが実行され、外部IPアドレスを介してアクセスできるようになったら、テストデータを追加して、MongoDBレプリカセットのメンバー間で複製されていることを確認できます。
まず、ブラウザをアプリケーションのランディングページに移動したことを確認します。
Get SharkInfoボタンをクリックします。 サメの名前とそのサメの一般的な性格の説明を入力できる入力フォームのあるページが表示されます。
フォームに、選択した最初のサメを追加します。 実証するために、 Megalodon Shark
Shark Name フィールドに移動し、 Ancient
Shark Character フィールドへ:
送信ボタンをクリックします。 このサメの情報が表示されたページが表示されます。
次に、上部のナビゲーションバーにある 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コマンドと作成に使用したユーザー名を使用できます。 mongo-secret
ステップ2で。 アクセスする mongo
次のコマンドを使用して、StatefulSetの最初のポッドでシェルを作成します。
- 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のドキュメントを参照してください。 。