IAM Roleを割り当てたEC2インスタンスからEMRを起動する
いろいろとハマったのでメモ.
サマリ
- IAM Roleは3種類必要
- EMRをキックするインスタンス用の通常IAM Role
- EMRのservice role
- EMRで起動されるEC2用のjobflow role
- service / jobflow roleはdefaultを自動生成できるので使うべし
- AWSのドキュメントは英語版を見る方が結果的に早そう
- 日本語版は情報が古い
やろうとしていること
cronでデイリーにEMRを起動してS3のデータを集計する. 元々はサーバにAWSのトークン情報を抱かせて環境変数経由で渡して動いていたものを,IAM Roleを使う方式に変更することが目的.
条件は下記の通り.
- AWS
- サーバ(EC2)
- EMR Job
- S3のbucket Aにあるデータを入力
- 集計結果は別のbucket Bに保存される
やったこと
emr-kickerだけを設定 → 失敗
サーバのIAM Roleであるemr-kickerに必要な権限(EMR/EC2/S3など)を全て割り当てた. これでEMRを起動しようとすると
/path/to/vendor/bundle/ruby/2.1.0/gems/aws-sdk-1.48.1/lib/aws/core/client.rb:375:in 'return_or_raise': Service role and InstanceProfile are required for calls made with temporary credentials provided by STS (AWS::EMR::Errors::ValidationException)
となってコマンドが失敗する.
公式ドキュメントのAmazon EMR に IAM ロールを設定するから起動時にjobflow-roleを設定できることを知り,emr-jobflowというIAM Roleを新たに自前で作成してみるも,同じメッセージで起動できなかった.
よく見たらこのドキュメントにはIAM ロールでclusterを起動する方法は、現在 Amazon EMR コンソールではサポートされていません
などと書いてあった...
自前で用意したjobflow / service roleも設定 → 失敗
日本語のドキュメントでは情報が見つからなかったが,ググっているうちにDefault IAM Roles for Amazon EMRに当たった.
ここのデフォルト設定を元に,カスタムしたroleをそれぞれ(emr-service, emr-instance)作成し,service-role, jobflow-roleに設定するとコマンドは成功.
しかしAWS Consoleを見ると
Terminated with errors EMR service role arn:aws:iam::***************:role/emr-service is invalid
となって起動できていなかった.
default roleを生成してそのまま利用 → 成功
Default IAM Roles for Amazon EMRの末尾にある
- Create Default Roles with the CLI
を参考に,AWS CLIから下記コマンドでdefault roleを作成.
$ aws emr create-default-roles
このコマンドの結果,EMR_DefaultRole
とEMR_EC2_DefaultRole
がIAM Roleに追加される.
service-roleにEMR_DefaultRole
, jobflow-roleにEMR_EC2_DefaultRole
を指定したところ,上述のTerminated with erros
が出なくなり集計処理を実行することができた.
自前設定のroleで失敗して,デフォルトのroleだと成功した原因
IAM RoleのPermissionとは別の設定項目であるTrust Relationshipが正しく設定できていなかったためだった.
jobflow-roleをカスタム
EMR_EC2_DefaultRole
はS3やDynamoDBフルアクセスなど,かなり強い権限を持った状態なので,こちらは自前設定して必要範囲に絞った権限で利用することにした.
EC2に複数EBSを束ねたLVMボリュームを作成し,後からEBS追加して容量拡張する方法
サマリ
以下の手順でLVMボリュームの作成,追加ができる.
$ sudo apt-get install lvm2 # PV作成 $ sudo pvcreate /dev/xvdf $ sudo pvcreate /dev/xvdg # VG作成 $ sudo vgcreate vg1 /dev/xvdf /dev/xvdg # LV作成 $ sudo lvcreate -L 1.99G -n lv1 vg1 # ファイルシステム構築 & mount $ sudo mkfs -t ext4 /dev/vg1/lv1 $ sudo mount /dev/vg1/lv1 /data # 追加ディスクのPV作成 $ sudo pvcreate /dev/xvdh # VGに追加PVを追加 $ sudo vgextend vg1 /dev/xvdh # LVを拡張 $ sudo lvextend -l +100%FREE /dev/vg1/lv1 # ファイルシステムを拡張 $ sudo resize2fs /dev/vg1/lv1
事前準備
EC2セットアップ
EC2にDebian (Wheezy 7.5)のインスタンスを立てる. 今回はami-b53570b4を利用. 1GBのEBSを3つ用意. 最初に2つで組んだ後,もう一つを追加する.
- /dev/sdf
- /dev/sdg
- /dev/sdh
必要なパッケージをインストール
$ sudo apt-get update $ sudo apt-get install lvm2
LVMボリュームの作成手順
物理ボリューム(PV)作成
$ sudo pvcreate /dev/xvdf Writing physical volume data to disk "/dev/xvdf" Physical volume "/dev/xvdf" successfully created $ sudo pvcreate /dev/xvdg Writing physical volume data to disk "/dev/xvdg" Physical volume "/dev/xvdg" successfully created $ sudo pvscan PV /dev/xvdf lvm2 [1.00 GiB] PV /dev/xvdg lvm2 [1.00 GiB] Total: 2 [2.00 GiB] / in use: 0 [0 ] / in no VG: 2 [2.00 GiB]
ボリュームグループ(VG)作成
$ sudo vgcreate vg1 /dev/xvdf /dev/xvdg Volume group "vg1" successfully created $ sudo vgs VG #PV #LV #SN Attr VSize VFree vg1 2 0 0 wz--n- 1.99g 1.99g
論理ボリューム(LV)作成
$ sudo lvcreate -L 1.99G -n lv1 vg1 Rounding up size to full physical extent 1.99 GiB Logical volume "lv1" created $ sudo lvscan ACTIVE '/dev/vg1/lv1' [1.99 GiB] inherit
$ sudo mkfs -t ext4 /dev/vg1/lv1 mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 130560 inodes, 522240 blocks 26112 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=536870912 16 block groups 32768 blocks per group, 32768 fragments per group 8160 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done
マウント
$ sudo mount /dev/vg1/lv1 /data $ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg1-lv1 2.0G 35M 1.9G 2% /data
/etc/fstabに追記
/dev/vg1/lv1 /data ext4 defaults 1 2
新しいEBSの追加
追加ディスクにPV作成
$ sudo pvcreate /dev/xvdh Writing physical volume data to disk "/dev/xvdh" Physical volume "/dev/xvdh" successfully created $ sudo pvscan PV /dev/xvdf VG vg1 lvm2 [1020.00 MiB / 0 free] PV /dev/xvdg VG vg1 lvm2 [1020.00 MiB / 0 free] PV /dev/xvdh lvm2 [1.00 GiB] Total: 3 [2.99 GiB] / in use: 2 [1.99 GiB] / in no VG: 1 [1.00 GiB]
VGに新しいPVを追加
$ sudo vgextend vg1 /dev/xvdh Volume group "vg1" successfully extended $ sudo vgs VG #PV #LV #SN Attr VSize VFree vg1 3 1 0 wz--n- 2.99g 1020.00m
LVを拡張.この時点ではまだ実容量は増えていない.
$ sudo lvextend -l +100%FREE /dev/vg1/lv1 Extending logical volume lv1 to 2.99 GiB Logical volume lv1 successfully resized $ sudo lvscan ACTIVE '/dev/vg1/lv1' [2.99 GiB] inherit $ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg1-lv1 2.0G 36M 1.9G 2% /data
ファイルシステムを拡張
$ sudo resize2fs /dev/vg1/lv1 resize2fs 1.42.5 (29-Jul-2012) Filesystem at /dev/vg1/lv1 is mounted on /data; on-line resizing required old_desc_blocks = 1, new_desc_blocks = 1 Performing an on-line resize of /dev/vg1/lv1 to 783360 (4k) blocks. The filesystem on /dev/vg1/lv1 is now 783360 blocks long. $ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg1-lv1 3.0G 36M 2.8G 2% /data
EBSを別のインスタンスにアタッチするとき
まず大きいファイルを書き込んでおく
$ fallocate -l 2G /data/dummy.img $ md5sum /data/dummy.img a981130cf2b7e09f4686dc273cf7187e /data/dummy.img $ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg1-lv1 3.0G 2.1G 777M 73% /data $ sudo umount /data
AWSコンソールから3つのEBSをすべてデタッチして別のインスタンスにアタッチする. 以降新インスタンスで作業.
起動してlvm2インストール直後の状態
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda1 202:1 0 4G 0 disk / xvdb 202:16 0 149.1G 0 disk xvda3 202:3 0 896M 0 disk [SWAP] xvdf 202:80 0 1G 0 disk └─vg1-lv1 (dm-0) 254:0 0 3G 0 lvm xvdg 202:96 0 1G 0 disk └─vg1-lv1 (dm-0) 254:0 0 3G 0 lvm xvdh 202:112 0 1G 0 disk └─vg1-lv1 (dm-0) 254:0 0 3G 0 lvm $ sudo lvscan ACTIVE '/dev/vg1/lv1' [2.99 GiB] inherit
普通にマウントすれば使えた.
$ sudo mount /dev/vg1/lv1 /data $ md5sum /data/dummy.img a981130cf2b7e09f4686dc273cf7187e /data/dummy.img $ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg1-lv1 3.0G 2.1G 777M 73% /data
lvm2がインストール済みだった場合は参考URLの手続きが必要になるかも.
2014年の目標
1年の計は元旦にあり、ということで今年の目標を列挙してみる。
全般
- アウトプットを継続的に出す
- そのための時間を犠牲にしない
- プライベートな時間確保
- 仕事に時間をかけ過ぎない
- 家で仕事をしない
- 勉強会に積極参加する
- 参加したらレポート書く
- 本を読む
- 読んだらレポート書く
OSS活動
- 適切な機能範囲でrubygemを作る習慣を身につける
- 再利用可能な部品を切り出す
- 何らかのOSSプロダクトにコントリビュートする
スキルアップ
- 大規模データ分析技術
- ログ収集、可視化ツール
- fluentd, (growth|hr)forecast, graphite
- SQL、DB設計技術
- 統計学
- Rも使いこなしたい
- 新しい言語を覚える
- Python, Goあたり?
- 各種サービスを使いこなす
プライベート
- 毎日子供と過ごす時間を取る
- 毎日1つは家事を手伝う
- 家計の管理をちゃんとやる
思いつくものを列挙したら盛り沢山になったが目標を忘れず精進する。
App::highlightをplenv+cpanmでインストールしてみた
このスライドを見て便利そうなのでインストールしてみた.
http://www.slideshare.net/kaokun/apphighlight-londonpm-tech-meeting-july-2013
App::highlight はコマンドラインで指定したキーワードに見やすく色を付けてハイライトしてくれる.
grepしても1行が長くて見たかった場所を発見するのに苦労していたようなケースで非常に捗ると思われる.
普段はperlを使っていないので,plenv + cpanm でシステムのperlとは独立にインストールした手順のメモ.
cpanmをインストールするまではほぼplenvのREADMEの手順のまま.
(1) plenv をインストール
まずはplenv本体のインストール.
$ git clone git://github.com/tokuhirom/plenv.git ~/.plenv $ echo 'export PATH="$HOME/.plenv/bin:$PATH"' >> ~/.zshrc $ source ~/.zshrc $ echo 'eval "$(plenv init -)"' >> ~/.bash_profile $ source ~/.zshrc
次にperl-buildをplenvのpluginsディレクトリにcloneしてくる.
$ git clone git://github.com/tokuhirom/Perl-Build.git ~/.plenv/plugins/perl-build/
これで好きなバージョンのperlをインストールする準備が整った.
(2) perl をインストール
所望のバージョンのperlをインストールする.
$ GREP_OPTIONS= plenv install 5.18.1 $ plenv rehash $ plenv global 5.18.1
環境変数GREP_OPTIONSが原因でmakeで失敗する場合があるので注意が必要.
今回以下の様な設定になっていたらmakeでerrorとなった.
$ echo $GREP_OPTIONS --color=auto --exclude-dir=.hg --exclude-dir=.libs --exclude-dir=.deps --exclude-dir=.git --exclude-dir=.svn --exclude=\*.tmp --binary-files=without-match
エラー内容は下記の通り.
$ plenv install 5.18.1 ...(省略)... make -f Makefile.old clean > /dev/null 2>&1 ../../miniperl "-I../../lib" "-I../../lib" Makefile.PL "INSTALLDIRS=perl" "INSTALLMAN1DIR=none" "INSTALLMAN3DIR=none" "PERL_CORE=1" "LIBPERL_A=libperl.a" Writing Makefile for AutoLoader ==> Your Makefile has been rebuilt. <== ==> Please rerun the make command. <== false make[1]: *** [Makefile] エラー 1 make[1]: ディレクトリ `/home/masa21kik/.plenv/build/perl-5.18.0/cpan/AutoLoader' から出ます make config PERL_CORE=1 LIBPERL_A=libperl.a failed, continuing anyway... Making all in cpan/AutoLoader make all PERL_CORE=1 LIBPERL_A=libperl.a make[1]: ディレクトリ `/home/masa21kik/.plenv/build/perl-5.18.0/cpan/AutoLoader' に入ります Skip ../../lib/AutoSplit.pm (unchanged) Skip ../../lib/AutoLoader.pm (unchanged) make[1]: ディレクトリ `/home/masa21kik/.plenv/build/perl-5.18.0/cpan/AutoLoader' から出ます ./miniperl -Ilib make_ext.pl ext/B/pm_to_blib MAKE=make LIBPERL_A=libperl.a Making B (all) Running Makefile.PL in ext/B ../../miniperl -I../../lib Makefile.PL INSTALLDIRS=perl INSTALLMAN1DIR=none INSTALLMAN3DIR=none PERL_CORE=1 LIBPERL_A=libperl.a Can't locate ExtUtils/Constant.pm in @INC (you may need to install the ExtUtils::Constant module) (@INC contains: /home/masa21kik/.plenv/build/perl-5.18.0/cpan/AutoLoader/lib /home/masa21kik/.plenv/build/perl-5.18.0/dist/Carp/lib /home/masa21kik/.plenv/build/perl-5.18.0/dist/Cwd /home/masa21kik/.plenv/build/perl-5.18.0/dist/Cwd/lib /home/masa21kik/.plenv/build/perl-5.18.0/dist/ExtUtils-Command/lib /home/masa21kik/.plenv/build/perl-5.18.0/dist/ExtUtils-Install/lib /home/masa21kik/.plenv/build/perl-5.18.0/cpan/ExtUtils-MakeMaker/lib /home/masa21kik/.plenv/build/perl-5.18.0/dist/ExtUtils-Manifest/lib /home/masa21kik/.plenv/build/perl-5.18.0/cpan/File-Path/lib /home/masa21kik/.plenv/build/perl-5.18.0/ext/re /home/masa21kik/.plenv/build/perl-5.18.0/dist/Term-ReadLine/lib /home/masa21kik/.plenv/build/perl-5.18.0/lib .) at Makefile.PL line 2. BEGIN failed--compilation aborted at Makefile.PL line 2. 512 from ext/B's Makefile.PL at make_ext.pl line 430. Warning: No Makefile! make[1]: ディレクトリ `/home/masa21kik/.plenv/build/perl-5.18.0/ext/B' に入ります make[1]: *** ターゲット `config' を make するルールがありません. 中止. make[1]: ディレクトリ `/home/masa21kik/.plenv/build/perl-5.18.0/ext/B' から出ます make config PERL_CORE=1 LIBPERL_A=libperl.a failed, continuing anyway... Making all in ext/B make all PERL_CORE=1 LIBPERL_A=libperl.a make[1]: ディレクトリ `/home/masa21kik/.plenv/build/perl-5.18.0/ext/B' に入ります make[1]: *** ターゲット `all' を make するルールがありません. 中止. make[1]: ディレクトリ `/home/masa21kik/.plenv/build/perl-5.18.0/ext/B' から出ます Unsuccessful make(ext/B): code=512 at make_ext.pl line 490. make: *** [ext/B/pm_to_blib] エラー 2 Installation failure: make at /home/masa21kik/.plenv/plugins/perl-build/bin/../lib//Perl/Build.pm line 280. ABORT
(3) cpanm をインストール
$ plenv install-cpanm $ plenv rehash
(4) App::highlight をインストール
$ cpanm install App::highlight $ plenv rehash
以上の手順で無事に App::highlight が使えるようになった.
knife-soloでLinux環境構築
http://d.hatena.ne.jp/naoya/20130204/1359971408
http://d.hatena.ne.jp/naoya/20130205/1360062070
に影響されてchef-solo, knife-soloを使ったLinux環境構築を試す.
自分用のzshやemacsの設定ファイルなんかはgithubにdotfilesを置いて,持って来るだけには
なっているが,新しいVMやサーバを立ち上げたときに毎回yum installしたりするのが面倒だと
思っていた.この解決にもちょうど良さそうだ.
試した環境
VirtualBOXのVMを使って実環境はホストのWindows機のみ.
・ホストOS Windows 7
・作業環境:Fedora 18 (VirtualBOX VM)
普通に手動でインストールしたもの
事前準備として ~/.ssh/config を使って対象マシンに名前を付けたり鍵を設定しておくと楽.
・セットアップ対象:CentOS 6.3 (VirtualBOX VM)
Windows版Vagrantを使って用意したもの
chef, knife-soloのインストール
まずは作業環境にchefとknife-soloをインストールする.
普通に実行するとknife-soloのインストールでエラーが起こった.
$ gem install chef $ gem install knife-solo ERROR: While executing gem ... (Gem::DependencyError) Unable to resolve dependencies: knife-solo requires net-ssh (~> 2.2.2)
net-sshのバージョンでchefとコンフリクトしている模様.
仕方ないのでknife-soloのpre版を入れる.
$ gem install knife-solo --pre
これで問題なくインストールは完了.
なおインストールされたのはchef (11.2.0), knife-solo (0.2.0.pre1).
最初にchefの設定をするが今回はsoloしか使わないのでデフォルトでOK.
$ knife configure
~/.chef に http://community.opscode.com/ で登録後に取得できるpemファイルを配置しておく.
このときに~/.chef/knife.rb とpemファイルの名前が違っていれば修正しておく.
chefのレシピ作成
次にchefリポジトリを作成
$ knife solo init chef-repo $ git init $ git add . $ git commit -m 'first commit'
yumのEPELを有効にする.
site vendorで入れると勝手にコミットまでしてくれる.
$ knife cookbook site vendor yum -o site-cookbooks
次にインストールしたいパッケージを管理するレシピを追加.
$ knife cookbook create base_packages -o site-cookbooks $ emacs site-cookbooks/base_packages/recipes/default.rb
%w{zsh mosh tmux emacs-nox}.each do |pkg| package pkg do action :install end end
knife solo prepareで対象マシンの下準備をする.
nodes/<マシン名>.json というファイルができているので,実行するレシピを書いておく.
$ knife solo prepare vagrant@<マシン名 or IP> $ emacs nodes/<マシン名>.json
{ "recipes":[ "yum::epel", "base_packages" ] }
これで準備完了.knife solo cookを実行する.
$ knife solo cook <マシン名>
これで対象マシン上でEPELリポジトリが有効になり,レシピに書いておいたzsh moshなどのパッケージがインストールされる.
これは便利!
UMLモデリングの本質 第2版
- 作者: 児玉公信
- 出版社/メーカー: 日経BP社
- 発売日: 2011/05/26
- メディア: 単行本
- 購入: 6人 クリック: 23回
- この商品を含むブログ (6件) を見る
サブタイトルにあるとおり,「良いモデルを作るための知識と実践」が分かりやすくまとまっている.UMLを道具としてどうやってモデルづくりに活用するのかが例題を通して理解できた.
モデリングから実装への大まかな流れをまとめてみる.
なお「型図」はUML記法のクラス図を使って概念の構造を記述したモデル図と定義されるもの.
- 1. 名詞抽出法(システムへの要求に出てくる名詞全てを型の候補として,選別ルールに基づいてふるい落とす)で概念を取り出す.中心となる概念に絞って,他の概念との関係を型図にする
- 2. 業務フローをアクティビティ図で書き,ユースケースを列挙する.
- 4. ユースケースシナリオに基づいてシーケンス図を書き,モデルを検証して型図を修正する.
- 5. 将来想定されそうな機能追加や拡張を想定してモデルを洗練する.
- 6. 概念レベルから実装レベルに変換する.実装する言語で扱えない部分(動的分類,多重分類など)について型図からクラス図に書き換え.
- 7. 各クラスの責務を割り付け,インタフェースを設計する.シーケンス図でクラス間のメッセージを確認する.
- 8. 4層モデル(ユーザインタフェース層,アプリケーション層,ドメイン層,永続層)に各クラスを分類し,層間の結合度が小さくなるように分離する.
実際のところ,時間的,要求仕様の固まり具合的な制約によって全工程を辿れることは少ない気がするが,自分の頭の中を整理する意味でも道具としては使いこなせるようになっておきたい.
UMLのツールは List of Unified Modeling Language tools にまとまっている.
有償のソフトだと Enterprise Architect が使いやすそうで,試用版を使ってみている.多機能すぎて全ては使いこなせる気がしないが,HPには動画のチュートリアルやマニュアルが揃っているし,無料セミナーもやっているようだ.プロフェッショナル版で26000円弱と,結構なお値段なのがネックではある.(それでも他の類似ツールよりは安くコスパはよさそう)
フリーなものだと,Dia がよさげ.Dia2Code と組み合わせるとDiaで書いたダイアグラムからソースコード生成もできるみたい.
Windows VistaにcoLinuxをインストール
Cygwinがあまりにも遅いのでcoLinuxを導入したメモ.
まずは http://www.colinux.org/ からインストーラ(coLinux-stable)とFedoraのイメージ(Fedora-10-20090228.exe)を入手する.
Fedoraのバージョンがやたら古いけど我慢.
インストール手順は
http://www.glidenote.com/archives/462
の通りで問題なし.インストール時のコンポーネントにあるWinPcapは不要とWeb DB Press Vol.40の記事に書いてあったのでこれも外しておいた.
あっという間にインストールはできたので環境を整える.
ネットワーク設定も特に何もしなくて済んで素晴らしすぎる.
まずはユーザ追加.
# passwd # adduser masa # passwd masa # visudo (wheelにsudo権を付与) # usermod -G wheel masa
マシン名の変更.
# vi /etc/sysconfig/network (HOSTNAME=xxxxx)
このままだとsudoがやたらと遅くなるので/etc/hostsに下記のとおり設定しておく.
127.0.0.1 localhost.localdomain localhost xxxxx xxxxx.localdomain
つぎに使いそうなパッケージのインストール.
# yum update # yum install lv git mercurial ruby irb rubygems scons gcc gcc-c++ samba emacs-nox libncurses-devel autoconf openssl-devel libcurl-devel
zshとscreenはバージョンが古かったのでソースからインストールした.
まずはzsh.
# wget http://jaist.dl.sourceforge.net/sourceforge/zsh/zsh-4.3.11.tar.bz2 # tar xjf zsh-4.3.11.tar.bz2 # cd zsh-4.3.11 # ./configure --enable-multibyte # make && make install
続いてscreen
# git clone git://git.savannah.gnu.org/screen.git # cd screen/src # autoconf # autoheader # ./configure # make & make install
今のところこれで快適に使えている.
こんな簡単ならもっと早く使っておけば良かった.
cygwin + meadowはもういらないかな...
追記)
gitのバージョンも古くてgithubからcloneができなくてハマった.なぜか403エラーが出る.
仕方ないのでgitもソースからインストールし直した.
# yum remove git # wget http://repo.or.cz/w/git.git/snapshot/f7d958dff5e194797ef6776bcc77c1349f9f8c81.tar.gz -O git-1.7.7.1.tar.gz # tar xzf git-1.7.7.1.tar.gz # cd git # yum install python-devel perl-ExtUtils-MakeMaker expat-devel # make prefix=/usr/local install
makeで色々エラーが出たけど上記パッケージをインストールして解消.
無事にgithubからもcloneできた.