Crear una máquina virtual base CentOS para Vagrant

Vagrant es un software que permite manejar máquinas virtuales desde la linea de comandos. Muy útil cuando uno necesita un entorno aislado para probar software o correr un servicio. Por ejemplo un servidor LDAP o html.

En esta entrada explico en términos generales como crear una máquina base para Vagrant. Dicha máquina se usa posteriormente para crear rápidamente una nueva máquina virtual cuando se necesite.

Asumiré que se tiene ya cierta experiencia usando Vagrant. La mayor parte del proceso que aquí se describe es desde una terminal. Crearemos una máquina virtual con CentOS 7.

Instalación de CentOS en VirtualBox

El primer paso instalar virtualbox y luego descargar centos. Si estás leyendo esto probablemente ya estás familiarizado con cómo instalar máquinas virtuales así que no explicare eso a detalle.

En mi caso decidí nombrar mi máquina virtual vagrant-centos7-64, es importante recordar el nombre a lo largo de todo el proceso.

Dado que nuestra interacción con la máquina virtual será a través de la línea de comandos, para mejorar el rendimiento es necesario deshabilitar audio y usb en la máquina cliente.

Al hacer la instalación es necesario usar los siguientes datos:

  • Usuario: vagrant
  • Password (también para root): vagrant
  • Hostname vagrantbox

Pasos adicionales post-instalación

Una vez finalizada la instalación hay que configurar algunas cosas en nuestra máquina cliente.

Instalar y habilitar ssh

Primero instalamos y habilitamos ssh para que arranque al iniciar. Desde una terminal como root usaremos los siguientes comandos:

yum install openssh-server
systemctl start sshd
systemctl enable sshd

Instalar Guest Additions

Instalaremos la paquete de extensión Guest Additions para en CentOS. Primero debemos instalar algunas cosas adicionales. Desde una terminal corremos el siguiente comando como administrador

yum install vim wget gcc bzip2 make kernel-devel-`uname -r`

Ahora en el menú de virtualbox damos click en Device -> Install Guest Additions… (o el equivalente en español). Si decidimos instalar algún entorno de escritorio en CentOS podemos seguir el resto de la instalación en el instalador gráfico en pantalla. En mi caso como el uso principal será por terminal decidí no instalar ningún entorno gráfico, así que para completar la instalación usaré los siguientes comandos.

mkdir /media/cdrom
mount /dev/cdrom /media/cdrom
sudo sh /media/cdrom/VBoxLinuxAdditions.run

Sudar sin contraseña

Lo que sigue es obviamente un enorme hoyo de seguridad en su sistema. Pero el objetivo de usar vagrant no es para máquinas en producción sino para hacer pruebas. Así que deshabilitaremos el que nos pida contraseña cada vez que usamos sudo, con lo que podremos hacer labores administrativas más fácilmente como usuario.

Para esto editaremos un archivo de texto con las configuraciones adecuadas. Corremos el siguiente comando:

visudo -f /etc/sudoers.d/vagrant

Lo que nos abrirá el editor vi para editar el archivo. Si no estás familiarizado con este editor, debes presionar i para poder insertar texto, echo eso ahora escribe lo siguiente:

vagrant ALL=(ALL) NOPASSWD:ALL

Para guardar el documento y salir ahora presiona ESC y en seguida escribe :wq

Apaga tu máquina virtual para configurar un par de cosas adicionales.

Abrir puertos para ssh en virtualbox

Una vez que la máquina virtual está apagada debemos asegurarnos de que en las configuraciones el Adaptador de red 1 está en modo NAT, éste es usualmente el valor por defecto así que solo hay que verificarlo. Ahora agregamos la siguiente regla de port-forwarding

[Name: SSH, Protocol: TCP, Host IP: blank, Host Port: 2222, Guest IP: blank, Guest Port: 22]

Se puede hacer desde la interfaz gráfica de VirtualBox, o más fácilmente desde la terminal con el siguiente comando:

VBoxManage modifyvm "vagrant-centos7-64" --natpf1 "guestssh,tcp,,2222,,22"

Enseguida arrancamos de nuevo nuestra máquina virtual para probar que ssh funciona correctamente. Una vez que CentOS haya iniciado abre una terminal en tu máquina Host, vamos a tratar de conectarnos a nuestra máquina virtual desde afuera con el siguiente comando:

ssh -p 2222 root@127.0.0.1

Deberías recibir una pequeña advertencia y luego te pedirá tu contraseña para root, que como establecimos al inicio debe ser vagrant.

Todo debería ir bien hasta ahora. Puedes seguir con el resto de este post desde «afuera» conectado por ssh abrir o directamente tu máquina virtual.

Añadir llave ssh de vagrant

Ahora añadiremos la llave insegura ssh para poder conectarnos a CentOS sin que nos pida contraseña. Dicha llave será reemplazada posteriormente por una llave segura aleatoria la primera vez que nos conectemos desde vagrant.

Abrimos una terminal en nuestra máquina virtual y ejecutamos los siguientes comandos:

mkdir -p /home/vagrant/.ssh
chmod 0700 /home/vagrant/.ssh
wget --no-check-certificate \
   https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub \
   -O /home/vagrant/.ssh/authorized_keys
chmod 0600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant /home/vagrant/.ssh

Ahora necesitamos decirle a ssh que use esta llave como método de autenticación. Para ello abriremos el archivo de configuración con nuestro editor favorito, en mi caso vim (remplazar por nano, emacs o lo que sea que usted use):

sudo vim /etc/ssh/sshd_config

Buscamos y descomentamos la siguiente línea

AuthorizedKeysFile %h/.ssh/authorized_keys

Guardamos y salimos del editor. Luego reiniciamos el servicio desde una terminal

sudo systemctl restart sshd

Toques finales, actualizar y limpiar

Ya estamos casi listos para empaquetar nuestra máquina virtual. Lo siguientes pasos son opcionales pero recomendables desde mi punto de vista.

Primero hay que actualizar esta vaina.

sudo yum update

Limpiamos el cache para borrar los archivos que hayan sido descargados durante la actualización.

sudo yum clean all

Finalmente apagamos la máquina virtual

shutdown 0

Empaquetar con vagrant

Ahora estamos listo para empaquetar la máquina virtual. Hay que crear una carpeta donde se guardará dicho archivo. En mi caso será en vagrant-boxes/vagrant-centos7-64. Desde una terminal navegamos hasta dicha ubicación.

cd ~/vagrant-boxes/vagrant-centos7-64

Enseguida empaquetamos la máquina virtual

vagrant package --base vagrant-centos7-64

Se mostraran algunos mensajes en la terminal:

==> vagrant-centos7-64: Attempting graceful shutdown of VM...
==> vagrant-centos7-64: Clearing any previously set forwarded ports...
==> vagrant-centos7-64: Exporting VM...
==> vagrant-centos7-64: Compressing package to: /home/geri/vagrant-boxes/vagrant-centos7-64/package.box

Eso es todo, en este momento debería haber un archivo llamado package.box en nuestro directorio actual.

Probar nuestra máquina base

Ahora probaremos que funciona. Vamos a crear una nueva máquina virtual a partir del paquete. Llamaré mi máquina virtual test y crearé una carpeta con ese nombre en vagrant-boxes

mkdir vagrant-boxes/test
cd vagrant-boxes/test

Añadimos la máquina virtual y luego la inicializamos:

vagrant box add test ../vagrant-centos7-64/package.box
vagrant init test

El segundo argumento de vagrant box add es la ruta hacia el la máquina base que creamos en la sección anterior.

El segundo comando creará el archivo Vagrantfile que nos permite modificar algunas configuraciones de nuestra máquina virtual. Por ejemplo, podemos permitir que la máquina virtual sea visible en nuestra red local descomentando la siguiente línea:

config.vm.network "public_network"

Listo, ahora podemos iniciar la máquina de prueba:

vagrant up

Se verá algo como esto

Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'air-gap'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: air-gap_default_1495680189444_50064
==> default: Clearing any previously set network interfaces...
==> default: Available bridged network interfaces:
1) enp2s0
2) enp3s0
==> default: When choosing an interface, it is usually the one that is
==> default: being used to connect to the internet.
    default: Which interface should the network bridge to? 1
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: bridged
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default:
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default:
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Mounting shared folders...
    default: /vagrant => /home/geri/vagrant-boxes/test

Como se indica el mensaje del final la carpeta actual se usa como carpeta compartida. La ruta a la carpeta desde dentro de la máquina virtual es /vagrant

Nos conectamos por ssh con este comando:

vagrant ssh

Debería aparecer el prompt que nos indica que ya estamos dentro de CentOS 7.

Si queremos apagar la máquina virtual para regresar luego usamos.

vagrant halt

O podemos borrar la máquina virtual por completo y hacer como que nunca existió con

vagrant destroy