AWSでEC2を使う場合、AmazonLinuxを使うことも多いかと思います。
そして、OpsWorksを使ったり、サーバー構成管理をChefなどで行う場合、Chefのレシピを作って確認してテストして。。。ということを何回もやる必要があると思います。
しかし、EC2のAmazonLinuxだと基本的に起動するまでに1分程度かかるので中々開発効率があげられません。
AmazonLinuxはRedhat互換なので事前にCentOSのDockerを使って確認しておくのもありですが、違っている部分もあり、結局最終的にはAmazonLinuxで確認しなきゃと思うとに2度手間だったりします。
じゃあどうすればよいのかーと思って調べていたらAmazonLinuxをDockerイメージにできるらしく実際にやってみて、Chefの開発効率を上げる方法を考えてみたのでメモ。
結論
- AmazonLinuxのDockerイメージは作れる
- ただし、yumはVPC内でしか使えない
- 逆に言えばEC2でならいい感じに使える
- PackerやVagrantを使うとより快適になる。Chefのテスト環境readyなPacker作りました。toshihirock/chef-test-ec2
- EC2ではインターネットへのアクセス通信量によっては利用料も発生するのでその点は注意
- 今回は試してないが、AnsibleやPuppet、UserDataの検証としてもとても有用ではないかと
参考
- KITCHEN-DOCKERでEC2の料金をかけず、高速にAMAZON LINUXでのCOOKBOOKのテストを行う方法
- Docker Meetup Tokyo #2でLTしてきた:「Docker+serverspecで作るconfigspec CI」 #dockerjp
AmazonLinuxのDockerイメージを作成する
以下、参考の「Amazon Linux Docker Image」の項に記載してあるように以下のように操作していきます。
Docker Meetup Tokyo #2でLTしてきた:「Docker+serverspecで作るconfigspec CI」 #dockerjp
まず、以下をCLIやマネージメントコンソールで実施します。
- EC2のインスタンスを2つ作成する(AmazonLinux201509)
- 一つのインスタスを停止する
- 停止したインスタンスのEBSボリュームをデタッチする
- デタッチボリュームを起動中のインスタンスにアタッチする
以降、起動中のインスタンスにsshログインして操作を実施します。
ディスクをマウントするあたりの操作がイマイチよくわかっておらず、以下を参考に少し細くやってみました。
アタッチされたEBSを確認する
lsblkコマンドでEC2で使用可能なディスクデバイスを確認します。
$lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 8G 0 disk
└─xvda1 202:1 0 8G 0 part /
xvdf 202:80 0 8G 0 disk
└─xvdf1 202:81 0 8G 0 part
xvda、xvdfというのが接続されているEBSでxvda1,xvdfというのがそのEBSのパーティションとなっています。(パーティションが複数ある場合、xvda1,xvda2みたいな感じになる)
xvda,xvdfという名称は必ずしもEBSでアタッチした時のデバイス名とは一致しないようです。末尾の文字は変わらない事が多いのでその情報やマウントポイントなどを見て見分けることができるようです。
今回の例でも後でアタッチしたEBSのデバイス名は/dev/sdfとしたが、上記では/dev/xvdfとなっていますが、末尾の文字が同じ事とxvda1はマウントポイントがあるのに対し、xvdf1はマウントポイントがない事からもこのデバイス名が追加したEBSであることがわかるかと思います。
EBSにファイルシステムを追加する必要が有るか確認
次に追加されたEBSにファイルシステムを作成する必要が有るか確認します。今回のEBSは、既ににファイルシステムが構成されたEBSではありますが、念のため確認します。lsblkコマンドで見たばいのパスは/dev/が抜けているのでこちらでは/dev/を先頭につけています。
$sudo file -s /dev/xvdf
/dev/xvdf: GPT partition table, version 1.0, GUID: 1fbb752b-6fa9-4f9c-b708-35541a3c2b73, disk size: 16777216 sectors of 512 bytes
上記のように表示された場合、既にファイルシステムが構築されていることを示していますので別途ファイルシステムを作成する必要はありません。
ファイルシステムがない場合には以下のような表示となるようです。(新しくEBSを作成し、アタッチした場合など)
$sudo file -s /dev/xvdf
data
上記の場合、以下のようにファイルシステムを作成する必要があります。
$sudo mkfs -t ext4 /dev/xvdf
マウントする
準備ができたのでいよいよマウントしてディスクを利用できるようにします。
まず、マウント先のディレクトリを作成します。今回は/data2
/という場所にマウントするようにしますので、そのディレクトリを作成します。
$sudo mkdir /data2
次にmountコマンドを使ってマウントします。マウントコマンドの第一引数では/dev/xvdf1などのパーティションを指定し、第2引数でマウントするポイント(今回の例では/data2)を指定します。
$sudo mount /dev/xvdf1 /data2
マウントができているか、以下で確認できます。
$lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 8G 0 disk
└─xvda1 202:1 0 8G 0 part /
xvdf 202:80 0 8G 0 disk
└─xvdf1 202:81 0 8G 0 part /data2
xvdf1のマウントポイントが記載されて無事マウントができたようです。
docker利用準備
EC2上でdockerコマンドなどを使うためにインストール及びサービスの起動を行います。
$sudo yum install docker -y
$sudo docker service start
また、あとでDockerHubにpushするためにloginしておきます。(DockerHubのアカウントがない場合、事前に作成しておくこと)
$docker login
不要ファイルの削除
マウントしたボリュームの不要ファイル群を削除します。
$cd /data2/
$sudo rm -rf var/log/*
$sudo rm -rf var/cache/yum/*
$sudo rm -rf home/ec2-user/.ssh/authorized_keys
dockerイメージ作成及びDockerHubへのpush
以下のコマンドでdocker imageを作成します。tarコマンドでカレントディレクトリのアーカイブを作成し、それをdocker importを使ってimageを作成します。
$sudo su
$tar --numeric-owner -cjp . | docker import - local/amzn
少し待って完了したらイメージができているかと思います。
$docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
local/amzn latest 8da3738750f5 10 minutes ago 867 MB
起動してsshログイン時にパスワード認証にするなどの事前処理を行います。
$docker run -t -i local/amzn /bin/bash
[root@60134c5bf7f7 /]# rm -f /etc/ssh/ssh_host_*
[root@60134c5bf7f7 /]# sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
[root@60134c5bf7f7 /]# exit
コンテナIDを確認し、AmazonLinuxリリース日付のタグを切ってDockerHubにpushします。 toshihirock となっている部分は自身のDockerHubのアカウントに変更してください。
$docker ps -a
$docker commit ${CONTAINER ID} toshihirock/amzn
$docker tag ${IMAGE ID} toshihirock/amzn:2015.09
$docker push toshihirock/amzn
成功すればDockerHubのリポジトリでも確認できます。
AmazonLinuxのDockerイメージを使ってみる
ローカル、EC2上で確認してみました。
結論としてはローカルでも利用できますが、yumが使えません。EC2上からであればyumも使えます。
ローカル環境(Mac)で利用する
MacにDockerToolBoxをインストールしておき、確認してみます。
# imageのダウンロード
$docker pull toshihirock/amzn
# amazonlinuxが利用できる
$docker run -t -i toshihirock/amzn /bin/bash
[root@e1f9894debf7 /]# cat /etc/system-release
Amazon Linux AMI release 2015.09
# yumについては利用不可
[root@e1f9894debf7 /]#sudo yum install nginx
Loaded plugins: priorities, update-motd, upgrade-helper
http://packages.ap-northeast-1.amazonaws.com/2015.09/main/201509419456/x86_64/repodata/repomd.xml?instance_id=fail®ion=URLError: [Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 403 Forbidden"
Trying other mirror.
http://packages.ap-southeast-1.amazonaws.com/2015.09/main/201509419456/x86_64/repodata/repomd.xml?instance_id=fail®ion=URLError: [Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 403 Forbidden"
Trying other mirror.
EC2上で利用する
以降の処理はEC2にsshログインし、確認。
確認はAmazonLinux201509で実施
# dcokerをインストール
$sudo yum install docker -y
#dockerグループに追加
$sudo usermod -g docker ec2-user
#サービス起動
$sudo service docker start
# imageダウンロード
$docker pull toshihirock/amzn
$docker pull toshihirock/amzn:2015.09
# VPC内からの通信であればyumも利用できる
$docker run -t -i toshihirock/amzn /bin/bash
[root@111c9900747f /]# sudo yum install nginx
Loaded plugins: priorities, update-motd, upgrade-helper
amzn-main/latest | 2.1 kB 00:00
amzn-main/latest/group | 35 kB 00:00
amzn-main/latest/primary_db | 3.4 MB 00:00
amzn-updates/latest | 2.3 kB 00:00
amzn-updates/latest/group | 35 kB 00:00
amzn-updates/latest/updateinfo | 258 kB 00:00
amzn-updates/latest/primary_db | 1.2 kB 00:00
Resolving Dependencies
--> Running transaction check
Chefのプロビジョニングをやってみる
AmazonLinux上でchefDKをインストールして、Chefの開発環境を構築し、テストなどできるかやってみます。
まずはchefDKのインストールと設定を行います。
# インストール
$wget https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chefdk-0.8.0-1.el6.x86_64.rpm
$sudo rpm --test chefdk-0.8.0-1.el6.x86_64.rpm
$sudo rpm -Uvh chefdk-0.8.0-1.el6.x86_64.rpm
# verifyで確認
$ chef verify
Running verification for component 'berkshelf'
Running verification for component 'test-kitchen'
Running verification for component 'chef-client'
Running verification for component 'chef-dk'
Running verification for component 'chef-provisioning'
Running verification for component 'chefspec'
Running verification for component 'rubocop'
Running verification for component 'fauxhai'
Running verification for component 'knife-spork'
Running verification for component 'kitchen-vagrant'
Running verification for component 'package installation'
Running verification for component 'openssl'
.......................
---------------------------------------------
Verification of component 'rubocop' succeeded.
Verification of component 'kitchen-vagrant' succeeded.
Verification of component 'openssl' succeeded.
Verification of component 'berkshelf' succeeded.
Verification of component 'fauxhai' succeeded.
Verification of component 'test-kitchen' succeeded.
Verification of component 'chef-dk' succeeded.
Verification of component 'knife-spork' succeeded.
Verification of component 'chef-client' succeeded.
Verification of component 'chefspec' succeeded.
Verification of component 'chef-provisioning' succeeded.
Verification of component 'package installation' succeeded.
# chefDK付属のrubyを使うようにする
$echo "eval \"$(chef shell-init `basename $SHELL`)\"" >> ~/.bashrc
$source ~/.bashrc
$which ruby
/opt/chefdk/embedded/bin/ruby
以前作ったChefのクックブックを使ってプロビジョニング、テストを実施してみます。
$git clone https://github.com/toshihirock/opsworks
$cd opsworks/myweb/
# kitchen-docker_cliをインストール
$bundle install
# .kitchen.ymlにAmazonLinuxイメージの記載があるか確認
$cat .kitchen.yml |grep amzn
- name: toshihirock/amzn-2015.09
# 起動できるものを確認
$kitchen list
Instance Driver Provisioner Verifier Transport Last Action
default-centos-67 DockerCli ChefZero Busser DockerCli <Not Created>
default-toshihirock-amzn-201509 DockerCli ChefZero Busser DockerCli <Not Created>
default-AmazonLinux-20150301 Ec2 ChefZero Busser DockerCli <Not Created>
# AmazonLinuxのイメージを起動。.kitchen.ymlに記載しているように起動時にchefをインストール
$kitchen create default-toshihirock-amzn-20150
# convergeでchefを流してテストする
$kitchen converge default-toshihirock-amzn-201509
# verifyでserverspceを実行
$kitchen verify default-toshihirock-amzn-201509
# 破棄
$kitchen destroy default-toshihirock-amzn-201509
# 起動、chef実行、servespec、破棄を一気に実施
$kitchen test default-toshihirock-amzn-201509
コンテナの起動、破棄なので実際にEC2を起動停止するよりめちゃくちゃ早い!!!!最高。
PackerとVagrantを使ってよりテスト環境を使いやすくする
個別のプロジェクトのインストールは別として以下は常に実施し、時間も掛かるのでPackerでAMI化しちゃいます。
- ChefDKのインストール
- Gitのインストール
- Dockerのインストール、設定
Githubのファイルはこちら。
$git clone https://github.com/toshihirock/chef-test-ec2.git
$cd chef-test-ec2
$packer build chef-test-ec2.json
これでできあがり。 test_chef_ami 1443256201 という感じのAMIができていると思います。
あとVagrantのvagrant-awsプラグインを使って先ほどのAMIを起動すればsync_folderを使って自分の環境のエディタを使ってコードを書き、テストしたい際にはEC2上で実行すれば快適ではないかと思います。