【ITニュース解説】🚀 Deploying a Node.js Product API on Kubernetes with MongoDB
2025年09月18日に「Dev.to」が公開したITニュース「🚀 Deploying a Node.js Product API on Kubernetes with MongoDB」について初心者にもわかりやすく解説しています。
ITニュース概要
Node.jsとMongoDBで作ったAPIを、コンテナ技術Dockerで動くようにし、Kubernetesというシステムで自動的に動かし続ける方法を解説。外部からのアクセスや負荷に応じた自動増減(オートスケーリング)も設定し、安定稼働するWebサービス基盤を構築する手順を紹介する。
ITニュース解説
現代のアプリケーション開発では、ユーザーの増加に柔軟に対応できるスケーラビリティ、システムの一部に障害が発生しても全体が停止しない強靭さ、そして開発環境と本番環境で同じように動作するポータビリティが非常に重要となる。これらの要件を満たすために、Dockerというコンテナ技術と、そのコンテナ群を効率的に管理するKubernetesというオーケストレーションプラットフォームが広く利用されている。
この記事では、Node.jsで構築した製品情報を取り扱うAPIを例に挙げ、MongoDBというデータベースと連携させながら、Kubernetes上にデプロイする一連の流れを解説する。このデプロイメントを通じて、アプリケーションの自動スケーリング、自己修復、ポータビリティといったKubernetesの強力な利点がどのように実現されるかを学ぶことができる。
今回構築するシステムは、Node.jsとExpressフレームワークを使って製品情報の作成、読み取り、更新、削除(CRUD)を行うREST APIである。データの保存にはMongoDBというNoSQLデータベースを利用し、Mongooseというライブラリを使ってNode.jsアプリケーションとMongoDBの連携を容易にしている。このアプリケーションはDockerという技術を使ってコンテナ化され、Kubernetes上で管理される。Kubernetesのリソースとしては、アプリケーションを実行するための「Deployment」、アプリケーションへの安定したアクセスを可能にする「Service」、外部からのアクセスをクラスター内部にルーティングする「Ingress」、機密情報を安全に保存する「Secrets」、そしてアプリケーションの負荷に応じて自動的にPod(コンテナの実行単位)の数を調整する「Horizontal Pod Autoscaler (HPA)」を利用する。全体のデータフローとしては、クライアントからのリクエストがIngressを通じてKubernetesクラスターに入り、Serviceを介してNode.js APIが動作しているPodへと送られる。Node.js APIは必要に応じてMongoDBと通信し、HPAはPodの負荷を監視して自動的にPodの数を増減させる仕組みである。
まず、Node.js APIの構築から始める。製品情報のスキーマでは、製品名、説明、価格、在庫状況などの属性を定義する。例えば、nameは必須の文字列で、priceは必須の数値かつ0以上といった制約を持つ。APIは/api/productsというエンドポイントでCRUD操作を提供し、HTTP POSTリクエストを使って新しい製品を登録したり、GETリクエストで製品情報を取得したりできる。
次に、このNode.jsアプリケーションをDockerでコンテナ化する。Dockerは、アプリケーションとその実行に必要なすべての要素(コード、ライブラリ、設定など)を一つの自己完結型のパッケージにまとめる技術である。このパッケージをDockerイメージと呼び、その作成指示書がDockerfileである。Dockerfileでは、Node.jsのベースイメージを選び、作業ディレクトリを設定し、package.jsonから必要な依存ライブラリをインストールし、アプリケーションのコードをコピーして、最後にアプリケーションを起動するコマンドを定義する。このDockerイメージをビルドし、ローカル環境で実行することで、Node.js APIがコンテナ内で期待通りに動作するかを確認できる。このとき、MongoDBの接続情報などは環境変数としてコンテナに渡す。
アプリケーションがDockerコンテナとして準備できたら、いよいよKubernetesの登場である。Kubernetesは、これらのDockerコンテナを効率的にデプロイ、管理、スケーリングするための強力なプラットフォームである。Kubernetesは、アプリケーションの実行に必要な設定を「マニフェストファイル」というYAML形式のファイルで定義する。
**Deployment(デプロイメント)**は、アプリケーションのPod(Kubernetesにおけるコンテナの実行単位)を管理するKubernetesの重要なリソースである。ここでは、Node.js APIのコンテナイメージを指定し、何個のPodを同時に実行するか(例: replicas: 2で2つのPod)を設定する。また、コンテナが公開するポートや、MongoDBへの接続情報のような環境変数を定義する。このMongoDBへの接続情報は、後述するSecretsから安全に取得するよう設定する。
**Service(サービス)**は、Pod群への安定したネットワークアクセスを提供する。Deploymentで複数のPodが実行されている場合でも、ServiceはそのPod群全体を単一のアクセスポイントとして抽象化してくれるため、どのPodが動いているかを意識することなくアプリケーションにアクセスできる。ここでは、クラスター内部からのみアクセス可能なClusterIPタイプを設定し、Podのポート5000番をServiceのポート80番にマッピングする。
**Ingress(イングレス)**は、外部からKubernetesクラスター内のServiceへのアクセスを管理する。Serviceがクラスター内部からのアクセスを担当するのに対し、Ingressはインターネット経由など、クラスター外部からのHTTP/HTTPSリクエストをServiceにルーティングする役割を果たす。この設定では、すべてのパス(/)へのリクエストを先ほど定義したproduct-api-svcのポート80番へ転送するように指定する。
**Secrets(シークレット)**は、データベースのパスワードやAPIキーなど、アプリケーションで使う機密情報を安全に管理するためのKubernetesリソースである。機密情報をマニフェストファイルに直接記述するのではなく、Base64でエンコードした形式でSecretに保存し、Deploymentから参照させることで、安全性を高める。例えば、MongoDBの接続URIをSecretとして設定し、Node.jsアプリケーションがこのSecretから接続情報を取得するようにする。
**Horizontal Pod Autoscaler (HPA)**は、アプリケーションの負荷に応じてPodの数を自動的に調整するKubernetesの機能である。この記事では、CPU使用率を基準として自動スケーリングを設定している。例えば、PodのCPU使用率が平均70%を超えた場合、Podの数を自動的に増やし(最大10個まで)、負荷が低下すればPodの数を減らす(最小2個まで)といった設定が可能である。これにより、急なトラフィック増加にもアプリケーションが自動で対応できる。
これらのKubernetesマニフェストファイルが完成したら、いよいよKubernetesクラスターへのデプロイを行う。まず、作成したDockerイメージをDocker HubやAWS ECR、GCP Artifact Registryなどのコンテナレジストリにプッシュする必要がある。これは、KubernetesクラスターがPodを起動する際に、そのイメージを取得できるようにするためである。その後、kubectl apply -f k8s/というコマンドを実行することで、k8sディレクトリ内のすべてのマニフェストファイルがKubernetesクラスターに適用され、DeploymentやService、Ingressなどが作成される。デプロイ後には、kubectl get podsやkubectl get svc、kubectl get ingressといったコマンドで、各リソースの状態や稼働状況を確認できる。全てが正常にデプロイされれば、Ingressのホスト名を使って、インターネット経由でNode.js APIにアクセスし、製品情報のCRUD操作を実行できるようになる。
デプロイが完了した後は、アプリケーションの安定稼働と効率的な運用が求められる。Horizontal Pod Autoscalerは、設定に基づいてPodの数を自動的にスケーリングし続ける。また、Kubernetesには「Liveness Probe(生存プローブ)」と「Readiness Probe(準備完了プローブ)」という機能があり、これらを適切に設定することで、Podが正常に動作しているか、またはリクエストを受け入れる準備ができているかをKubernetesが監視し、異常があれば自動的に再起動したり、トラフィックを遮断したりしてアプリケーションの健全性を保つことができる。さらに、PrometheusやGrafanaといったツールを導入することで、アプリケーションやKubernetesクラスターの状態を詳細に監視し、ログを集中管理するELKスタック(Elasticsearch, Logstash, Kibana)やクラウドプロバイダーのロギングサービス(CloudWatchなど)を活用することで、問題発生時の原因究明やパフォーマンス改善に役立てることができる。
本番環境でこのシステムを運用する際には、さらにいくつかの考慮事項がある。例えば、データベースとして自身で管理するMongoDBではなく、AWS AtlasやAzure Cosmos DB、Google Cloud DocumentDBのようなマネージドサービスを利用することで、運用負荷を軽減し、高い可用性とスケーラビリティを享受できる。また、IngressにはTLS/HTTPSを設定し、通信を暗号化することが必須である。これにはcert-managerとLet’s Encryptなどのツールが利用できる。Secretsの管理も重要であり、Kubernetes Secretsだけでなく、より高度な外部のシークレット管理システムと連携させることも検討される。Podには、どれくらいのCPUやメモリが必要か、また最大でどれくらいまで使用できるかといったリソースリクエストとリミットを定義することで、クラスター全体のリソースを効率的に利用し、安定稼働を促すことができる。最後に、アプリケーションのコード変更からデプロイまでを一連の自動化されたプロセスで行うCI/CD(継続的インテグレーション/継続的デリバリー)パイプラインを構築することで、開発効率と信頼性を大幅に向上させることが可能となる。
このように、Node.jsアプリケーションをDockerでコンテナ化し、KubernetesのDeployment、Service、Ingress、Secretsといった主要なリソースを組み合わせ、さらにHorizontal Pod Autoscalerによる自動スケーリングを導入することで、スケーラブルで回復力があり、本番環境にも耐えうるモダンなマイクロサービス基盤を構築できる。この経験は、クラウドネイティブなアプリケーション開発における重要な第一歩となるだろう。