VMImport時に必見!VMイメージをS3へ分割アップロード

記事タイトルとURLをコピーする

春らしくなるかと思いきや、まだまだ肌寒い日が続いておりますが、みなさまいかがお過ごしでしょうか。
技術4課の酒井です。

VM Importを利用する時イメージファイルが大きくなってしまいアップロード時に利用されている回線を圧迫し他の業務に影響するかもと懸念されることがあるかと思います。
そのような場合アップロードする端末で通信速度を絞ってネットワーク全体の不可を減らす方法があります。
例えばWindowsの場合ですと以下のような手順で端末側で通信速度を絞ることが可能です。
http://blog.serverworks.co.jp/tech/2017/01/20/win2016-bandwidth-control/

通信速度を絞って回避するやり方とは別の手段として、イメージファイルを分割し、業務時間外などの回線に余裕のある時間帯などに、分割したファイルをS3にアップロードしアップロード完了後にS3で結合することが可能です。

また、分割したファイルを並列でS3にアップロードすることで、より早くアップロード完了を見込めることもあります。

その他の利点としては、アップロードに失敗した時に最初からやり直しにならず、失敗したファイルだけ再度アップロードすることで失敗した際の影響を少なくすることもできます。
今回は、分割アップロードの方法としてsplitコマンドとAWS CLIを利用したS3へのmultipart-uploadの方法をご紹介します。

前提条件

今回ご案内する内容はAmazon LinuxもしくはmacOSでAWS CLIのインストールとセットアップが完了した環境が前提となります。
Windowsについては未確認ではありますが、ファイル分割以外の手順はAWS CLIを利用するので今回紹介する手順と同じような要領でできるかもしれません。

splitコマンドでファイル分割

split -b 100m {FILE_NAME}

このコマンドでは対象ファイルを100MB単位で分割しています。
-b オプションに与える数値を変更することで分割したファイルサイズを変更することが可能です。
オプションの詳細な情報はコマンドのmanをご確認ください。

分割されたファイルはxaaから順番にxab,xbcと行った名前で分割されます。

multipart-uploadを作成

AWS CLIで以下のコマンドを実行します。

aws s3api create-multipart-upload --bucket {BUCKET_NAME} --key {FILE_NAME}

コマンドの実行に成功すると以下のように UploadId が表示されます。

{
    "UploadId": "vW7sKQEIfvKbhnxFAmkbY1LX9HzttFZdF94Aulh5sfYf1X0jdYEgXrKx5r.l2h_dn3p6K03v2BVZ_vxQ1je2oZfT4Axlep8M0bOjVJVwUPvueuMvOYp8a.n5xlbgxXj8aB2cnlk9mK7eAnv_A2aqhw--",
    "Key": "{FILE_NAME}",
    "Bucket": "{BUCKET_NAME}"
}
※こちらは出力例でございますので作業時は必ず表示された`UploadId`をご利用ください。

このUploadIdは分割ファイルをアップロードする際に利用致しますのでコピーアンドペースト等でメモしておいてください。

分割したファイルのアップロード

以下のコマンドを実行し分割したファイルを一つづつアップロードします。

upload_id="{UPLOAD_ID}"

aws s3api upload-part --bucket {BUCKET_NAME} --key {FILE_NAME}  --upload-id $upload_id --part-number {COUNT_NUMBER} --body {SPLIT_FILE_NAME}

ぞれぞれのオプションの引数には次の内容を指定します。

  • --bucket create-multipart-uploadで指定したバケットと同じバケット名
  • --key create-multipart-uploadで指定したkeyと同じファイル名
  • --upload-id create-multipart-upload実行時表示されたUploadId
  • --part-number 1からはじめ順番に1づつ増やす形で値を設定します。
  • --body は分割したファイルのファイル名を指定します。

upload_idについては今後なんども利用することや1行がかなり長くなってしまうので変数として格納して利用すると便利です。

分割ファイルが正常にアップロードできた場合以下のような形でETagの情報が返却されます。

{
    "ETag": "\"26645a0391a7c4e2860277d935c8456b\""
}

このEtagは結合コマンド実行時に必要な情報となりますため確実にメモしておいてください。

ファイル結合用JSONの作成

分割ファイルアップロード時に返却されたETagの情報を利用してS3上でファイル結合させるためのjsonファイルを作成します。

注意点としてjsonファイルのPartNumberと--part-numberで渡した数値は一致させる必要があるのでご注意ください。

以下はサンプルのjsonとなります。

{
  "Parts": [
    {
        "ETag": "\"26645a0391a7c4e2860277d935c8456b\"",
        "PartNumber": 1
    },
    {
        "ETag": "\"98dfdca997ad9d6e3264b4fe9d6ab6f4\"",
        "PartNumber": 2
    },
    {
        "ETag": "\"9c3085286e19b9b6f8d85a48802300f4\"",
        "PartNumber": 3
    },
    {
        "ETag": "\"2ad563a78c7e3b39fb5b5cc58a217991\"",
        "PartNumber": 4
    },
    {
        "ETag": "\"86df4c83aa3fb5e29719bb4e30b52d6e\"",
        "PartNumber": 5
    },
    {
        "ETag": "\"b3355635d14204087f8c760a586ad42e\"",
        "PartNumber": 6
    },
    {
        "ETag": "\"5aefbbc27d96f01b5226469d96b1fb0e\"",
        "PartNumber": 7
    },
    {
        "ETag": "\"6f555bac37b336389d827c4cd5d614b6\"",
        "PartNumber": 8
    },
    {
        "ETag": "\"82432f2f0710036a2bbf7a38184e9dda\"",
        "PartNumber": 9
    },
    {
        "ETag": "\"26aee2798d0a15900cf6204f62da3989\"",
        "PartNumber": 10
    },
    {
        "ETag": "\"abe0f8d0dafa725f237f026e311c14dc\"",
        "PartNumber": 11
    },
    {
        "ETag": "\"82d23cf72fbd94b6b14d5c8a14cdde48\"",
        "PartNumber": 12
    },
    {
        "ETag": "\"2f5cda2139ca235760a0dcfd15618f1d\"",
        "PartNumber": 13
    },
    {
        "ETag": "\"c2483301c06779266f847789159c59a3\"",
        "PartNumber": 14
    },
    {
        "ETag": "\"b1bf3d83a1a754298c3c6a9056ea1b51\"",
        "PartNumber": 15
    }
  ]
}

ファイルの結合

全ての分割ファイルのアップロードが完了しjsonファイルも用意できれば
以下のコマンドを利用して分割アップロードしたファイルを結合させます。

aws s3api complete-multipart-upload --bucket {BUCKET_NAME} --key {FILE_NAME} --multipart-upload file://multipart-upload.json --upload-id $upload_id

成功した場合以下のような結果が表示されます。

{
    "ETag": "\"{ETag}\"",
    "Bucket": "{BUCKET_NAME}",
    "Location": "https://{BUCKET_NAME}/{FILE_NAME}",
    "Key": "{FILE_NAME}"
}

ファイルの確認

以下のコマンドを実行しS3上でファイルが存在すること確認できれば分割アップロードは成功です。

aws s3 ls s3://{BUCKET_NAME}/{FILE_NAME}

VM Importの実施

分割アップロードを利用してアップロードしたイメージファイルを指定してVM Importを実行します。
ここでエラーなどが発生せずタスクが進めば成功となります。

VM Importの詳細な手順についてはこちらのブログで紹介しておりますので併せてご確認いただけると幸いです。
http://blog.serverworks.co.jp/tech/2016/12/29/import-image/

まとめ

分割アップロードを利用することでより柔軟に大きなイメージファイルをS3へとアップロードすることができます。
また、より簡単に分割アップロードを行う方法としてはAWSCLIの aws s3 cp を利用する方法があります。
こちらはアップロードタイミングはコントロールできませんがそのぶん分割や結合を自動でやってくれお手軽に実行することが可能です。

どちらの方法もVM Importを行うときのイメージアップロードの手段の一つとして知っていただければ幸いです。