序章

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:

  1. git clone https://github.com/do-community/node-mongo-docker-dev.git node_project

に移動します node_project ディレクトリ:

  1. 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 またはお気に入りの編集者:

  1. 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 またはあなた自身が選んだ名前:

  1. docker build -t your_dockerhub_username/node-replicas .

The . コマンドで、ビルドコンテキストが現在のディレクトリであることを指定します。

イメージの作成には1〜2分かかります。 完了したら、画像を確認します。

  1. docker images

次の出力が表示されます。

Output
REPOSITORY 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アカウントにログインします。

  1. docker login -u your_dockerhub_username

プロンプトが表示されたら、DockerHubアカウントのパスワードを入力します。 この方法でログインすると、 ~/.docker/config.json ルート以外のユーザーのホームディレクトリに、DockerHubのクレデンシャルを使用してファイルします。

dockerpushコマンドを使用してアプリケーションイメージをDockerHubにプッシュします。 交換することを忘れないでください your_dockerhub_username 独自のDockerHubユーザー名を使用:

  1. 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バイトのランダムな文字列を生成するオプション:

  1. openssl rand -base64 756 > key.txt

コマンドによって生成された出力は、 base64 でエンコードされ、均一なデータ送信を保証し、次のファイルにリダイレクトされます。 key.txtmongodb-replicasetチャート認証ドキュメントに記載されているガイドラインに従います。 キー自体は、6〜1024文字の長さで、base64セットの文字のみで構成されている必要があります。

これで、というシークレットを作成できます keyfilesecret このファイルをkubectlcreate で使用する:

  1. kubectl create secret generic keyfilesecret --from-file=key.txt

これにより、にシークレットオブジェクトが作成されます default namespace 、セットアップ用の特定の名前空間を作成していないため。

シークレットが作成されたことを示す次の出力が表示されます。

Output
secret/keyfilesecret created

削除する key.txt:

  1. rm key.txt

または、ファイルを保存する場合は、必ずアクセス許可を制限し、.gitignoreファイルに追加してバージョン管理されないようにしてください。

次に、MongoDB管理者ユーザーのシークレットを作成します。 最初のステップは、希望するユーザー名とパスワードをbase64に変換することです。

データベースのユーザー名を変換します。

  1. echo -n 'your_database_username' | base64

出力に表示される値を書き留めます。

次に、パスワードを変換します。

  1. echo -n 'your_database_password' | base64

ここでも出力の値に注意してください。

シークレットのファイルを開きます。

  1. nano secret.yaml

注:Kubernetesオブジェクトは通常YAML を使用して定義されます。これはタブを厳密に禁止し、インデントに2つのスペースを必要とします。 YAMLファイルのフォーマットを確認したい場合は、 linter を使用するか、次を使用して構文の有効性をテストできます。 kubectl create とともに --dry-run--validate フラグ:

  1. kubectl create -f your_yaml_file.yaml --dry-run --validate=true

一般に、リソースを作成する前に構文を検証することをお勧めします。 kubectl.

次のコードをファイルに追加して、 userpassword 作成したエンコードされた値を使用します。 ここのダミー値は、必ず独自のエンコードされたユーザー名とパスワードに置き換えてください。

〜/ node_project / secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mongo-secret
data:
  user: your_encoded_username
  password: your_encoded_password

ここでは、 mongodb-replicaset チャートは以下を期待します: userpassword. シークレットオブジェクトに名前を付けました mongo-secret、ただし、好きな名前を付けることができます。

編集が終了したら、ファイルを保存して閉じます。

次のコマンドを使用してSecretオブジェクトを作成します。

  1. kubectl create -f secret.yaml

次の出力が表示されます。

Output
secret/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 —次のように入力して確認できます。

  1. kubectl get storageclass

DigitalOceanクラスターを使用している場合は、次の出力が表示されます。

Output
NAME PROVISIONER AGE do-block-storage (default) dobs.csi.digitalocean.com 21m

DigitalOceanクラスターを使用していない場合は、StorageClassを作成し、 provisioner お好みの。 これを行う方法の詳細については、公式ドキュメントを参照してください。

StorageClassが構成されていることを確認したので、開いてください mongodb-values.yaml 編集用:

  1. nano mongodb-values.yaml

このファイルには、次のような値を設定します。

  • 承認を有効にします。
  • あなたの keyfilesecretmongo-secret オブジェクト。
  • 特定 1Gi PersistentVolumes用。
  • レプリカセット名をに設定します 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

The persistentVolume.storageClass パラメータはここでコメント化されています:コメントを削除し、その値をに設定します "-" 動的プロビジョニングを無効にします。 この場合、この値を未定義のままにしているため、グラフはデフォルトを選択します provisioner – 私たちの場合には、 dobs.csi.digitalocean.com.

また、 accessMode に関連付けられている persistentVolume 鍵: ReadWriteOnce プロビジョニングされたボリュームは、単一のノードによってのみ読み取り/書き込みが行われることを意味します。 さまざまなアクセスモードの詳細については、ドキュメントを参照してください。

ファイルに含まれている他のパラメーターの詳細については、リポジトリに含まれている構成テーブルを参照してください。

編集が終了したら、ファイルを保存して閉じます。

展開する前に mongodb-replicaset チャートでは、 stableリポジトリをhelmリポジトリ更新コマンドで更新する必要があります。

  1. helm repo update

これにより、stableリポジトリから最新のチャート情報が取得されます。

最後に、次のコマンドを使用してチャートをインストールします。

  1. helm install --name mongo -f mongodb-values.yaml stable/mongodb-replicaset

注:チャートをインストールする前に、実行できます helm install とともに --dry-run--debug リリース用に生成されたマニフェストをチェックするオプション:

  1. 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 名前空間。

リリースを作成すると、作成されたオブジェクトに関する情報とそれらを操作するための手順とともに、そのステータスに関する出力が表示されます。

Output
NAME: 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 ...

これで、次のコマンドを使用してポッドの作成を確認できます。

  1. kubectl get pods

ポッドが作成されると、次のような出力が表示されます。

Output
NAME 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 READYSTATUS ここでの出力は、StatefulSet内のポッドの準備が完全に整っていないことを示しています。ポッドのコンテナーに関連付けられている InitContainersはまだ実行中です。 StatefulSetメンバーは順番に作成されるため、StatefulSetの各ポッドはである必要があります。 RunningReady 次のポッドが作成される前に。

ポッドが作成され、関連するすべてのコンテナが実行されると、次の出力が表示されます。

Output
NAME 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 列では、次のコマンドを使用してポッドのトラブルシューティングを行うことができることを忘れないでください。

  1. kubectl describe pods your_pod
  2. 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 チャートの名前は同じです。

  1. kubectl get statefulset
Output
NAME READY AGE mongo-mongodb-replicaset 3/3 4m2s
  1. kubectl get svc
Output
NAME 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 次のコマンドを使用します。

  1. 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. 今すぐそのファイルを開きます:

  1. 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 ファイル:

〜/ 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
...

編集が終了したら、ファイルを保存して閉じます。

次に、 secret.yaml のファイル nodeapp/templates ディレクトリ:

  1. nano nodeapp/templates/secret.yaml

このファイルに、 MONGO_USERNAMEMONGO_PASSWORD アプリケーション定数。 これらは、で指定されているように、アプリケーションが実行時にアクセスできると期待する定数です。 db.js、データベース接続ファイル。 これらの定数の値を追加するときは、作成時にステップ2で以前に使用したbase64-エンコードされた値を使用することを忘れないでください。 mongo-secret 物体。 これらの値を再作成する必要がある場合は、ステップ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を作成します。

  1. 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_HOSTNAMEMONGO_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に含まれる値を変更する必要があります。 同じことが当てはまります MONGO_REPLICASET、MongoDBリリースでレプリカセット名を指定したため。

また、ここにリストされている値は引用符で囲まれていることに注意してください。これは、Helmの環境変数の期待値です。

編集が終了したら、ファイルを保存して閉じます。

チャートパラメーター値を定義し、SecretマニフェストとConfigMapマニフェストを作成したら、アプリケーションデプロイメントテンプレートを編集して環境変数を使用できます。

ステップ5—環境変数をHelmデプロイメントに統合する

アプリケーションSecretとConfigMapのファイルを配置したら、アプリケーションDeploymentがこれらの値を使用できることを確認する必要があります。 また、展開マニフェストですでに定義されているライブネスおよび準備プローブをカスタマイズします。

編集用にアプリケーションデプロイメントテンプレートを開きます。

  1. 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コマンドを実行します。これには、リリースの名前とチャートディレクトリの場所が含まれます。

  1. helm install --name nodejs ./nodeapp

実行できることを忘れないでください helm install とともに --dry-run--debug ステップ3で説明されているように、最初にオプションを選択して、リリース用に生成されたマニフェストを確認します。

繰り返しますが、 --namespace フラグ helm install、チャートオブジェクトはで作成されます default 名前空間。

リリースが作成されたことを示す次の出力が表示されます。

Output
NAME: 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 ...

この場合も、出力には、作成されたオブジェクトとそれらを操作する方法に関する情報とともに、リリースのステータスが示されます。

ポッドのステータスを確認します。

  1. kubectl get pods
Output
NAME 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

ポッドが稼働したら、サービスを確認します。

  1. kubectl get svc
Output
NAME 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 SharkLarge:

送信をクリックすると、新しいサメがデータベースのサメコレクションに追加されたことがわかります。

入力したデータがレプリカセットのプライマリメンバーとセカンダリメンバーの間で複製されていることを確認しましょう。

ポッドのリストを取得します。

  1. kubectl get pods
Output
NAME 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の最初のポッドでシェルを作成します。

  1. kubectl exec -it mongo-mongodb-replicaset-0 -- mongo -u your_database_username -p --authenticationDatabase admin

プロンプトが表示されたら、このユーザー名に関連付けられているパスワードを入力します。

Output
MongoDB shell version v4.1.9 Enter password:

管理シェルにドロップされます:

Output
MongoDB server version: 4.1.9 Welcome to the MongoDB shell. ... db:PRIMARY>

プロンプト自体にこの情報が含まれていますが、 rs.isMaster()メソッドを使用して、どのレプリカセットメンバーがプライマリであるかを手動で確認できます。

  1. rs.isMaster()

プライマリのホスト名を示す次のような出力が表示されます。

Output
db: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 データベース:

  1. use sharkinfo
Output
switched to db sharkinfo

データベース内のコレクションを一覧表示します。

  1. show collections
Output
sharks

コレクション内のドキュメントを出力します。

  1. 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シェルを終了します。

  1. exit

プライマリのデータを確認したので、セカンダリにデータが複製されていることを確認しましょう。 kubectl exec の中へ mongo-mongodb-replicaset-1 次のコマンドを使用します。

  1. kubectl exec -it mongo-mongodb-replicaset-1 -- mongo -u your_database_username -p --authenticationDatabase admin

管理シェルに入ったら、を使用する必要があります db.setSlaveOk() セカンダリインスタンスからの読み取り操作を許可するメソッド:

  1. db.setSlaveOk(1)

に切り替えます sharkinfo データベース:

  1. use sharkinfo
Output
switched to db sharkinfo

内のドキュメントの読み取り操作を許可します sharks コレクション:

  1. db.setSlaveOk(1)

コレクション内のドキュメントを出力します。

  1. db.sharks.find()

これで、プライマリインスタンスでこのメソッドを実行したときに表示されたのと同じ情報が表示されます。

Output
db: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リポジトリと他のチャートリポジトリを利用する際の出発点として機能します。

本番環境に移行するときは、次の実装を検討してください。

Helmの詳細については、 Helmの概要、Kubernetesのパッケージマネージャー Helm Package Manager を使用してKubernetesクラスターにソフトウェアをインストールする方法、およびHelmのドキュメントを参照してください。