[Amazon FSx for NetApp ONTAP] ECS上のコンテナからボリュームをマウントしてみた

ECSでハイパフォーマンスな永続ストレージにデータを保存したいときに
2024.02.19

ECSからFSxNのボリュームをマウントする方法を知りたい

こんにちは、のんピ(@non____97)です。

皆さんはECSからAmazon FSx for NetApp ONTAP(以降FSxN)のボリュームをマウントする方法を知りたいなと思ったことはありますか? 私はあります。

データ分析バッチ処理などの高スループット、高IOPSが求められるワークロードやデータの永続化をするためにFSxNのボリュームをマウントしたい場面があります。

「どうやってマウントするのかな?」と調べていると、AWS公式ドキュメントに答えが書いてありました。

どうやらバインドマウントでFSxNのボリュームをマウントするようです。

実際に試してみました。

いきなりまとめ

  • 2024/2/19ではECS on EC2のみ対応
    • ECS on Fargateは非対応
  • バインドマウントでマウントする

やってみた

検証環境構成

検証環境の構成は以下のとおりです。

[Amazon FSx for NetApp ONTAP] ECS上のコンテナからボリュームをマウントしてみた検証環境構成図

FSxNのボリュームは以下のとおりです。

::> volume show -fields security-style, junction-path
vserver volume   security-style junction-path
------- -------- -------------- -------------
svm     svm_root unix           /
svm     vol1     unix           /vol1
2 entries were displayed.

vol1をNFSでマウントします。

ECS on EC2の用意

ECS on EC2を用意します。VPCやFSxNは既にデプロイ済みです。

今回はAWS CDKでデプロイしました。

コンテナインスタンスのユーザーデータでFSxNのボリュームをマウントしてあげて、その領域をバインドマウントします。

./lib/ecs-stack.ts

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";

export class EcsStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const vpcId = "vpc-043c0858ea33e8ec2";
    const sourceVolume = "fsxn-vol1";
    const sourcePath = "/mnt/fsxn/vol1";
    const containerPath = "/vol1";
    const junctionPath = "vol1";
    const nfsDnsName =
      "svm-0a277039fa1e73d6a.fs-0130e4e832527894e.fsx.us-east-1.amazonaws.com";

    // VPC
    const vpc = cdk.aws_ec2.Vpc.fromLookup(this, "Vpc", {
      vpcId,
    });

    // ECS Cluster
    const cluster = new cdk.aws_ecs.Cluster(this, "Cluster", {
      vpc,
      containerInsights: true,
    });

    // Container Instance
    cluster
      .addCapacity("DefaultAutoScalingGroupCapacity", {
        instanceType: new cdk.aws_ec2.InstanceType("t3.small"),
        machineImage: cdk.aws_ec2.MachineImage.fromSsmParameter(
          "/aws/service/ecs/optimized-ami/amazon-linux-2023/recommended/image_id"
        ),
        maxCapacity: 1,
        minCapacity: 1,
        associatePublicIpAddress: true,
        vpcSubnets: { subnetType: cdk.aws_ec2.SubnetType.PUBLIC },
        ssmSessionPermissions: true,
      })
      .userData.addCommands(
        `mkdir -p ${sourcePath}`,
        `echo -e "${nfsDnsName}:${junctionPath}\t${sourcePath}\tnfs\tnfsvers=4,_netdev,noresvport,defaults\t0\t0" | tee -a /etc/fstab`,
        `systemctl daemon-reload`,
        `mount -a`,
        "df -hT"
      );

    // Task Definition
    const taskDefinition = new cdk.aws_ecs.Ec2TaskDefinition(
      this,
      "TaskDefinition"
    );

    taskDefinition.addVolume({
      name: sourceVolume,
      host: {
        sourcePath,
      },
    });

    taskDefinition
      .addContainer("SampleContainer", {
        image: cdk.aws_ecs.ContainerImage.fromRegistry(
          "amazon/amazon-ecs-sample"
        ),
        memoryLimitMiB: 256,
      })
      .addMountPoints({
        sourceVolume,
        containerPath,
        readOnly: false,
      });

    // ECS Service
    new cdk.aws_ecs.Ec2Service(this, "Service", {
      cluster,
      taskDefinition,
      desiredCount: 2,
      circuitBreaker: { enable: true },
      enableExecuteCommand: true,
    });
  }
}

使用したコードは以下リポジトリに保存しています。

デプロイ後にタスク定義を確認すると、バインドマウントの設定がされていました。

タスク定義_ボリューム

FSxNのボリュームをマウントできているか確認

FSxNのボリュームをマウントできているか確認します。

EC2インスタンス上からFSxNのボリュームをマウントできているかです。

$ hostname -f
ip-10-0-0-148.ec2.internal

$ df -hT
Filesystem                                                                   Type      Size  Used Avail Use% Mounted on
devtmpfs                                                                     devtmpfs  4.0M     0  4.0M   0% /dev
tmpfs                                                                        tmpfs     951M     0  951M   0% /dev/shm
tmpfs                                                                        tmpfs     381M  728K  380M   1% /run
/dev/nvme0n1p1                                                               xfs        30G  2.7G   28G   9% /
tmpfs                                                                        tmpfs     951M     0  951M   0% /tmp
/dev/nvme0n1p128                                                             vfat       10M  1.3M  8.7M  13% /boot/efi
svm-0a277039fa1e73d6a.fs-0130e4e832527894e.fsx.us-east-1.amazonaws.com:/vol1 nfs4       61G  448K   61G   1% /mnt/fsxn/vol1

$ cat /etc/fstab
#
UUID=cf7f5187-deab-4eff-bb4b-616b8aa7ddcc     /           xfs    defaults,noatime  1   1
UUID=994B-8B56        /boot/efi       vfat    defaults,noatime,uid=0,gid=0,umask=0077,shortname=winnt,x-systemd.automount 0 2
svm-0a277039fa1e73d6a.fs-0130e4e832527894e.fsx.us-east-1.amazonaws.com:vol1     /mnt/fsxn/vol1  nfs     nfsvers=4,_netdev,noresvport,defaults   0       0

$ ls -l /mnt/fsxn/vol1
total 0

$ ls -ld /mnt/fsxn/vol1
drwxr-xr-x. 2 root root 4096 Feb 19 08:17 /mnt/fsxn/vol1

マウントできていました。

適当にファイルを追加します。

$ sudo touch /mnt/fsxn/vol1/container_instance.txt

$ ls -l /mnt/fsxn/vol1
total 0
-rw-r--r--. 1 root root 0 Feb 19 08:17 container_instance.txt

ECS Execでコンテナに接続します。

$ aws ecs execute-command \
  --cluster EcsStack-ClusterEB0386A7-lrNwJL7PjHYZ \
  --task 3e6614aa5dc74daebbbf1f4703b1d36c \
  --container SampleContainer \
  --interactive \
  --command "/bin/sh"
$ df -hT
Filesystem                                                                   Type     Size  Used Avail Use% Mounted on
overlay                                                                      overlay   30G  2.7G   28G  10% /
tmpfs                                                                        tmpfs     64M     0   64M   0% /dev
svm-0a277039fa1e73d6a.fs-0130e4e832527894e.fsx.us-east-1.amazonaws.com:/vol1 nfs4      61G  448K   61G   1% /vol1
/dev/nvme0n1p1                                                               xfs       30G  2.7G   28G  10% /etc/hosts
shm                                                                          tmpfs     64M     0   64M   0% /dev/shm
tmpfs                                                                        tmpfs    951M     0  951M   0% /proc/acpi
tmpfs                                                                        tmpfs    951M     0  951M   0% /sys/firmware

$ ls -ld /vol1
drwxr-xr-x. 2 root root 4096 Feb 19 08:17 /vol1

$ ls -l /vol1
total 0
-rw-r--r--. 1 root root 0 Feb 19 08:17 container_instance.txt

ECSのコンテナ上でもEC2インスタンスから作成されたファイルを確認できました。

さらに適当にファイルを追加します。

$ touch /vol1/3e6614aa5dc74daebbbf1f4703b1d36c.txt

$ ls -l /vol1
total 0
-rw-r--r--. 1 root root 0 Feb 19 08:25 3e6614aa5dc74daebbbf1f4703b1d36c.txt
-rw-r--r--. 1 root root 0 Feb 19 08:17 container_instance.txt

別のコンテナにもECS Execで接続します。

$ aws ecs execute-command \
  --cluster EcsStack-ClusterEB0386A7-lrNwJL7PjHYZ \
  --task c482c7b3dcd248d6a8bac2b437bd90a5 \
  --container SampleContainer \
  --interactive \
  --command "/bin/sh"
$ df -hT
Filesystem                                                                   Type     Size  Used Avail Use% Mounted on
overlay                                                                      overlay   30G  2.7G   28G  10% /
tmpfs                                                                        tmpfs     64M     0   64M   0% /dev
svm-0a277039fa1e73d6a.fs-0130e4e832527894e.fsx.us-east-1.amazonaws.com:/vol1 nfs4      61G  384K   61G   1% /vol1
/dev/nvme0n1p1                                                               xfs       30G  2.7G   28G  10% /etc/hosts
shm                                                                          tmpfs     64M     0   64M   0% /dev/shm
tmpfs                                                                        tmpfs    951M     0  951M   0% /proc/acpi
tmpfs                                                                        tmpfs    951M     0  951M   0% /sys/firmware

$ ls -ld /vol1
drwxr-xr-x. 2 root root 4096 Feb 19 08:25 /vol1

$ ls -l /vol1
total 0
-rw-r--r--. 1 root root 0 Feb 19 08:25 3e6614aa5dc74daebbbf1f4703b1d36c.txt
-rw-r--r--. 1 root root 0 Feb 19 08:17 container_instance.txt

$ touch /vol1/c482c7b3dcd248d6a8bac2b437bd90a5.txt
$ ls -l /vol1
total 0
-rw-r--r--. 1 root root 0 Feb 19 08:25 3e6614aa5dc74daebbbf1f4703b1d36c.txt
-rw-r--r--. 1 root root 0 Feb 19 08:27 c482c7b3dcd248d6a8bac2b437bd90a5.txt
-rw-r--r--. 1 root root 0 Feb 19 08:17 container_instance.txt

コンテナ間、コンテナ-EC2インスタンス間で同じ領域を参照していることを確認できました。

ECSタスク入れ替え後の確認

ECSタスクを入れ替えても継続してボリュームに書き込んだファイルを確認できるかチェックします。

stop all tasks

新しいタスクが立ち上がったことを確認します。

新しいタスクが立ち上がったことを確認

ECS Execでコンテナに入り、変わらずマウントできていることを確認します。

aws ecs execute-command \
  --cluster EcsStack-ClusterEB0386A7-lrNwJL7PjHYZ \
  --task 0ece3561f98d433a9add51d4be2038c6 \
  --container SampleContainer \
  --interactive \
  --command "/bin/sh"
$ df -hT
Filesystem                                                                   Type     Size  Used Avail Use% Mounted on
overlay                                                                      overlay   30G  2.7G   28G  10% /
tmpfs                                                                        tmpfs     64M     0   64M   0% /dev
svm-0a277039fa1e73d6a.fs-0130e4e832527894e.fsx.us-east-1.amazonaws.com:/vol1 nfs4      61G  448K   61G   1% /vol1
/dev/nvme0n1p1                                                               xfs       30G  2.7G   28G  10% /etc/hosts
shm                                                                          tmpfs     64M     0   64M   0% /dev/shm
tmpfs                                                                        tmpfs    951M     0  951M   0% /proc/acpi
tmpfs                                                                        tmpfs    951M     0  951M   0% /sys/firmware

$ ls -l /vol1
total 0
-rw-r--r--. 1 root root 0 Feb 19 08:25 3e6614aa5dc74daebbbf1f4703b1d36c.txt
-rw-r--r--. 1 root root 0 Feb 19 08:27 c482c7b3dcd248d6a8bac2b437bd90a5.txt
-rw-r--r--. 1 root root 0 Feb 19 08:17 container_instance.txt

マウントできていますね。

EC2インスタンス入れ替え後の確認

EC2インスタンス入れ替え後の確認も行います。

コンテナインスタンスを停止させます。

EC2インスタンスの停止

Auto Scalingにより、新しくEC2インスタンスが立ち上がったことを確認します。

EC2インスタンスが起動してきたことを確認

新しく立ち上がったコンテナインスタンスにSSMセッションマネージャーで接続し、FSxNのボリュームをマウントできているか確認します。

$ hostname -f
ip-10-0-1-156.ec2.internal

$ df -hT
Filesystem                                                                   Type      Size  Used Avail Use% Mounted on
devtmpfs                                                                     devtmpfs  4.0M     0  4.0M   0% /dev
tmpfs                                                                        tmpfs     951M     0  951M   0% /dev/shm
tmpfs                                                                        tmpfs     381M  520K  380M   1% /run
/dev/nvme0n1p1                                                               xfs        30G  2.3G   28G   8% /
tmpfs                                                                        tmpfs     951M     0  951M   0% /tmp
/dev/nvme0n1p128                                                             vfat       10M  1.3M  8.7M  13% /boot/efi
svm-0a277039fa1e73d6a.fs-0130e4e832527894e.fsx.us-east-1.amazonaws.com:/vol1 nfs4       61G  448K   61G   1% /mnt/fsxn/vol1

$ ls -l /mnt/fsxn/vol1
total 0
-rw-r--r--. 1 root root 0 Feb 19 08:25 3e6614aa5dc74daebbbf1f4703b1d36c.txt
-rw-r--r--. 1 root root 0 Feb 19 08:27 c482c7b3dcd248d6a8bac2b437bd90a5.txt
-rw-r--r--. 1 root root 0 Feb 19 08:17 container_instance.txt

$ sudo docker ps
CONTAINER ID   IMAGE                            COMMAND    CREATED         STATUS                   PORTS     NAMES
6997752d6174   amazon/amazon-ecs-agent:latest   "/agent"   4 minutes ago   Up 4 minutes (healthy)             ecs-agent

$ sudo docker ps -a
CONTAINER ID   IMAGE                            COMMAND                  CREATED          STATUS                   PORTS     NAMES
3f871a0b5c27   amazon/amazon-ecs-sample         "/usr/sbin/apache2 -…"   20 seconds ago   Up 19 seconds            80/tcp    ecs-EcsStackTaskDefinition458D056A-16-SampleContainer-d4c2a3d3c8bbe5c00e00
6f38d7fed62d   amazon/amazon-ecs-sample         "/usr/sbin/apache2 -…"   20 seconds ago   Up 18 seconds            80/tcp    ecs-EcsStackTaskDefinition458D056A-16-SampleContainer-9cd3d892c89b87a88601
6997752d6174   amazon/amazon-ecs-agent:latest   "/agent"                 5 minutes ago    Up 5 minutes (healthy)             ecs-agent

新しいコンテナインスタンス上で稼動しているコンテナにECS Execで接続します。

$ aws ecs execute-command \
  --cluster EcsStack-ClusterEB0386A7-lrNwJL7PjHYZ \
  --task 741cc4b4ae2b43c182c95e3563c032e6 \
  --container SampleContainer \
  --interactive \
  --command "/bin/sh"
$ df -hT
Filesystem                                                                   Type     Size  Used Avail Use% Mounted on
overlay                                                                      overlay   30G  2.7G   28G  10% /
tmpfs                                                                        tmpfs     64M     0   64M   0% /dev
svm-0a277039fa1e73d6a.fs-0130e4e832527894e.fsx.us-east-1.amazonaws.com:/vol1 nfs4      61G  448K   61G   1% /vol1
/dev/nvme0n1p1                                                               xfs       30G  2.7G   28G  10% /etc/hosts
shm                                                                          tmpfs     64M     0   64M   0% /dev/shm
tmpfs                                                                        tmpfs    951M     0  951M   0% /proc/acpi
tmpfs                                                                        tmpfs    951M     0  951M   0% /sys/firmware

$ ls -l /vol1
total 0
-rw-r--r--. 1 root root 0 Feb 19 08:25 3e6614aa5dc74daebbbf1f4703b1d36c.txt
-rw-r--r--. 1 root root 0 Feb 19 08:27 c482c7b3dcd248d6a8bac2b437bd90a5.txt
-rw-r--r--. 1 root root 0 Feb 19 08:17 container_instance.txt

コンテナ上からもFSxNのボリューム内のファイルを確認できました。永続化できていますね。

ECSでハイパフォーマンスな永続ストレージにデータを保存したいときに

ECS on EC2においてFSxNのボリュームにNFSでマウントする方法を紹介しました。

ECSでハイパフォーマンスな永続ストレージにデータを保存したいときにお世話になりそうです。EFSやS3、FSx for Windows File Serverとの費用対効果を比較して、最適化なストレージを選択しましょう。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!