簡體   English   中英

將 EBS 卷(不是快照)掛載到 Elastic Beanstalk EC2

[英]Mount a EBS volume (not snapshot) to Elastic Beanstalk EC2

我正在將遺留應用程序遷移到 Elastic Beanstalk。 它需要持久存儲(暫時)。 我想掛載 EBS 卷。

我希望以下內容可以在.ebextensions/ebs.config中使用:

commands:
  01mkdir:
    command: "mkdir /data"
  02mount:
    command: "mount /dev/sdh /data"

option_settings:
  - namespace: aws:autoscaling:launchconfiguration
    option_name: BlockDeviceMappings
    value: /dev/sdh=vol-XXXXX

https://blogs.aws.amazon.com/application-management/post/Tx224DU59IG3OR9/Customize-Ephemeral-and-EBS-Volumes-in-Elastic-Beanstalk-Environments

但不幸的是,我收到以下錯誤消息“參數 snapshotId 的 (vol-XXXX) 無效。應為:'snap-...'。”

很明顯,這種方法只允許快照。 任何人都可以建議修復或替代方法。

我找到了解決方案。 可以通過刪除“sleep 10”來改進它,但不幸的是,因為aws ec2 attach-volume是異步的並且在附件發生之前立即返回。

container_commands:
  01mount:
    command: "aws ec2 attach-volume --volume-id vol-XXXXXX --instance-id $(curl -s http://169.254.169.254/latest/meta-data/instance-id) --device /dev/sdh"
    ignoreErrors: true
  02wait:
    command: "sleep 10"
  03mkdir:
    command: "mkdir /data"
    test: "[ ! -d /data ]"
  04mount:
    command: "mount /dev/sdh /data"
    test: "! mountpoint -q /dev/sdh"

注意。 理想情況下,它將在commands部分運行而不是container_commands但環境變量未及時設置。

要添加到@ Simon的答案(以避免陷入困境的陷阱):

  • 如果正在安裝的持久存儲最終將在Docker容器中使用(例如,如果您正在運行Jenkins並希望保留jenkins_home),則需要在運行mount之后重新啟動docker容器。
  • 您需要對EB假設角色策略中的EC2實例(或實例/ * ARN)和要附加的卷(或卷/ * ARN)允許“ec2:AttachVolumes”操作。 如果沒有這個, aws ec2 attach-volume命令將失敗。
  • 您還需要將--region傳遞給aws ec2 ...命令(至少在撰寫本文時)

或者,您可以考慮使用彈性文件系統(EFS)存儲,而不是使用EBS卷。 AWS已發布了一個腳本,介紹如何將EFS卷安裝到Elastic Beanstalk EC2實例,並且它還可以同時附加到多個EC2實例(這對於EBS是不可能的)。

http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/services-efs.html

這是一個可以放入.ebextensions的配置文件。 您需要提供要附加的VOLUME_ID 測試命令使得只能根據需要進行連接和安裝,以便您可以重復進行eb deploy而不會出現錯誤。

container_commands:
  00attach:
    command: |
      export REGION=$(/opt/aws/bin/ec2-metadata -z | awk '{print substr($2, 0, length($2)-1)}')
      export INSTANCE_ID=$(/opt/aws/bin/ec2-metadata -i | awk '{print $2}')
      export VOLUME_ID=$(aws ec2 describe-volumes --region ${REGION} --output text --filters Name=tag:Name,Values=tf-trading-prod --query 'Volumes[*].VolumeId')

      aws ec2 attach-volume --region ${REGION} --device /dev/sdh --instance-id ${INSTANCE_ID} --volume-id ${VOLUME_ID}
      aws ec2 wait volume-in-use --region ${REGION} --volume-ids ${VOLUME_ID}
      sleep 1
    test: "! file -E /dev/xvdh"
  01mkfs:
    command: "mkfs -t ext3 /dev/xvdh"
    test: "file -s /dev/xvdh | awk '{print $2}' | grep -q data"
  02mkdir:
    command: "mkdir -p /data"
  03mount:
    command: "mount /dev/xvdh /data"
    test: "! mountpoint /data"

必須使用container_commands因為當commands運行時源包還沒有完全解壓。

.ebextensions/whatever.config

container_commands:
  chmod:
    command: chmod +x .platform/hooks/predeploy/mount-volume.sh

預部署掛鈎在容器命令之后但在部署之前運行。 無需重新啟動您的 docker 容器,即使它在附加的 ebs 卷上安裝了一個目錄,因為 beanstalk 在預部署掛鈎完成后將其旋轉起來。 您可以在日志中看到它。

.platform/hooks/predeploy/mount-volume.sh

#!/bin/sh

# Make sure LF line endings are used in the file, otherwise there would be an error saying "file not found".

# All platform hooks run as root user, no need for sudo.

# Before attaching the volume find out the root volume's name, so that we can later use it for filtering purposes.
# -d – to filter out partitions.
# -P – to display the result as key-value pairs.
# -o – to output only the matching part.
# lsblk strips the "/dev/" part
ROOT_VOLUME_NAME=$(lsblk -d -P | grep -o 'NAME="[a-z0-9]*"' | grep -o '[a-z0-9]*')

aws ec2 attach-volume --volume-id vol-xxx --instance-id $(curl -s http://169.254.169.254/latest/meta-data/instance-id) --device /dev/sdf --region us-east-1
# The above command is async, so we need to wait.
aws ec2 wait volume-in-use --volume-ids vol-xxx --region us-east-1

# Now lsblk should show two devices. We figure out which one is non-root by filtering out the stored root volume name.
NON_ROOT_VOLUME_NAME=$(lsblk -d -P | grep -o 'NAME="[a-z0-9]*"' | grep -o '[a-z0-9]*' | awk -v name="$ROOT_VOLUME_NAME" '$0 !~ name')

FILE_COMMAND_OUTPUT=$(file -s /dev/$NON_ROOT_VOLUME_NAME)

# Create a file system on the non-root device only if there isn't one already, so that we don't accidentally override it.
if test "$FILE_COMMAND_OUTPUT" = "/dev/$NON_ROOT_VOLUME_NAME: data"; then
  mkfs -t xfs /dev/$NON_ROOT_VOLUME_NAME
fi

mkdir /data

mount /dev/$NON_ROOT_VOLUME_NAME /data

# Need to make sure that the volume gets mounted after every reboot, because by default only root volume is automatically mounted.

cp /etc/fstab /etc/fstab.orig

NON_ROOT_VOLUME_UUID=$(lsblk -d -P -o +UUID | awk -v name="$NON_ROOT_VOLUME_NAME" '$0 ~ name' | grep -o 'UUID="[-0-9a-z]*"' | grep -o '[-0-9a-z]*')

# We specify 0 to prevent the file system from being dumped, and 2 to indicate that it is a non-root device.
# If you ever boot your instance without this volume attached, the nofail mount option enables the instance to boot
# even if there are errors mounting the volume.
# Debian derivatives, including Ubuntu versions earlier than 16.04, must also add the nobootwait mount option.
echo "UUID=$NON_ROOT_VOLUME_UUID /data xfs defaults,nofail 0 2" | tee -a /etc/fstab

很確定我用grepawk做的事情可以用更簡潔的方式完成。 我不太擅長 Linux。

實例配置文件應包括以下權限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:AttachVolume",
                "ec2:DetachVolume",
                "ec2:DescribeVolumes"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:volume/*",
                "arn:aws:ec2:*:*:instance/*"
            ]
        }
    ]
}

您必須確保將 ebs 卷部署在與 beantalk 相同的 AZ 中,並且您使用 SingleInstance 部署。 然后,如果您的實例崩潰,ASG 將終止它,創建另一個實例,並將卷附加到新實例以保留所有數據。

這是缺少配置:

commands:
  01mount:
    command: "export AWS_ACCESS_KEY_ID=<replace by your AWS key> && export AWS_SECRET_ACCESS_KEY=<replace by your AWS secret> && aws ec2 attach-volume --volume-id <replace by you volume id> --instance-id $(curl -s http://169.254.169.254/latest/meta-data/instance-id) --device /dev/xvdf --region <replace with your region>"
    ignoreErrors: true
  02wait:
    command: "sleep 10"
  03mkdir:
    command: "mkdir /home/lucene"
    test: "[ ! -d /home/lucene ]"
  04mount:
    command: "mount /dev/xvdf /home/lucene"
    test: "! mountpoint -q /dev/xvdf"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM