モード変更


    言語

サーバーレスとコンテナの適切な利用とハイブリッドの考え方

2024/06/21

はじめに

現代のクラウドコンピューティングの世界では、アプリケーションのデプロイや管理の方法が多様化しています。特に注目されるのがサーバーレスとコンテナ技術です。これらの技術の違いや、それぞれの適切な利用シーンについて解説します。

サーバーレスとは

サーバーレスは、開発者がインフラの管理を意識することなく、コードの実行に集中できるようにするものです。主な特徴として以下の点が挙げられます。

  • サーバーの抽象化:開発者はサーバーを直接管理する必要がありません。
  • イベント駆動型の実行:イベントが発生したときにコードが実行されます。
  • 自動スケーリング:需要に応じて自動的にスケールします。
  • 料金体系:実行時間と使用リソースに基づいて料金が発生します。

代表的なものは、AWS Lambda、Azure Functions、Google Cloud Functionsなどがあります。

コンテナとは

コンテナは、アプリケーションとその依存関係を一緒にパッケージ化し、一貫した実行環境を提供する技術です。主な特徴として以下の点が挙げられます。

  • 軽量でポータブル:どの環境でも一貫して動作します。
  • 隔離されたアプリケーション実行:他のアプリケーションから隔離された環境で実行されます。
  • 開発と本番環境の一貫性:開発環境と本番環境で同じコンテナを使用できます。

代表的なものは、AWS ECS、EKS、Kubernetesなどがあります。

比較

サーバーレスとコンテナは、それぞれの特徴によって異なるメリットとデメリットがあります。以下にそれぞれの比較を示します。

デプロイと管理

  • サーバーレス:クラウドプロバイダーによって管理され、インフラストラクチャの管理は不要です。
  • コンテナ:コンテナオーケストレーションの管理が必要で、任意のインフラストラクチャで実行可能です。

スケーラビリティ

  • サーバーレス:需要に応じて自動的にスケールします。
  • コンテナ:オーケストレーションツールでスケールしますが、設定が必要です。

コスト

  • サーバーレス:実行ごとに課金され、変動するワークロードに対してコスト効果が高いです。
  • コンテナ:稼働中のインスタンスに対して課金され、安定した高スループットのワークロードに対してコスト効果が高いです。

ユースケース

  • サーバーレス:短期間での実行、ステートレスなアプリケーション、イベント駆動型アーキテクチャ、リアルタイム処理、マイクロサービスに適しています。
  • コンテナ:長期間の実行、複雑なマイクロサービスアーキテクチャ、レガシーアプリケーションのモダナイズ、一貫したランタイムが必要な環境に適しています。

メリットとデメリット

サーバーレス

  • メリット:サーバー管理不要、自動スケーリング、バーストワークロードに対してコスト効果が高い。
  • デメリット:コールドスタート遅延、実行時間の制限、環境の制御が少ない。

コンテナ

  • メリット:環境の制御が高い、一貫した駆動環境。
  • デメリット:管理の複雑さ、運用のオーバーヘッドが高い。

サーバーレスとコンテナの選択は、アプリケーションの要件、開発者のスキル、予算、セキュリティ要件などに依存します。特に、サーバーレスは短期間の実行やイベント駆動型アーキテクチャに適しています。一方、コンテナは長期間の実行や複雑なマイクロサービスアーキテクチャに適しています。インフラプロバイダーによって提供されるサーバーレスプラットフォームやコンテナオーケストレーションプラットフォームを比較し、適切な選択を行うことが重要です。

ハイブリッドアプローチ

システムによっては、サーバーレスとコンテナの両方を組み合わせることが有効な場合があります。例えば、サーバーレス関数を使用してイベント駆動型の処理を行い、コンテナを使用して長期間の実行や複雑なマイクロサービスを実行することができます。このようなハイブリッドアプローチは、アプリケーションの要件に応じて柔軟に対応できる利点があります。

その実装の例を少し紹介すると、サーバーレス関数をトリガーとしてコンテナを起動することができます。このようなアーキテクチャは、サーバーレスとコンテナの両方の利点を組み合わせることができます。

実装サンプル

以下は、TerraformとECSでコンテナを管理し、Serverless FrameworkとAPI GatewayでAPIを提供するサーバーレスとコンテナのハイブリッドアーキテクチャのコードのサンプルです。その間にSQSを使用してイベント駆動型の処理を行います。

# serverless.yml
service: example-service

provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: us-east-1

functions:
  longRunningTask:
    handler: index.longRunningTaskHandler
    events:
      - sqs:
          arn:
            Fn::GetAtt:
              - LongRunningTaskQueue
              - Arn

  shortRunningTask:
    handler: index.shortRunningTaskHandler
    events:
      - http:
          path: short-task
          method: post

resources:
  Resources:
    LongRunningTaskQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: long-running-task-queue
    ShortRunningTaskApi:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Name: short-running-task-api
# main.tf
provider "aws" {
  region = "us-east-1"
}

resource "aws_ecs_cluster" "example" {
  name = "example-cluster"
}

resource "aws_ecs_task_definition" "example" {
  family = "long-task"
  container_definitions = jsonencode([
    {
      name = "long-task-container"
      image = "some-long-task-image"
      cpu = 256
      memory = 512
    }
  ])
}

resource "aws_ecs_service" "example" {
  name = "long-task-service"
  cluster = aws_ecs_cluster.example.id
  task_definition = aws_ecs_task_definition.example.arn
  desired_count = 1
}
// index.js
const AWS = require('aws-sdk');
const ecs = new AWS.ECS();
const env = process.env;

exports.longRunningTaskHandler = async (event) => {
  // some logic to handle long running task
  // ...

  // params for starting ECS Task
  const params = {
    cluster: env.ECS_CLUSTER_NAME,
    taskDefinition: env.ECS_TASK_DEFINITION_ARN,
    count: 1,
    launchType: 'FARGATE',
    networkConfiguration: {
      awsvpcConfiguration: {
        subnets: [env.SUBNET_ID],
      },
    },
  };

  try {
    // start ECS Task
    const data = await ecs.runTask(params).promise();
    console.log('ECS Task started:', data);

    // return response
    return {
      statusCode: 200,
      body: JSON.stringify('ECS Task started successfully'),
    };
  } catch (error) {
    // handle error
    console.error('Error starting ECS Task:', error);

    // return error response
    return {
      statusCode: 500,
      body: JSON.stringify('Error starting ECS Task'),
    };
  }
};

exports.shortRunningTaskHandler = async (event) => {
  // some logic to handle short running task
  // ...

  // if you need to run long running task in handler, send message to SQS
  // you can consider using AWS Step functions, SNS or EventBridge as well
  const sqs = new AWS.SQS();
  const params = {
    MessageBody: JSON.stringify({ key: 'value' }),
    QueueUrl: env.LONG_TASK_QUEUE_URL,
  };
  await sqs.sendMessage(params).promise();

  // return response
  const response = {
    statusCode: 200,
    body: JSON.stringify('Short running task completed successfully'),
  };
  return response;
};

まとめ

  • サーバーレスはサーバーの管理を意識せずにコードを実行できる。
  • コンテナはアプリケーションとその依存関係をパッケージ化し、一貫した実行環境を提供する。
  • サーバーレスとコンテナの選択はアプリケーションの要件に依存する。
  • ハイブリッドアプローチはサーバーレスとコンテナの両方を組み合わせることができる。

両方の技術を理解し、適切に利用することで、クラウドネイティブなアプリケーションを設計・構築することができます。サーバーレスとコンテナの適切な利用とハイブリッドアプローチを検討し、アプリケーションの要件に応じて最適な選択を行いましょう。

serverlesscontainer

Author

Gwanmuk Kang

Gwanmuk Kang

Backend engineer

Backend and Infra engineer with architecture

その他おすすめ記事

2024/11/05

エンタープライズデータ基盤における dbt の活用戦略

近年、データ駆動型の意思決定が企業の競争力を左右する重要な要素となっており、大規模かつ複雑なデータ基盤の構築が不可欠となっています。この潮流の中で、dbt(data build tool)は、エンタープライズレベルのデータ変換とモデリングを効率化する強力なツールとして注目を集めています。 dbt は、SQL を使用してデータ変換を定義し、バージョン管理、テスト、ドキュメンテーションを統合的に行うことができるオープンソースツールです。特に以下の点で、エンタープライズデータ基盤の構築に大きな価値をもたらします...

Yoshiaki Sano

Yoshiaki Sano

Architecture

2024/11/04

データエンジニアリング初心者でも分かる!dbtの魅力と基本

データ駆動型ビジネスが当たり前となった今日、多くの企業がデータ分析の課題に直面しています。複雑な SQL クエリの管理、データの整合性確保、分析プロセスの再現性など、様々な問題が山積みです。そんな中で注目を集めているのが「dbt(data build tool)」です。 本記事では、データエンジニアリングの深い知識がなくても理解できるよう、dbt の基本と魅力について解説します。 dbt とは? dbt は、SQL を中心としたデータ変換ワークフローを管理するためのオープンソースツールです。従来の SQL...

Yoshiaki Sano

Yoshiaki Sano

Architecture

サービス開発実績会社情報
採用情報インサイトお問い合わせ
© 2022 Monstarlab
情報セキュリティ基本方針個人情報の取り扱いについて個人情報保護方針