EC2 instance起動時にtagをつけるTagSpecifications

AWSCLIでEC2 instance起動時に同時にタグをつける方法としては、instance起動してinstance-idを取得しておいて、パイプでつないでtagをつけたり、スクリプトの中で後でタグ付けする方法があったと思います。
http://kurochan-note.hatenablog.jp/entry/2017/01/08/220155

AWSCLI EC2 Run-Instanceのなかに–tag-specificationsというoptionが入って、run-instancesの中でタグが作成できるようになりました。地味なアップデートかもしれませんが、結構うれしいです。

instanceの詳細はjsonに記述して、下記のように指定して実行します。

aws ec2 run-instances --cli-input-json file://instance.json

EC2は山ほど設定項目があるので、generate-cli-skeltonでフォーマットを出力して、必要な項目だけ入力して、不必要なものは消すとinstanceの詳細を記述したjsonの完成です。Gitにでも入れておきましょう。
http://docs.aws.amazon.com/cli/latest/userguide/generate-cli-skeleton.html

aws ec2 run-instances --generate-cli-skeleton

Instanceの設定詳細を記述したjsonサンプル

instance.json
{
    "ImageId": "<image-id>",
    "KeyName": "<my-key>",
    "SecurityGroupIds": [
        "<my-sgid>"
    ],
    "InstanceType": "<instance-type>",
    "BlockDeviceMappings": [
        {
            "VirtualName": "Root",
            "DeviceName": "/dev/sda1",
            "Ebs": {
                "VolumeSize": 100,
                "DeleteOnTermination": true,
                "VolumeType": "gp2"
            }
        }
    ],
    "Monitoring": {
        "Enabled": false
    },
    "SubnetId": "<subnet-id>",
    "DisableApiTermination": false,
    "IamInstanceProfile": {
        "Name": "<instance-iam-role>"
    },
    "TagSpecifications":[
        {
            "ResourceType": "instance",
            "Tags": [
              {
                "Key": "Name",
                "Value": "<server-name>"
              },
              {
                "Key": "ClusterName",
                "Value": "<cluster-name>"
              },
              {
                "Key": "Application",
                "Value": "<myapp>"
              },
              {
                "Key": "CostCenter",
                "Value": "<my-cost-center>"
              },
              {
                "Key": "Environment",
                "Value": "Test"
              },
              {
                "Key": "User",
                "Value": "<user-name>"
              }
            ]
        },
        {
          "ResourceType": "volume",
          "Tags": [
            {
              "Key": "Device",
              "Value": "<device-name>"
            },
{
              "Key": "CostCenter",
              "Value": "<my-cost-center>"
            },
            {
              "Key": "backup_key",
              "Value": "true"
            }
          ]
        }
    ]
}

続きを読む

EC2のボリューム(EBS)容量拡張方法検証 (AmazonLinux)

結論を3行で

検証

【遂に来た!】EBS でボリュームサイズを変更できるようになりました(ボリュームタイプ変更も) | Developers.IO を参考に、稼働中のインスタンスにアタッチ済みのボリュームのサイズを増やしてみます。

今回ボリュームを増やしたいインスタンスはこのような感じです。

インスタンス的には/dev/xvdaというところに30GBのボリュームがあります。

ec2-user@ip-172-31-10-224 ~ $  df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       30G  3.8G   26G  13% /
devtmpfs        490M   56K  490M   1% /dev
tmpfs           499M     0  499M   0% /dev/shm

ec2-user@ip-172-31-10-224 ~ $  lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  30G  0 disk
└─xvda1 202:1    0  30G  0 part /

ほとんど元記事のとおりですが以下のような感じです。

スクリーンショット_2017-05-18_11_30_15.png

Modify Volumeを押します

スクリーンショット 2017-05-18 11.30.31.png

今回は 30GB -> 100GBにします

スクリーンショット 2017-05-18 11.32.51.png

パフォーマンスが変更されるまで時間がかかるとのこと。。yesを押す。

スクリーンショット 2017-05-18 11.33.00.png

完了。

スクリーンショット 2017-05-18 11.34.08.png

ボリュームの状態は optimizing...0% という表示になりますが、もうこの状態で ディスクの拡張は終わっています。

スクリーンショット 2017-05-18 11.34.46.png

awscli的には $ aws ec2 describe-volumes-modifications と叩くと進捗が表示されます(引数なしでOK)

$ aws ec2 describe-volumes-modifications
{
    "VolumesModifications": [
        {
            "TargetSize": 100,
            "TargetVolumeType": "gp2",
            "ModificationState": "optimizing",
            "VolumeId": "vol-0e92fb2e26dfd9687",
            "TargetIops": 300,
            "StartTime": "2017-05-18T02:34:07.151Z",
            "Progress": 0,
            "OriginalVolumeType": "gp2",
            "OriginalIops": 100,
            "OriginalSize": 30
        }
    ]
}

"Progress": 0 ですが、lsblk を叩くともう反映されていることがわかります。

ec2-user@ip-172-31-3-117 ~ $  lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  100G  0 disk             # <- 100になってる
└─xvda1 202:1    0   30G  0 part /

次に resize2fs すればよいのですが、以下のような感じで怒られます。

resize2fs 1.42.12 (29-Aug-2014)
resize2fs: Device or resource busy while trying to open /dev/xvda
Couldn't find valid filesystem superblock.

今回はパーティションの設定がされているためと思われます。パーティションを利用している場合の設定はこちら。http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/storage_expand_partition.html
ただルートパーティションの場合は面倒そうなので、起動時に実行されるresize2fsに任せることにしました。

見たところAmazonLinuxの場合 /etc/cloud/cloud.cfg.d/00_defaults.cfg の中で resize2fs の記述があるので、再起動時に実行されるようです。

こうして、何も考えずにrebootすることにより、dfの結果が変わりました :tada:

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       99G  9.1G   90G  10% /           # <- 99GBに増えてる
devtmpfs        490M   56K  490M   1% /dev
tmpfs           499M     0  499M   0% /dev/shm

続きを読む

JAWS-UG コンテナ支部 #8

DockerCon 2017 報告 @toricls さん

LINUX KIT

  • Dockerエンジンをどの環境でも動作する為のLinuxサブシステムを集めたツール
  • DOCKER.YMLで定義する(ymlで定義)
  • 全てのサブシステムはコンテナ
  • ポータブルなlinuxサブシステム
  • 動作にはMobyが必要

MOBY PROJECT

  • ビルドツール(makeみたいなもの)。
  • アプリケーションエンジニア、インフラエンジニアには必要ない。
  • 将来的にはDockerバイナリをビルドできるようになる。
  • 従来のDockerはDocker社のものになった。

MULTI STAGE BUILDS

  • build用のコンテナを用意する必要なくなった。

    • Dockerfileでビルドを2つ書く

『Dockerで構成するWebサービス~EmotionTechの場合・増補版~』株式会社Emotion Tech 子安 輝さん

  • EmotionTechのDocker導入から運用までの話
  • ElasticBeanstallkを使用
  • phusionのDockerImageを使用(イメージサイズは大きい)。
  • フロント(angular.js)とバックエンド(Rails)とワーカー(SQS)の3つのコンテナ。テスト環境と本番環境は同じ構成。ローカル環境もだいたい同じ構成。
  • 構築する時に気をつけた事
    • ポリシーを持って構築。
    • 各環境(ローカル、CI)で使えるDockerバージョン
    • Dockerfileのお手本参照するべし(https://github.com/docker-library)
    • ローカル環境を本番環境に近づける
  • 使ってみたら起きたこと
    • rails cで30秒待った
    • CIで使いたいコマンドが使えなかった
    • db:migrateする仕組みがない
    • 環境変数でコンテナの挙動を変えたかった
  • 本稼働してから
    • ビルドがだんだん遅くなる
    • 監視は普通にやれた
    • 内部監視はホストのmackerelエージェント。
    • cronで監視ログをマウントしたVolumeに出力して、ホストのmackerelエージェントが監視している。これでうまくいっている。
    • インスタンスをあえて入れ替えた
  • Tips
    • ローカル環境はdocker-composeで。
    • ローカル環境の初期化/更新のスクリプトを用意。
    • ローカル環境の実行環境はDocker for xxxが主流。
    • GithubTag、Dockerイメージタグ、デプロイバージョン、全て同じ値を使用する。
    • 環境変数は設定出来る箇所は複数可能なのでどこで設定するかを整理しておく。
  • ステージング環境で検証したイメージをそのまま本番環境へデプロイする=ステージング環境から本番まで同じイメージを使用する事。
  • Railsを動作しているRails.envはProductionで動作してて、DBの接続先の変更は環境変数で切替している。

LT kenjiszk さん

  • FiNCでのコンテナの管理方法
  • マイクロサービス化しててAmazonECSで解決
  • Dockerビルド&テストはJenkins
  • ECSのクラスターはDeployTask、Web、Batchの3つで運用
  • jenkinsfileをDirectoryTopに用意しておく

LT hokkai7go さん

LT kuntaroIshiyama さん

LT gavinzhm さん

  • DockerHubの脆弱性について
  • DockerHubのイメージで80%以上は少なくても重大な脆弱性がある
    • CommunityImageが更新されていない(1800+)
    • オフィシャルイメージでも(392)
    • ScanningToolを使用するべき(Clairオススメ)
  • yum update apt-get updateする
  • AplineLinux使う
  • ScanTool使う
  • GolangならFROM scrachがある

LT wata727 さん

続きを読む

AWS EBSのルートディスク拡張した際のサイズ拡張のやりかた

いつも忘れるのでメモっておく
環境はUbuntu14.04

AWSコンソール上

EBSボリュームの「アクション」⇒「Modify Volume」
指定のサイズに設定

対象インスタンス上

# root
sudo su -

# 認識されてるか確認
lsblk

# 現在のサイズ確認
df -hT

# サイズ拡張
growpart /dev/xvda 1
resize2fs /dev/xvda1

# サイズ確認
df -hT

続きを読む

AWSのGPUインスタンスを利用してTensorflowを試す

EC2のセットアップ

以下の通りp2.xlargeというGPUインスタンスを利用して、Ubuntuのインスタンスを構築します。
(現状、東京リージョンではp2インスタンスは利用できないため、ここでは)

  • AMIの選択: Ubuntu Server 16.04 LTS (HVM), SSD Volume Type – ami-80861296
  • インスタンスタイプの選択: p2.xlarge(GPUコンピューティング) $0.90/h
  • インスタンスの詳細の設定: デフォルトのまま
  • ストレージの追加: 64GiB 汎用SSD
  • Add Tags: なし
  • セキュリティグループの追加: 新しいセキュリティグループを作成する
    • sg_01: ssh 22, カスタムTCP 9898(jupyter用)
  • 確認と作成
    • 新しいキーペアの作成: kp_01.pem

セキュリティグループとキーペアは適当な名前を設定します。(ここでは、sg_01kp_01としています。)
また、既存のキーペアを利用しても問題ありません。

キーペアをダウンロードしたら、.sshに移動してパーミションを変更します。

$ mv ~/Download/kp_01.pem ~/.ssh/.
$ chmod 600 ~/.ssh/kp_01.pem

インスタンスが作成されたら、マネジメントコンソールでPublic DNSを確認し、SSHでログインします。

$ ssh -i ~/.ssh/kp_01.pem ubuntu@<Public DNS>

以下はEC2上での作業となります。まず、パッケージを更新しておきます。

$ sudo apt-get update
$ sudo apt-get upgrade

CUDA

CUDA 8.0のインストール

URL: https://developer.nvidia.com/cuda-downloads
Installation guide: http://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html

事前確認

CUDAに対応したGPUを搭載しているか確認

$ lspci | grep -i nvidia
00:1e.0 3D controller: NVIDIA Corporation GK210GL [Tesla K80] (rev a1)

CUDAに対応したOSか確認

$ uname -m && cat /etc/*release
x86_64
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS"
NAME="Ubuntu"
VERSION="16.04.2 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.2 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

gcc(+開発ツール群)のインストール

$ sudo apt-get install build-essential

動作中のカーネルと同じバージョンのカーネルヘッダーをインストール

$ sudo apt-get install linux-headers-$(uname -r)

インストール

https://developer.nvidia.com/cuda-downloads の「Select Target Platform」で以下の通り選択するとダウンロードリンクとインストール手順が表示されます。
リンク先のURLからwgetでファイルを取得して、インストールします。
(ここではcuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-debをインストールします。)

$ wget https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb
$ sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb
$ sudo apt-get update
$ sudo apt-get install cuda

環境変数の設定

~/.bash_profileに以下の通り設定します。

~/.bash_profile
export CUDA_HOME="/usr/local/cuda-8.0"
export PATH="${CUDA_HOME}/bin${PATH:+:${PATH}}"
export LD_LIBRARY_PATH="${CUDA_HOME}/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"

ログインし直して設定を反映します。

$ exec $SHELL -l

動作確認

サンプルプログラムをビルドして動作確認をします。(実行しなくても問題ありません。)

$ cuda-install-samples-8.0.61.sh test
$ cd test/NVIDIA_CUDA-8.0_Samples
$ sed -i "s/nvidia-367/nvidia-375/g" `grep "nvidia-367" -r ./ -l`
$ make

※sedの行は、今回のバージョンのサンプルプログラムに含まれるMakefileでドライバの指定に誤りがあったため置換しています。
(参考: https://askubuntu.com/questions/911548/cuda-examples-not-working-after-cuda-8-0-install)

cuDNN 5.1のインストール

URL: https://developer.nvidia.com/cudnn
ダウンロードにはNVIDIA Developer Programの会員登録が必要です。
認証が必要なため、ファイルをいったんローカルPCにダウンロードし、SCPでEC2にアップロードします。
(ここではcudnn-8.0-linux-x64-v5.1.tgzを利用します。)

ローカルからSCP

$ scp -i ~/.ssh/kp_01.pem ~/Downloads/cudnn-8.0-linux-x64-v5.1.tgz ubuntu@<Public DNS>:~/.

EC2上でインストール(ファイルの展開と配置のみ)

$ tar zxvf cudnn-8.0-linux-x64-v5.1.tgz
$ sudo cp cuda/include/* ${CUDA_HOME}/include/.
$ sudo cp cuda/lib64/* ${CUDA_HOME}/lib64/.

NVIDIA CUDA Profile Tools Interface(libcupti-dev)のインストール

apt-getでインストールできます。

$ sudo apt-get install libcupti-dev

ただし、今回は実行した時に”*** is not a symbolic link”というエラーが出たため、以下の通り解決しました。
(参考: http://stackoverflow.com/questions/43016255/libegl-so-1-is-not-a-symbolic-link)

$ sudo mv /usr/lib/nvidia-375/libEGL.so.1 /usr/lib/nvidia-375/libEGL.so.1.org
$ sudo ln -s /usr/lib/nvidia-375/libEGL.so.375.39 /usr/lib/nvidia-375/libEGL.so.1

$ sudo mv /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcudnn.so.5 /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcudnn.so.5.org
$ sudo ln -s /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcudnn.so.5.1.10 /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcudnn.so.5

$ sudo mv /usr/lib32/nvidia-375/libEGL.so.1 /usr/lib32/nvidia-375/libEGL.so.1.org
$ sudo ln -s /usr/lib32/nvidia-375/libEGL.so.375.39 /usr/lib32/nvidia-375/libEGL.so.1

GPU設定

http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/accelerated-computing-instances.html
を参考に”GPU 設定の最適化 (P2 インスタンスのみ)”を適用します。

$ sudo nvidia-smi -pm 1
$ sudo nvidia-smi --auto-boost-default=0
$ sudo nvidia-smi -ac 2505,875

Python環境

こちらの記事を参考にして、pyenv + minicondaの環境を作成します。
(「anaconda単独だと実は問題があります。」とのこと)

pyenv

https://github.com/pyenv/pyenv#installation

git cloneして~/.bash_profileの設定をします。

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
~/.bash_profile
export PYENV_ROOT="${HOME}/.pyenv"
export PATH="${PYENV_ROOT}/bin:${PATH:+:${PATH}}"
eval "$(pyenv init -)"

miniconda

pyenvで最新のminiconda(ここでは、miniconda3-4.3.11)をインストールします。

$ pyenv install -l | grep miniconda
...
(省略)
...
  miniconda3-4.3.11

$ pyenv install miniconda3-4.3.11
~/.bash_profile
export CONDA_HOME="${PYENV_ROOT}/versions/miniconda3-4.3.11"
export PATH="${CONDA_HOME}/bin${PATH:+:${PATH}}"

Tensorflow

Install with Anaconda

condaでAnaconda環境を作成して、Tensorflowをインストールします。

$ conda create -n tensorflow python=3.5 anaconda
$ source activate tensorflow
(tensorflow)$ pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.1.0-cp35-cp35m-linux_x86_64.whl

Jupyter notebook

http://jupyter-notebook.readthedocs.io/en/latest/public_server.html
EC2上で起動したJupyter notebookにローカルPCから接続するための設定をします。

  • 任意のホスト名でアクセス
  • ポート番号をデフォルトから変更(ここでは9999に設定)
  • httpsで接続
  • パスワードの設定

サーバ証明書と鍵ファイルの作成

(tensorflow)$ mkdir certificate
(tensorflow)$ cd certificate
(tensorflow)$ openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mykey.key -out mycert.pem

パスワードのハッシュ値作成

(tensorflow)$ python
>>> from notebook.auth import passwd
>>> passwd()
Enter password: 
Verify password:
'sha1:********'
>>> exit()

jupyterの設定ファイル作成

設定ファイルの雛形を出力

(tensorflow)$ jupyter notebook --generate-config

以下の設定を追加

~/.jupyter/jupyter_notebook_config.py
c.NotebookApp.certfile = '/home/ubuntu/certificate/mycert.pem'
c.NotebookApp.keyfile = '/home/ubuntu/certificate/mykey.key'
c.NotebookApp.ip = '*'
c.NotebookApp.port = 9999
c.NotebookApp.open_browser = False
c.NotebookApp.password='sha1:********'

Jupyter notebook起動

(tensorflow)$ jupyter notebook

ローカルPCのブラウザでhttps://<Public DNS>:9999にアクセスすると、パスワード入力画面が表示されるので、「パスワードのハッシュ値作成」の際に入力したパスワードを入力してログインします。

続きを読む

EBSボリュームのサイズ変更をやってみる

環境

項目 設定
OS AmazonLinux (version 2017.03)
インスタンスタイプ t2.micro
ボリュームタイプ gp2
pythonバージョン Python 3.5.3 (pyenv)
AWS CLIバージョン aws-cli/1.11.82

その他詳細

a.拡張対象ディスクの初期状態
{
    "Volumes": [
        {
            "VolumeType": "gp2",
            "VolumeId": "vol-05c927a2a0afec131",
            "Iops": 100,
            "CreateTime": "2017-05-04T01:17:37.368Z",
            "State": "in-use",
            "Size": 10,
            "Encrypted": false,
            "AvailabilityZone": "ap-northeast-1a",
            "Attachments": [
                {
                    "VolumeId": "vol-05c927a2a0afec131",
                    "DeleteOnTermination": false,
                    "State": "attached",
                    "AttachTime": "2017-05-04T01:17:37.000Z",
                    "Device": "/dev/sdb",
                    "InstanceId": "i-074b8466302e6dc1a"
                }
            ],
            "SnapshotId": ""
        }
    ]
}
b.拡張対象ディスクの変更情報は無し
[root@ip-172-30-0-5 work]# aws ec2 describe-volumes-modifications --volume-id vol-05c927a2a0afec131 --region ap-northeast-1

An error occurred (InvalidVolumeModification.NotFound) when calling the DescribeVolumesModifications operation: Modification for volume 'vol-05c927a2a0afec131' does not exist.
c.OSから見た初期状態
[root@ip-172-30-0-5 ~]# lsblk /dev/xvdb
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvdb 202:16   0  10G  0 disk /mnt
[root@ip-172-30-0-5 ~]# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvdb       9.8G   23M  9.2G   1% /mnt

手順

1.拡張対象のディスクを10GiB→11GiBに拡張する

コマンド
aws ec2 modify-volume --volume-id vol-05c927a2a0afec131 --size 11 --region ap-northeast-1
レスポンス
{
    "VolumeModification": {
        "TargetVolumeType": "gp2",
        "OriginalSize": 10,
        "StartTime": "2017-05-04T05:32:52.500Z",
        "TargetIops": 100,
        "TargetSize": 11,
        "OriginalVolumeType": "gp2",
        "OriginalIops": 100,
        "VolumeId": "vol-05c927a2a0afec131",
        "ModificationState": "modifying",
        "Progress": 0
    }
}

2.変更の進行状況をチェック

コマンド
aws ec2 describe-volumes-modifications --volume-id vol-05c927a2a0afec131 --region ap-northeast-1
変更リクエスト発行から間髪入れずに発行した時のレスポンス
{
    "VolumesModifications": [
        {
            "OriginalSize": 10,
            "OriginalVolumeType": "gp2",
            "TargetIops": 100,
            "TargetSize": 11,
            "StartTime": "2017-05-04T05:32:52.500Z",
            "OriginalIops": 100,
            "ModificationState": "modifying",
            "TargetVolumeType": "gp2",
            "Progress": 0,
            "VolumeId": "vol-05c927a2a0afec131"
        }
    ]
}
変更リクエスト発行からちょっと経ってから発行した時のレスポンス
{
    "VolumesModifications": [
        {
            "TargetSize": 11,
            "TargetVolumeType": "gp2",
            "Progress": 2,
            "OriginalVolumeType": "gp2",
            "VolumeId": "vol-05c927a2a0afec131",
            "OriginalSize": 10,
            "StartTime": "2017-05-04T05:32:52.500Z",
            "ModificationState": "optimizing",
            "OriginalIops": 100,
            "TargetIops": 100
        }
    ]
}

状態がoptimizingに進行。{"Progress":"2"} の部分が進捗状況。完了するとこうなる。

拡張完了後
{
    "VolumesModifications": [
        {
            "EndTime": "2017-05-04T05:38:04.434Z",
            "TargetSize": 11,
            "TargetIops": 100,
            "ModificationState": "completed",
            "StartTime": "2017-05-04T05:32:52.500Z",
            "TargetVolumeType": "gp2",
            "OriginalVolumeType": "gp2",
            "VolumeId": "vol-05c927a2a0afec131",
            "Progress": 100,
            "OriginalSize": 10,
            "OriginalIops": 100
        }
    ]
}

1GiB増やすのに05:12って結構かかるのね。
進捗状況は直前まで2%だったので、相変わらず適当なパーセントな模様。

3.OSから見た状態をチェック

コマンド
lsblk /dev/xvdb
[root@ip-172-30-0-5 work]# lsblk /dev/xvdb
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvdb 202:16   0  11G  0 disk /mnt

ちゃんと拡張されました。

回数制限があった気がするので、何回かやってみようとしたところ…

[root@ip-172-30-0-5 work]# aws ec2 modify-volume --volume-id vol-05c927a2a0afec131 --size 12 --region ap-northeast-1

An error occurred (VolumeModificationRateExceeded) when calling the ModifyVolume operation: You've reached the maximum modification rate per volume limit. Wait at least 6 hours between modifications per EBS volume.

あ、そういう制限だったのか。ドキュメントにもあった。

APIReference ModifyVolume

If you reach the maximum volume modification rate per volume limit, you will need to wait at least six hours before applying further modifications to the affected EBS volume.

今度気が向いたら拡張中の性能を測ってみよう。

続きを読む

ECSのAMIで使われる/dev/xvdczについて【cloudpack大阪ブログ】

cloudpack大阪の佐々木です。
ECSでコンテナ用のボリュームを作ったらどこに保存されるか?という話です。

ECSで使うamazon-ecs-optimizedのAMIはデフォルトでは下記のディスク構成になっています。(2015.09.d 以降)

  • /dev/xvda 8G
  • /dev/xvdcz 22G

http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/launch_container_instance.html

Amazon ECS に最適化された、2015.09.d 以降の AMI を使用している場合、インスタンスには 2 つのボリュームが設定されます。[Root] ボリュームはオペレーティングシステム用で、2 番目の Amazon EBS ボリューム (/dev/xvdcz にアタッチ) は Docker 用です。

永続化データを取り扱う場合、ボリュームを追加すると思います。/dev/xvdcz はDocker用ボリュームってことなので、当然そちらに作られるのかと思ったのですが、違うようです。

https://github.com/aws/amazon-ecs-agent/issues/312

/dev/xvdcz is dedicated to layer storage; since volumes are not layers, they’re not stored there.

実際にやってみます。
タスク定義はこんな感じです。

"volumes": [
  {
    "name": "volume-0",
    "host": {
        "sourcePath": "/ecs/mysql"
    }
  }
]

dfではRootボリュームの/dev/xvda1 だけが見えています。

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1       7.8G  1.7G  6.1G   22% /
devtmpfs         1.9G   96K  1.9G    1% /dev
tmpfs            1.9G     0  1.9G    0% /dev/shm

コンテナにログインし、マウントしているボリュームに2Gのファイルを作成します。

$ docker exec -it 706e24a04caa /bin/bash
root@706e24a04caa:/# dd if=/dev/zero of=/var/lib/mysql/test.out bs=1024 count=2000000
root@706e24a04caa:/# ls -lh /var/lib/mysql/test.out
-rw-r--r-- 1 root root 2.0G Apr 25 04:47 /var/lib/mysql/test.out

ログアウトして、dfを実行してみます。

[ec2-user@ip-172-31-49-18 ~]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1       7.8G  3.6G  4.2G   47% /
devtmpfs         1.9G   96K  1.9G    1% /dev
tmpfs            1.9G     0  1.9G    0% /dev/shm

/dev/xvda1 が増えています。

ではDocker用のボリューム /dev/xvdcz はどんな感じで使われているのでしょうか?
ここに詳しく書いてました。
http://enakai00.hatenablog.com/entry/20140420/1397981156

ホストOSからはこんな感じで見えています。

# lsblk
NAME                                                                                         MAJ:MIN   RM  SIZE RO TYPE MOUNTPOINT
xvda                                                                                         202:0      0    8G  0 disk
└─xvda1                                                                                      202:1      0    8G  0 part /
xvdcz                                                                                        202:26368  0   50G  0 disk
└─xvdcz1                                                                                     202:26369  0   50G  0 part
  ├─docker-docker--pool_tmeta                                                                253:0      0   52M  0 lvm
  │ └─docker-docker--pool                                                                    253:2      0 49.5G  0 lvm
  │   ├─docker-202:1-263192-5c6d48e2f8751428fe02afdadbd0cea776f6019d7ea6b84b3313a66d0c1f8ed7 253:3      0   10G  0 dm
  │   ├─docker-202:1-263192-eca78b256bf5721af414556f0ab42f4436e5ddd2dfb060da1f0ccf843cdbe11a 253:4      0   10G  0 dm
  │   ├─docker-202:1-263192-035491c621338eac035f0a3ee3894dc7c02c0f2989a33bce5e4628226edb1f10 253:5      0   10G  0 dm
  │   ├─docker-202:1-263192-d27d60081d632b3cc0e5b7c7213f40b4eec77d445d0c445abdf69efc83535d54 253:6      0   10G  0 dm
  │   └─docker-202:1-263192-60b1cb416a8ced69c0f6f5c71b842298427dfa406dd7ed6f5f44a56dc3d5f78f 253:7      0   10G  0 dm
  └─docker-docker--pool_tdata                                                                253:1      0 49.5G  0 lvm
    └─docker-docker--pool                                                                    253:2      0 49.5G  0 lvm
      ├─docker-202:1-263192-5c6d48e2f8751428fe02afdadbd0cea776f6019d7ea6b84b3313a66d0c1f8ed7 253:3      0   10G  0 dm
      ├─docker-202:1-263192-eca78b256bf5721af414556f0ab42f4436e5ddd2dfb060da1f0ccf843cdbe11a 253:4      0   10G  0 dm
      ├─docker-202:1-263192-035491c621338eac035f0a3ee3894dc7c02c0f2989a33bce5e4628226edb1f10 253:5      0   10G  0 dm
      ├─docker-202:1-263192-d27d60081d632b3cc0e5b7c7213f40b4eec77d445d0c445abdf69efc83535d54 253:6      0   10G  0 dm
      └─docker-202:1-263192-60b1cb416a8ced69c0f6f5c71b842298427dfa406dd7ed6f5f44a56dc3d5f78f 253:7      0   10G  0 dm

まとめ

ECSで永続化データ用のボリュームを使う場合は、Rootボリュームをあらかじめ大きくしておくか、別ボリュームをアタッチしてマウントしとく必要があるようです。

続きを読む

TensorFlow with GPU on Docker を AWS で起動する

構成

https://github.com/NVIDIA/nvidia-docker にある以下の図が分かりやすい。

図

今回、Server は AWS の p2 インスタンス (GPU インスタンス)。
Host OS は Ubuntu 16.04 を利用する。

手動でインストールが必要なものは以下の通り。

  • CUDA Toolkit / CUDA Driver

    • NVIDIA GPU をコントロールするために必要
    • 2つ同時にインストールされる
  • Docker Engine
  • nvidia-docker
    • Docker コンテナ内から CUDA Toolkit 経由で GPU を触るために必要

1. AWS インスタンス起動

GPU インスタンスの p2 系を起動する。

AMI
Ubuntu Server 16.04 LTS (HVM), SSD Volume Type
備考
ディスクサイズは 100 GB に変更する (デフォルトは 8 GB、足りない)

2. CUDA のインストール

公式ドキュメント 通りに進める。
ただ、ドキュメントが長いので読まない方が良い。ハマると果てしなくハマって辛い。

実際に必要なのは3箇所のみ。

  • “2. Pre-installation Actions” > “2.6. Download the NVIDIA CUDA Toolkit”
  • “3. Package Manager Installation” > “3.6. Ubuntu”
  • “6. Post-installation Actions” > “6.1.1. Environment Setup”

実際のコマンドは以下の通り。

## 2.6 Pre-installation Actions (Download the NVIDIA CUDA Toolkit)
$ wget https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb

## 3.6 Package Manager Installation (Ubuntu)
$ sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb
$ sudo apt-get update
$ sudo apt-get install cuda

## 6.1.1 Post-installation Actions (Environment Setup)
$ echo 'export PATH=/usr/local/cuda-8.0/bin${PATH:+:${PATH}}' >> ~/.bashrc
$ source ~/.bashrc

nvcc が入れば成功。

$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2016 NVIDIA Corporation
Built on Tue_Jan_10_13:22:03_CST_2017
Cuda compilation tools, release 8.0, V8.0.61

3. Docker のインストール

公式ドキュメント (Install using the repository) 通りに、Docker CE をインストールする。

インストール完了したら、sudo 無しで動作するよう ubuntu ユーザを docker グループに追加して、SSH ログインし直す。

$ sudo usermod -aG docker ubuntu

hello-world が動けば完了。

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

4. nvidia-docker のインストール

公式ドキュメント 通りに進める。

“Quick start” > “ubuntu distributions” のコマンドを実行すればOK。

$ wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
$ sudo dpkg -i /tmp/nvidia-docker*.deb && rm /tmp/nvidia-docker*.deb

以下のコマンドで Docker コンテナがホスト (p2 インスタンス) の GPU を認識していることが確認できる。

$ nvidia-docker run --rm nvidia/cuda nvidia-smi
Sun Apr 23 06:10:55 2017
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 375.39                 Driver Version: 375.39                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 0000:00:1E.0     Off |                    0 |
| N/A   47C    P8    28W / 149W |      0MiB / 11439MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

TensorFlow

あとは TensorFlow でもなんでもコンテナ内から GPU が触れる。

https://hub.docker.com/r/tensorflow/tensorflow/

$ nvidia-docker run -it -p 8888:8888 tensorflow/tensorflow:latest-gpu

続きを読む

EC2のEBSボリュームをresize2fsせずに拡張する

概要

EC2のEBSボリュームを拡張する(10G -> 90G)
EC2はすでに起動済みのものとする。

背景

EBSのボリュームを拡張したので、ファイルシステム拡張のコマンドを実行!

$ sudo resize2fs /dev/xvda1
The filesystem is already 8972864 blocks long.  Nothing to do!

パーティションの容量が少ないためディスクの拡張ができず、怒られてしまいました・・・。
Linux パーティションの拡張が必要そうですが、ちょっと手順が多い。

しかし、サイズをEBSのサイズをあらかじめ拡張し、スナップショットから新規作成することで
コマンドを実行せずともwebコンソールからディスクを拡張できたので手順をメモ。

事前準備

  • EC2で使用してるEBSのID、ルートデバイスの名前を控える。

スクリーンショット 2017-04-19 20.14.28.png

  • EC2のインスタンスID、アベイラビリティーゾーンを控える。

手順

EBSボリュームサイズを拡張する

※EC2を停止しなくても拡張できますが、拡張中は不安定になります。

ELASTIC BLOCK STORE > ボリューム > アクション > Modify Volume
Sizeの値を変更します。

スクリーンショット 2017-04-19 21.38.05.png

EBSボリュームのスナップショットを作成する

※EC2を停止しなくてもスナップショットを作成できますが、停止したほうが安全です。

ELASTIC BLOCK STORE > ボリューム > アクション > スナップショットの作成

EC2を停止する

以降の作業はEC2を停止しないと行えません。

EBSボリュームをEC2からデタッチする

ELASTIC BLOCK STORE > ボリューム > アクション > ボリュームのデタッチ

既存のEBSをデタッチします。

EBSボリュームのスナップショットから新しいボリュームを作成する

ELASTIC BLOCK STORE > スナップショット > アクション > ボリュームの作成

EC2と同じアベイラビリティゾーンにする必要があります。

スクリーンショット 2017-04-19 20.11.33.png

新規作成したEBSボリュームをEC2にアタッチ

ELASTIC BLOCK STORE > ボリューム > アクション > ボリュームのアタッチ

アタッチしたいEC2のインスタンスを選択します。
事前に控えておいたデバイスを入力します。

スクリーンショット 2017-04-19 20.24.48.png

EC2を起動

これで作業完了です!

ディスクボリュームが拡張されているか確認する

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  90G  0 disk
└─xvda1 202:1    0  90G  0 part /

$ df -h
ファイルシス       サイズ  使用  残り 使用% マウント位置
/dev/xvda1            89G   84G   5G   18% /

最後に

使用していないEBSは削除しましょう!
EC2にアタッチしていなくても、料金がかかってしまいます。

続きを読む

AWS EBSのリサイズをシェルスクリプトにまとめてみた

はじめに

AWSのストレージサービスならばとりあえずS3を選んでおけば間違いはないのでしょうけど,既存サービスを短期間でAWSに移行する場合にはEBSを使うことがあるかと思います.以前はEBSの容量を変更できませんでしたので,事前に余裕を持って確保するか,都度容量を割り当ててデータを移行するか悩ましいところでした.

2017年2月にAWSよりEBSの新機能について発表があり,EBSの容量やタイプ,IOPSなどがオンザフライで変更できるようになりました.そこで,EBSの空き容量が閾値を下回ったときに拡張するシェルスクリプトを用意し,定期的に実行することでお財布への負担と管理運用作業を軽くしてみました.

https://aws.amazon.com/jp/blogs/news/amazon-ebs-update-new-elastic-volumes-change-everything/

書いてみた

  • スペシャルデバイス名とEBSボリューム名(Nameタグに割り当てた文字列)を指定して実行します.
  • 使用容量が95%に達したら,80%弱になるくらいに拡張します.
  • Amazon Linuxでroot権限で実行することを前提としています.
  • 2017年4月の時点でのAmazon Linuxにプレインストールされているaws-cliではaws ec2 modify-volumeに未対応なため,アップデートが必要でした.
  • JSONのパースにjqが必要なので,事前にインストールしてください.
#!/bin/sh
#
# $ sudo yum install jq
# $ sudo pip install -U awscli
# # sh ./ebs-resize.sh -d /dev/xvdf -v ebs-volume-name
#

usage() {
  echo "Usage: $0 -d device-name -v ebs-volume-name" 1>&2
  exit 1
}

while getopts d:v:h OPT
do
  case $OPT in
    'd')
      DEVICE_NAME=$OPTARG
      ;;
    'v')
      VOLUME_NAME=$OPTARG
      ;;
    'h')
      usage
      ;;
    ?)
      usage
      ;;
  esac
done

shift $((OPTIND - 1))

if test ${#DEVICE_NAME} -eq 0 -o ${#VOLUME_NAME} -eq 0; then
  usage
fi

df -k $DEVICE_NAME 1> /dev/null
if test "$?" -ne 0; then
  echo "$DEVICE_NAME is not found."
  exit 1
fi

export THRESHOLD_PERCENT=95
export EXPAND_RATE=1.25
export USED_PERCENT=`df -k $DEVICE_NAME | grep -v Filesystem | awk '{print $5}' | awk -F% '{print $1}'`
export CURRENT_SIZE=`df -k $DEVICE_NAME | grep -v Filesystem | awk '{print $2}'`
export NEW_SIZE=`echo "scale=0;$CURRENT_SIZE * $EXPAND_RATE / 1024 / 1024 + 1" | bc -l`
export AWS_DEFAULT_REGION=`curl --silent http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//g'`
export INSTANCE_ID=`curl --silent http://169.254.169.254/latest/meta-data/instance-id`
export VOLUME_ID=`aws ec2 describe-volumes --filter "Name=attachment.instance-id,Values=$INSTANCE_ID" "Name=tag:Name,Values=$VOLUME_NAME" |  jq -r '.Volumes[].VolumeId'`

if test ${#VOLUME_ID} -eq 0; then
  echo "$VOLUME_NAME is not found."
  exit 1
fi

if test $USED_PERCENT -ge $THRESHOLD_PERCENT; then
  aws ec2 modify-volume --volume-id $VOLUME_ID --size $NEW_SIZE
  resize2fs $DEVICE_NAME
fi

exit 0

おわりに

crontabに登録して1日1回程度動かすようにしましょう.なおaws ec2 modify-volumeは1度実行すると6時間は変更できないようです.ご利用は計画的に.

リンク

https://gist.github.com/stoshiya/4cafa50b34223aaa2a70c588abbede89

続きを読む