vagrant-azureとansibleを使ってRaspberry PiのLinux Kernelをビルドしてみた話
vagrant-azureを使ってAzureの上にVMを建てることを前回行いました。
vagrant-azureを使ってAzureに仮想マシンを建ててみたメモ - /home/tnishinaga/TechMEMO
今回はこれに加えてansibleを使ってRaspberry PiのLinux Kernelをビルドすることを行ってみたいと思います。
スクリプトの修正とLinux Kernelのビルド
ansibleを使ったプロビジョンの追加
前回書いたVagrantfileのVagrant.configureのところに以下を追記します。
# ansible provision config.vm.provision 'ansible' do |ansible| ansible.playbook = "provisioning/playbook.yml" end
これでprovisioning/playbook.ymlの記述に従って、Ansibleを使ったプロビジョンを行えるようになります。
追記した後のVagrantfileはこんな感じになります。
require 'dotenv'
Dotenv.load
Vagrant.configure('2') do |config|
# ansible provision
config.vm.provision 'ansible' do |ansible|
ansible.playbook = "provisioning/playbook.yml"
end
config.vm.box = 'azure'
# use local ssh key to connect to remote vagrant box
config.ssh.private_key_path = '~/.ssh/id_rsa'
config.vm.provider :azure do |azure, override|
# each of the below values will default to use the env vars named as below if not specified explicitly
azure.tenant_id = ENV['AZURE_TENANT_ID']
azure.client_id = ENV['AZURE_CLIENT_ID']
azure.client_secret = ENV['AZURE_CLIENT_SECRET']
azure.subscription_id = ENV['AZURE_SUBSCRIPTION_ID']
azure.location = ENV['AZURE_LOCATION']
end
end
その他必要なファイルは前回の記事を参照してください。
Ansible-Playbookを作る
- Ubuntu のアップデート
- ビルドに必要なパッケージのインストール
- クロスコンパイラの取得とインストール
- Linux kernel sourceの取得
- Raspberry Pi(BCM2835)用configの設定
- Linux Kernelのビルド
以上を行うAnsible playbookをつくります。
hostsのところはallにしておけば、inventoryファイルはいらないようです。
# update
- hosts: all
tasks:
- name: install basic packages
apt: name={{ item }} update_cache=yes state=latest
with_items:
- git
- build-essential
- bc
become: true
- name: install cross-compiler
unarchive:
src: https://releases.linaro.org/components/toolchain/binaries/latest/arm-eabi/gcc-linaro-6.3.1-2017.05-x86_64_arm-eabi.tar.xz
dest: /usr/local/
remote_src: True
become: true
- name: add /usr/local/gcc-linaro-6.3.1-2017.05-x86_64_arm-eabi/bin to path
lineinfile:
dest: .bashrc
insertafter: EOF
line: "export PATH=$PATH:/usr/local/gcc-linaro-6.3.1-2017.05-x86_64_arm-eabi/bin"
- name: clone linux source
git:
repo: https://github.com/torvalds/linux
dest: linux
version: master
depth: 1
- name: load bcm2835_defconfig
command: "make bcm2835_defconfig"
args:
chdir: ./linux
environment:
PATH: "{{ ansible_env.PATH }}:/usr/local/gcc-linaro-6.3.1-2017.05-x86_64_arm-eabi/bin"
ARCH: arm
CROSS_COMPILE: arm-eabi-
- name: make linux-kernel
command: "make -j4 zImage dtbs"
args:
chdir: ./linux
environment:
PATH: "{{ ansible_env.PATH }}:/usr/local/gcc-linaro-6.3.1-2017.05-x86_64_arm-eabi/bin"
ARCH: arm
CROSS_COMPILE: arm-eabi-
ビルドしてみる
前回同様、Vagrantfileのあるディレクトリで以下のコマンドを実行するとクラウド上のVM起動からLinux Kernelのビルドまでが行われます。
vagrant up
使い終わったら vagrant destroy でマシンを潰すのを忘れないようにしてください。
性能計測
このスクリプトを使ったビルドに必要な時間を計測して、より速くビルドするにはどうすればよいかを考えてみたいと思います。
ビルド時間の概要
今回のビルドにかかる時間は、大まかに以下の2つに分けることができると考えています。
- Azure上でVMを用意して立ち上げるまでの時間
- ansibleのプロビジョンにかかる時間
VM立ち上げとプロビジョン完了までの時間はtimeコマンドを使えば計測可能です。 なので、後者のプロビジョン時間を知ることができれば、計算でVM立ち上げまでの時間を得ることができるでしょう。
VM立ち上げの時間はこちら側で速くすることは難しそうなので、後者のプロビジョン時間を速くする方向性で考えていきたいと思います。
プロビジョン時間の計測
ansibleのプロビジョンの各タスクの実行にかかった時間はansible-profileプラグインを使うことで調べることができるようです。
このプラグインは現在ansibleにデフォルトで入っているので、少し設定を追記するだけで利用可能です。
ansibleの設定は、Vagrantfileと同じディレクトリにanisble.cfg というファイルを作り、そこに書き込めば良いようです。
以下の内容を書いた anisble.cfg を作ってください。
[defaults] callback_whitelist = profile_tasks
そして、再度 vagrant up を行うと、今度はプロビジョンにかかった詳細な時間が表示されるはずです。
計測結果の確認と検討
私の環境でのプロビジョン時間の結果の概要を以下に示します。
PLAY [all] ********************************************************************* TASK [Gathering Facts] ********************************************************* Friday 04 August 2017 00:47:21 +0900 (0:00:00.144) 0:00:00.144 ********* ok: [default] TASK [install basic packages] ************************************************** Friday 04 August 2017 00:47:25 +0900 (0:00:03.483) 0:00:03.628 ********* changed: [default] => (item=[u'git', u'build-essential', u'bc']) TASK [install cross-compiler] ************************************************** Friday 04 August 2017 00:48:00 +0900 (0:00:35.629) 0:00:39.257 ********* changed: [default] TASK [add /usr/local/gcc-linaro-6.3.1-2017.05-x86_64_arm-eabi/bin to path] ***** Friday 04 August 2017 00:50:04 +0900 (0:02:03.371) 0:02:42.628 ********* changed: [default] TASK [clone linux source] ****************************************************** Friday 04 August 2017 00:50:06 +0900 (0:00:01.734) 0:02:44.363 ********* changed: [default] TASK [load bcm2835_defconfig] ************************************************** Friday 04 August 2017 00:51:01 +0900 (0:00:55.154) 0:03:39.517 ********* changed: [default] TASK [make linux-kernel] ******************************************************* Friday 04 August 2017 00:51:07 +0900 (0:00:06.207) 0:03:45.725 ********* changed: [default] PLAY RECAP ********************************************************************* default : ok=7 changed=6 unreachable=0 failed=0 Friday 04 August 2017 00:57:02 +0900 (0:05:54.616) 0:09:40.341 ********* =============================================================================== make linux-kernel ----------------------------------------------------- 354.62s install cross-compiler ------------------------------------------------ 123.37s clone linux source ----------------------------------------------------- 55.15s install basic packages ------------------------------------------------- 35.63s load bcm2835_defconfig -------------------------------------------------- 6.21s Gathering Facts --------------------------------------------------------- 3.48s add /usr/local/gcc-linaro-6.3.1-2017.05-x86_64_arm-eabi/bin to path ----- 1.73s
結果を見ると、以下の順に時間がかかっているようです。
(4位のUbuntuのアップデートとパッケージのインストールは高速化が難しいのでパスします。)
一番時間のかかっているLinux Kernelのビルドは、使用するVMの性能を上げれば短縮できそうです。 もちろん、性能の良いマシンはお金がかかるので、費用対効果も考える必要がありそうです。
2番目に時間のかかっているクロスコンパイラのダウンロードは、永続ディスクなどを作ってそこに保存しておいたものを使うといったことを行えれば速くできそうです。現在は何度も実行するとダウンロード先に負荷をかけてしまうかもしれないので、この改善は早めに行ったほうが良さそうです。
3番目のSourceのクローンも2番めと同様に、永続ディスクを作って保存しておいて、差分だけpullしてくれば速くできそうな気がします。
おわり
今回はvagrant-azureとansibleを使って、Azure上でLinux Kernelのビルドを行い、その実行時間を測ることと、どうすれば改善できそうかを考えました。
次回はより速くビルドできるよう、工夫してみようと思います。