Kernel 3.19を搭載したUbuntu 14.04のVagrant boxを作る
Dockerでoverlay NWやoverlayfsがサポートされたがそれぞれKernel 3.16、3.18以上が必要になってくる。Ubuntu公式の14.04 TrustyのVagrant boxのKernelバージョンがこの条件を満たしておらず、毎回Kernelアップデートをするのが面倒だった。そこで、Dockerのoverlay NWやoverlayfsを試すためのVagrant Ubuntu14.04 boxを作ってみようと思う。
成果物
今回作成したVagrant boxはAtlasで公開した。利用するときは以下を実行する。
➤ vagrant box add takanabe/ubuntu1404-docker
開発環境
➤ system_profiler SPSoftwareDataType Software: System Software Overview: System Version: OS X 10.10.5 (14F27) Kernel Version: Darwin 14.5.0 ➤ vagrant -v Vagrant 1.7.4
VagrantでUbuntu14.04のVMを作る
いつもどおり手元にあるUbuntu14.04のboxを使ってVMを起動する。
➤ vagrant box list ubuntu14.04 (virtualbox, 0) ➤ vagrant init ubuntu14.04 ➤ vagrant up
Ubuntuのバージョンを確認する
起動したVMにログインして各種情報を確認する。
➤ vagrant ssh $ uname -a Linux vagrant-ubuntu-trusty-64 3.13.0-36-generic #63-Ubuntu SMP Wed Sep 3 21:30:07 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.1 LTS Release: 14.04 Codename: trusty
現状はKernel v3.13が利用されてていることが確認できる。
UbuntuのKernelバージョンを上げる
Ubuntuが公式に管理しているKernel情報はここを見ればわかる。今回はこの中のKernel v3.19.8を使う。Kernelのバージョンアップ方法はここを見ると良い。
mkdir kernel-v3.19.8 && cd kernel-v3.19.8 wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v3.19.8-vivid/linux-headers-3.19.8-031908-generic_3.19.8-031908.201505110938_amd64.deb wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v3.19.8-vivid/linux-headers-3.19.8-031908_3.19.8-031908.201505110938_all.deb wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v3.19.8-vivid/linux-image-3.19.8-031908-generic_3.19.8-031908.201505110938_amd64.deb sudo dpkg -i linux-*.deb cd .. rm -rf kernel-v3.19.8
まだ、バージョンが変わっていないことを確認してリブートする。
$ uname -a Linux vagrant-ubuntu-trusty-64 3.13.0-36-generic #63-Ubuntu SMP Wed Sep 3 21:30:07 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux $ reboot
リブート後Kernelのバージョンを確認するとちゃんと3.19.8になっている。
➤ vagrant ssh $ uname -a Linux vagrant-ubuntu-trusty-64 3.19.8-031908-generic #201505110938 SMP Mon May 11 13:39:59 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.1 LTS Release: 14.04 Codename: trusty
必要なパッケージを入れる
ついでに常用するパッケージを入れておくと便利。
$ sudo apt-get update $ sudo apt-get install zsh $ which zsh $ chsh # which zshで表示されたzshへのパスを入力する
vim、tmux、zshなんかは良く使うので設定をファイルを入れておくと捗る。とりあえずzshは自分の使い慣れた設定ファイルを作っておく。
~/.zshrc
## **** Fundamental setting/基本設定 **** ## export LANG=ja_JP.UTF-8 #PATH settings #Color settings export LSCOLORS=exfxcxdxbxegedabagacad export LS_COLORS='di=34:ln=35:so=32:pi=33:ex=31:bd=46;34:cd=43;34:su=41;30:sg=46;30:tw=42;30:ow=43;30' alias ls="ls -GF" alias gls="gls --color" zstyle ':completion:*' list-colors 'di=34' 'ln=35' 'so=32' 'ex=31' 'bd=46;34' 'cd=43;34' ## **** Complimentarity function/補完機能 **** ## #Basic complimentrity/補完機能を有効にする autoload -U compinit compinit ## **** Command history /コマンド履歴**** ## # ヒストリを保存するファイル HISTFILE=~/.zsh_history # メモリ上のヒストリ数 HISTSIZE=6000000 # 保存するヒストリ数 SAVEHIST=6000000 # zshプロセス間でヒストリを共有する setopt share_history # コマンド履歴検索 autoload history-search-end zle -N history-beginning-search-backward-end history-search-end zle -N history-beginning-search-forward-end history-search-end bindkey "^P" history-beginning-search-backward-end bindkey "^N" history-beginning-search-forward-end # ヒストリに追加されるコマンド行が古いものと同じなら古いものを削除 setopt hist_ignore_all_dups # スペースで始まるコマンド行はヒストリリストから削除 setopt hist_ignore_space # ヒストリを呼び出してから実行する間に一旦編集可能 setopt hist_verify # 余分な空白は詰めて記録 setopt hist_reduce_blanks # 古いコマンドと同じものは無視 setopt hist_save_no_dups # historyコマンドは履歴に登録しない setopt hist_no_store # 補完時にヒストリを自動的に展開 setopt hist_expand # 履歴をインクリメンタルに追加 setopt inc_append_history ## ヒストリファイルにコマンドラインだけではなく実行時刻と実行時間も保存する。 setopt extended_history ## 同じコマンドラインを連続で実行した場合はヒストリに登録しない。 setopt hist_ignore_dups # スペースで始まるコマンドラインはヒストリに追加しない。 setopt hist_ignore_space # C-sでのヒストリ検索が潰されてしまうため、出力停止・開始用にC-s/C-qを使わない。 setopt no_flow_control # インクリメンタルからの検索 bindkey "^R" history-incremental-search-backward bindkey "^S" history-incremental-search-forward ## **** Keybiding/キーバインド **** ## #Keybinding/キーバインドをvi風にする bindkey -v #keybindの追加。 bindkey "^A" beginning-of-line bindkey "^E" end-of-line ## Prompt definition/プロンプトの設定**** ## #vi mode の[insert] of [normal]の表示 function zle-line-init zle-keymap-select { local max_path_chars=30 local user_char='➤' local root_char='❯❯❯' local success_color='%F{071}' #local failure_color='%F{124}' local failure_color='%F{red}' local vcs_info_color='%F{242}' case $KEYMAP in vicmd) PROMPT="%B[%F{red}NORMAL%f]:%b%B%n@%m%b %(?.${success_color}.${failure_color})%(!.${root_char}.${user_char})%f " RPROMPT="%F{blue}%~%f" ;; main|viins) PROMPT="%B[%F{blue}INSERT%f]:%b%B%n@%m%b %(?.${success_color}.${failure_color})%(!.${root_char}.${user_char})%f " RPROMPT="%F{blue}%~%f" ;; esac zle reset-prompt } zle -N zle-line-init zle -N zle-keymap-select local max_path_chars=30 local user_char='➤' local root_char='❯❯❯' local success_color='%F{071}' local failure_color='%F{124}' local vcs_info_color='%F{242}' # Define prompts. autoload -Uz add-zsh-hook autoload -Uz vcs_info PROMPT="%B[%F{blue}INSERT%f]:%b%B%n@%m%b %(?.${success_color}.${failure_color})%(!.${root_char}.${user_char})%f " RPROMPT="%F{blue}%~%f" ## **** Options/オプション**** ## # 実行結果をコピペしやすいようにコマンド実行後は右プロンプトを消す。 setopt transient_rprompt #command correction/コマンドの訂正 setopt correct #/移動履歴をバッファに溜める setopt auto_pushd #/# 補完候補を詰めて表示する setopt list_packed #/補完候補表示時などにピッピとビープ音をならないように設定 setopt nolistbeep # 初期化 autoload -U compinit compinit ## 補完方法毎にグループ化する。 ### 補完方法の表示方法 ### %B...%b: 「...」を太字にする。 ### %d: 補完方法のラベル zstyle ':completion:*' format '%B%d%b' zstyle ':completion:*' group-name '' ## 補完侯補をメニューから選択する。 ### select=2: 補完候補を一覧から選択する。 ### ただし、補完候補が2つ以上なければすぐに補完する。 zstyle ':completion:*:default' menu select=2 ## 補完候補に色を付ける。 ### "": 空文字列はデフォルト値を使うという意味。 zstyle ':completion:*:default' list-colors "" ## 補完候補がなければより曖昧に候補を探す。 ### m:{a-z}={A-Z}: 小文字を大文字に変えたものでも補完する。 zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' ## 補完方法の設定。指定した順番に実行する。 ### _oldlist 前回の補完結果を再利用する。 ### _complete: 補完する。 ### _match: globを展開しないで候補の一覧から補完する。 ### _ignored: 補完候補にださないと指定したものも補完候補とする。 ### _approximate: 似ている補完候補も補完候補とする。 ### _prefix: カーソル以降を無視してカーソル位置までで補完する。 zstyle ':completion:*' completer \ _oldlist _complete _match _ignored _approximate _prefix ## 補完候補をキャッシュする。 zstyle ':completion:*' use-cache yes ## 詳細な情報を使う。 zstyle ':completion:*' verbose yes ## sudo時にはsudo用のパスも使う。 zstyle ':completion:sudo:*' environ PATH="$SUDO_PATH:$PATH" ## カーソル位置で補完する。 setopt complete_in_word ## globを展開しないで候補の一覧から補完する。 setopt glob_complete ## 補完時にヒストリを自動的に展開する。 setopt hist_expand ## 補完候補がないときなどにビープ音を鳴らさない。 setopt no_beep ## 辞書順ではなく数字順に並べる。 setopt numeric_glob_sort # 展開 ## --prefix=~/localというように「=」の後でも ## 「~」や「=コマンド」などのファイル名展開を行う。 setopt magic_equal_subst ## 拡張globを有効にする。 ## glob中で「(#...)」という書式で指定する。 setopt extended_glob ## globでパスを生成したときに、パスがディレクトリだったら最後に「/」をつける。 setopt mark_dirs # ジョブ ## jobsでプロセスIDも出力する。 setopt long_list_jobs # 実行時間 ## 実行したプロセスの消費時間が3秒以上かかったら ## 自動的に消費時間の統計情報を表示する。 REPORTTIME=3 # ログイン・ログアウト ## 全てのユーザのログイン・ログアウトを監視する。 watch="all" ## ログイン時にはすぐに表示する。 log ## ^Dでログアウトしないようにする。 setopt ignore_eof # 単語 ## 「/」も単語区切りとみなす。 WORDCHARS=${WORDCHARS:s,/,,} ## 「|」も単語区切りとみなす。 ## 2011-09-19 WORDCHARS="${WORDCHARS}|" ## **** /ウィンドウタイトル ## # 実行中のコマンドとユーザ名とホスト名とカレントディレクトリを表示。 update_title() { local command_line= typeset -a command_line command_line=${(z)2} local command= if [ ${(t)command_line} = "array-local" ]; then command="$command_line[1]" else command="$2" fi print -n -P "\e]2;" echo -n "(${command})" print -n -P " %n@%m:%~\a" } # X環境上でだけウィンドウタイトルを変える。 if [ -n "$DISPLAY" ]; then preexec_functions=($preexec_functions update_title) fi
sshの鍵登録をする
vagrant sshコマンドでログインできるように公開鍵を登録する。公開鍵はここから取得する。
cd ~/.ssh/ wget https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pumv mv vagrant.pub authorized_keys
VMからVagrant Boxを作る
既存のVMからVagrant Boxを作るのは簡単。以下のコマンドを実行するだけ。
➤ vagrant halt ➤ vagrant package ➤ vagrant box add ubuntu14.04_for_docker package.box
これで、VMからboxが生成された。後はいつもどおりvagrant init ubuntu14.04_for_docker
で追加されたboxを使うことができる。
➤ mkdir test_customized_box ➤ cd test_customized_box ➤ vagrant init ubuntu14.04_for_docker ➤ vagrant up
終了。。。と思いきや以下のようにエラーが出た。
Bringing machine 'default' up with 'virtualbox' provider... ==> default: Importing base box 'ubuntu14.04_for_docker'... ==> default: Matching MAC address for NAT networking... ==> default: Setting the name of the VM: test_customized_box_default_1449116982418_22480 ==> default: Fixed port collision for 22 => 2222. Now on port 2203. ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 22 => 2203 (adapter 1) ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2203 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Connection timeout. Retrying... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... default: The guest additions on this VM do not match the installed version of default: VirtualBox! In most cases this is fine, but in rare cases it can default: prevent things such as shared folders from working properly. If you see default: shared folder errors, please make sure the guest additions within the default: virtual machine match the version of VirtualBox you have installed on default: your host and reload your VM. default: default: Guest Additions Version: 4.3.10 default: VirtualBox Version: 5.0 ==> default: Mounting shared folders... default: /vagrant => /Users/takayuki/Desktop/test_ubuntu/test_customized_box Failed to mount folders in Linux guest. This is usually because the "vboxsf" file system is not available. Please verify that the guest additions are properly installed in the guest and can work properly. The command attempted was: mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant The error output from the last command was: stdin: is not a tty /sbin/mount.vboxsf: mounting failed with the error: No such device
原因を探していたが、同様な症状のFailed to mount folders in Linux guest. This is usually because the “vboxsf” file system is not available.を直す方法という記事が見つかった。
カーネルがアップデートされたことにより、VitualBox GuestAdditionが壊れ、vboxsfのマウント機能が動かなくなったのが原因らしい。
VMにログインして必要なパッケージのアップデートやインストールでも対応可能だが、ホストがからも修正可能なので以下を実行する。
➤ vagrant plugin install vagrant-vbguest ➤ vagrant vbguest ➤ vagrant reload
あとは、またパッケージを作りなおせばOK。一応sshでログインしてKernelバージョンを確認する。
$ uname -a Linux vagrant-ubuntu-trusty-64 3.19.8-031908-generic #201505110938 SMP Mon May 11 13:39:59 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
できた!
Boxファイルの圧縮の話
今回作成したboxは圧縮などの容量削減対策は一切していない。したい場合はVagrant のベースBOX を更新するとかVagrant用のboxファイルを小さくするを参考にするといい。
参考
UbuntuとKenel
UbuntuのKernelアップデート関連
- Kernel/MainlineBuilds - Ubuntu Wiki
- How can I install 3.16 kernel on Ubuntu 14.04 ainline-version-without-any-distro-upgrade)
- Index of /~kernel-ppa/mainline