⚰️

PackerでVagrant用のBoxを作る-①

2021/02/27に公開

はじめに

この記事では、以下を行います

  1. PackerでBoxを作成
  2. 作成したBoxを用いて仮想マシンを作成
  3. 仮想マシンに接続

作業環境

Macで作業を行いました(Windows環境でも確認できたら追記予定)
※各ソフトウェアのバージョンは最新ではありません

ソフトウェア Packer Vagrant VirtualBox
バージョン 1.6.0 2.2.4 6.1.10

始める前の準備

インストール以外で他に何を準備するんだ?って感じですが...
使用するVirtualBoxのバージョンが6.1以降?だと、Vagrantのバージョンによっては対応していない場合があるため、その対応を行います

VirtualBox6.1をProviderとして認識させる

インストールした時点でのVagrant2.2.4だと、VirualBox6.1系をProviderとして認識いないため、参考サイト通りに対応させます

VagrantのProvidersに関するファイルは以下のパスです(バージョンは読み替えていただいて)
/opt/vagrant/embedded/gems/2.2.4/gems/vagrant-2.2.4/plugins/providers/

作業するディレクトリに移動

$ cd /opt/vagrant/embedded/gems/2.2.4/gems/vagrant-2.2.4/plugins/providers/virtualbox
  • drive_mapに6.1を追加
    (該当箇所があるので探してください)
driver/meta.rb
@logger.debug("Finding driver for VirtualBox version: #{@@version}")
          driver_map   = {
	    "4.0" => Version_4_0,
	    ~省略~
	    "6.0" => Version_6_0,
            "6.1" => Version_6_1, //この行を追加
          }
  • driverの作成
driver/version_6_1.rb
$ sudo tee driver/version_6_1.rb << EOF
require File.expand_path("../version_6_0", __FILE__)

module VagrantPlugins
  module ProviderVirtualBox
    module Driver
      # Driver for VirtualBox 6.1.x
      class Version_6_1 < Version_6_0
        def initialize(uuid)
          super

          @logger = Log4r::Logger.new("vagrant::provider::virtualbox_6_1")
        end
      end
    end
  end
end
EOF
  • module_Driverに6.1を追加
    (該当箇所があるので探してください)
plugin.rb
module Driver
  autoload :Meta, File.expand_path("../driver/meta", __FILE__)
  autoload :Version_4_0, File.expand_path("../driver/version_4_0", __FILE__)
  ~省略~
  autoload :Version_6_0, File.expand_path("../driver/version_6_0", __FILE__)
  autoload :Version_6_1, File.expand_path("../driver/version_6_1", __FILE__)  //この行を追加
end

以上を行い、VagrantからVirtualBoxに仮想マシンを構築できるかを確認します
試しに、centos7の仮想マシンを構築します

commnad
$ mkdir -p vagrant/centos7
$ cd vagrant/centos7
$ vagrant init centos/7
$ vagrant up
$ vagrant ssh
$ cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

Packerを使ってboxを作成する

やっと本題!

今回はCentOS7用のboxを作成します

Packerのいい所

  • コード管理できる
  • 同じ環境を誰でも作成できる
  • 他になんかありそうだけど思いつきませんでした

要はみんなハッピーになれます(雑でごめんなさい)

ディレクトリ構造

tree
.
├── packer
│   ├── development
│   │   └── centos7.json (テンプレート)
│   ├── kickstart
│   │   └── centos7.cfg (kickstart)
│   └── var
│       └── centos7.json (変数ファイル)
└── vagrant
    ├── box (Packerで作成するboxの出力先)
    │   └── centos7-machine.box
    └── centos7
        └── Vagrantfile

各ファイル

公開用のリポジトリを持っていないので、以下をご確認ください
(書き方やパラメータについて詳しく知りたいかはご自身で調べてください)

packer/development/centos7.json
{
    "variables": {
        },
    "builders": [
      {
        "type": "virtualbox-iso",
        "vm_name": "{{user `vm_name`}}",
        "guest_os_type": "RedHat_64",
        "iso_url": "{{user `iso_url`}}",
        "iso_checksum": "{{user `iso_checksum`}}",
        "http_directory": "{{user `http_directory`}}",
        "boot_command": [
            "<tab> text ks=http://{{.HTTPIP}}:{{.HTTPPort}}/centos7.cfg <enter>"
        ],
        "boot_wait": "10s",
        "shutdown_command": "echo {{user `ssh_password`}} | sudo -S shutdown -h now",
        "guest_additions_path": "/home/vagrant/VBoxGuestAdditions.iso",
        "disk_size": "10240",
        "vboxmanage": [
          ["modifyvm", "{{.Name}}", "--memory", "2048"],
          ["modifyvm", "{{.Name}}", "--cpus", "1"],
          ["modifyvm", "{{.Name}}", "--paravirtprovider", "kvm"]
        ],
        "headless": true,
        "ssh_username": "{{user `ssh_username`}}",
        "ssh_password": "{{user `ssh_password`}}",
        "ssh_timeout": "600s"
      }
    ],
    "post-processors": [
        [
            {
                "type": "vagrant",
                "output": "{{user `output_directory`}}/{{user `vm_name`}}.box"
              }
        ]
    ]
  }
packer/var/centos7.json
{
   "environment": "development",
   "vm_name": "centos7-machine",
   "iso_url": "http://ftp.riken.jp/Linux/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso",
   "iso_checksum": "07b94e6b1a0b0260b94c83d6bb76b26bf7a310dc78d7a9c7432809fb9bc6194a",
   "http_directory": "../kickstart",
   "ssh_username": "vagrant",
   "ssh_password": "vagrant",
   "output_directory": "../../vagrant/box"
}
packer/kickstart/centos.cfg
#version=DEVEL
# Install a fresh new system (optional)
install

# System authorization information
auth --enableshadow --passalgo=sha512

# Use CDROM installation media
cdrom

# Use graphical or text to install
text

firstboot --disabled
firewall --disabled
selinux --disabled

# Keyboard layouts
keyboard --vckeymap=jp --xlayouts='jp'

# System language
lang ja_JP.UTF-8

# Network information
network --bootproto=dhcp --onboot=on --device=eth0
network --hostname=dev-service

# Root password
rootpw --iscrypted パスワード

# create vagrant user
user --name=vagrant --plaintext --password vagrant

# System timezone
timezone Asia/Tokyo --isUtc

# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda
autopart --type=lvm

# Partition clearing information
clearpart --linux --initlabel

# machine reboot
reboot --eject

%post
#!/bin/bash
echo "%vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant
chmod 0440 /etc/sudoers.d/vagrant

mkdir /home/vagrant/.ssh
curl -L https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub -o /home/vagrant/.ssh/authorized_keys
chmod 0700 /home/vagrant/.ssh
chmod 0600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant /home/vagrant/.ssh
%end

ビルド

Packerを実行して、boxを作成します

command
$ cd packer/development
$ packer build -var-file=../var/centos7.json centos7.json

ビルド(多分5分ぐらい)が問題なく終わったら、出力先(../../vagrant/box)を確認しboxが出来上がっているのを確認します

command
$ cd ../../vagrant/box
$ ls
centos7-machine.box

仮想マシンの作成とアクセス

作成したBoxを追加し、仮想マシンを作成します
(initで作成されるVagrantfileの中身は変えません)

vagrant up を行うと色々とやりはるんで、終わるまで待ちましょう

command
$ cd ../centos7/
$ vagrant box add --name centos7-machine ../box/centos7-machine.box
$ vagrant init centos7-machine
$ vagrant up
$ vagrant ssh

おわりに

細かい説明などは省かせていただきましたが、やってることがなんとなく理解できるんじゃないかなーと思います

書いている私自身も、フワッとした感じで扱っているのは否めないので個人的にはこう使っているよ!ってのと備忘録としてここに書きました

次は、今回のにAnsibleを追加してもう少し実践的な内容にできればと思います!

それではまた。

Discussion