Featured image of post Crear una maquina virtual (VM) Linux

Crear una maquina virtual (VM) Linux

Como crear una maquina virtual de forma automatizada con Vagrant

Creación de Maquina virtual.

Aprovecharé que hace unas semanas me contactó alguien para dar apoyo a su prueba de ingreso laboral y por tratarse de fin de semana, no envíe respuestas hasta el lunes a primera hora, pero la falta de voy a decir comunicación (y no falta de juicio o seriedad) cuando envié la respuesta me contestaron que no era necesaria, ya que había contratado a alguien más para que resolviera el cuestionario y bueno, las preguntas aunque básicas ya quedaron resueltas e intentaré entonces aprovecharlas y adornarlas un poco para que justifiquen un pequeño tutorial.

La prueba de capacidades técnicas planteaba un pequeño escenario, que considero practico para el aprendizaje y comento a continuación:

Consistía en:

“Instalar cualquier herramienta de virtualización para crear una máquina en la que se debe instalar un sistema operativo Linux a consideración del participante.

Una vez realizado, se debe garantizar la respectiva conexión de puertos para acceder desde alguna de las interfaces de del equipo anfitrión a los servicios que sean creados y expuestos en la máquina virtual.”

Procedemos entonces a ello, Los métodos más comunes para la creación de máquinas virtuales son:

MacOS X: VMware Fusion, Parallels Desktop y VirtualBox de Oracle. Linux: KVM quemu, VMWare, Virtualbox de Oracle. Windows: VMWare, Virtualbox de Oracle y Microsoft Hyper-v

Mi entorno de elección es obviamente Linux y aunque Virtualbox en lugar de KVM/quemu supone un paso adicional (la instalación de virtualbox), me decanto por virtualbox

Procedimiento: Descargar e instalar Virtualbox

Descargar e instalar virtualbox desde: https://www.virtualbox.org/wiki/Downloads recordar descargar e instalar el VirtualBox Extension Pack https://download.virtualbox.org/virtualbox/6.1.32/Oracle_VM_VirtualBox_Extension_Pack-6.1.32.vbox-extpack

En mi caso utilizo Fedora Linux, con lo que la instalación puede ser bastante simple, bastará con:

1
sudo dnf in VirtualBox -y

Indicaciones para la instalación de Virtualbox en otras distribuciones Linux: https://www.virtualbox.org/wiki/Linux_Downloads

y para tener control del entorno y total flexibilidad planteo gestionar la VMs a través de vagrant, así que se hace necesario descargar e instalar vagrant desde https://www.vagrantup.com/downloads

Instalación de vagrant en Fedora:

1
2
3
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
sudo dnf -y install vagrant

Creación de la maquina virtual,

Características de la VM:

OS seleccionado: Rocky Linux 8,

Nombre de la VM: vmrocky

Host name: prueba

Tamaño de memoria ram asignado: 2gb.

script de inicio: comandos.sh (este contendrá los comandos iniciales que se desee ejecutar al inicio de la máquina, por ejemplo actualizaciones, instalación de paquetes o configuraciones generales.)

Redirrección de puertos: del 8088 al 8080 de localhost

Tamaño del disco: por defecto de la imagen

Puerto SSH: redirección por defecto a localhost:2222

Script de instalación:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
cd ~/
mkdir vagrant-rocky-conf
cd vagrant-rocky-conf
cat <<EOF >Vagrantfile
Vagrant.configure("2") do |config|
  if Vagrant.has_plugin?("vagrant-vbguest") then
      config.vbguest.auto_update = false
  end
  config.vm.define "vmrocky" do |vmrocky|
    vmrocky.vm.box = "rockylinux/8"
    vmrocky.vm.box_version = "4.0.0"
    vmrocky.vm.hostname = 'prueba'
    vmrocky.vm.network "forwarded_port", guest: 8088, host: 8080
    vmrocky.vm.provision "shell", path: "comandos.sh"
    vmrocky.vm.provider "virtualbox" do |vb|
      vb.memory = "2048"
    end
  end
end
EOF

echo "Creado el archivo de configuraciones Vagrant"
cat <<EOF >comandos.sh
#!/bin/bash
rm -rf /usr/sbin/vbo*
dnf clean all
dnf makecache
dnf update -y
dnf install -y epel-release wget
dnf install -y nginx gcc make perl kernel-devel kernel-headers bzip2 dkms
sed -i s/^SELINUX=.*$/SELINUX=disabled/ /etc/selinux/config
sleep 5s
systemctl enable nginx
systemctl restart nginx
sed  -i 's/listen       80/listen       8088/g' /etc/nginx/nginx.conf
/sbin/shutdown -r now
EOF
echo "Creado el archivo de comandos"
echo "Iniciando la instalación de la VM"
# he instalar el plugin vagrant-vbguest que instalará Virtualbox Guest Additions necesario para gestionar con facilidad la VM 
vagrant plugin install vagrant-vbguest
vagrant up

Conexión SSH a la VM

Ahora, también se solicita que el acceso a la máquina Linux se debe hacer por SSH, sin usar password, usando una llave SSH. Se debe generar un par de llaves SSH (llave pública y llave privada) con formato RSA y tamaño 4096 bits. Esta llave debe ser agregada al usuario con el cual se accederá a la máquina virtual para realizar las posteriores actividades de la prueba.

para cumplir con lo solicitado, se crea una llave RSA de 4096 bits y se copia a la carpeta donde hemos puesto el archivo de configuración Vagrant, que por defecto será la carpeta compartida de la VM con el host

1
2
3
ssh-keygen -t rsa -b 4096
cp ~/.ssh/id_rsa.pub ~/vagrant-rocky-conf/id_rsa.pub
cd ~/vagrant-rocky-conf

Por defecto la conexión en vagrant se realiza utilizando una llave en lugar de clave, lo que cubriría la solicitud, pero para ingresar de manera automática desde cualquier folder sin recurrir a las llaves de vagrant y en su lugar usar la llave creada anteriormente se hace lo siguiente:

1
2
3
vagrant ssh vmrocky
# para copiar y la llave RSA creada en el paso anterior se escribe el contenido del archivo en .ssh/authorized_keys ya como usuario en la VM
cat /vagrant/id_rsa.pub >>~/.ssh/authorized_keys

de esta forma el sistema queda preparado para conectarse desde el entorno configurado de vagrant y desde cualquier fonder con las llaves ssh del usuario así:

ssh -l vagrant -p 2222 127.0.0.1

Tareas de administración de sistemas Linux

  1. Instalar un servidor web (Preferiblemente Nginx o Apache)

    elegido nginx por requerir poca ram para su funcionamiento y ser de fácil configuración

  2. Cambiar el puerto por defecto del servidor para que sea 8088 archivo de configuración por defecto /etc/nginx/nginx.conf

  3. En la página web por defecto del servidor instalado poner un texto con los siguientes datos:

    A). Breve descripción de cómo instaló el servidor Web, ¿qué herramientas o comandos usó?, ¿qué inconvenientes encontró?

    En nginx el puerto por defecto es el 80 y se gestiona desde el archivo nginx.conf o a través de cada archivo vhost, en la instalación por defecto sólo es necesario cambiar el puerto en el archivo nginx.conf, sin embargo es necesario tener en consideración que en el caso de sistemas RHEL o basados en este, selinux se encuentra activo y configurado para controlar el acceso a puertos a través de servicios, así que es necesario o configurar las reglas de selinux o desabilitarlo, para este caso se elige desabilitarlo editando el archivo /etc/selinux/config y reiniciando la máquina.

    Los comandos utilizados fueron:

    Instalación de nginx

    1
    2
    
    sudo su -
    dnf install -y nginx 
    

    Configuración de selinux

    1
    
       sed -i s/^SELINUX=.*$/SELINUX=disabled/ /etc/selinux/config
    

    Cambio de puerto en nginx

    1
    
       sed  -i 's/listen       80/listen       8088/g' /etc/nginx/nginx.conf
    

    Habilitar nginx y arrancar el servicio

    1
    
       systemctl enable --now nginx
    

    B). Los siguientes datos de la máquina en la que está instalado el servidor web y que comandos de Linux usó para averiguarlos: ¿Qué Sistema Operativo tiene la máquina?

Información:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
   Rocky Linux release 8.5 (Green Obsidian)
   NAME="Rocky Linux"
   VERSION="8.5 (Green Obsidian)"
   ID="rocky"
   ID_LIKE="rhel centos fedora"
   VERSION_ID="8.5"
   PLATFORM_ID="platform:el8"
   PRETTY_NAME="Rocky Linux 8.5 (Green Obsidian)"
   ANSI_COLOR="0;32"
   CPE_NAME="cpe:/o:rocky:rocky:8:GA"
   HOME_URL="https://rockylinux.org/"
   BUG_REPORT_URL="https://bugs.rockylinux.org/"
   ROCKY_SUPPORT_PRODUCT="Rocky Linux"
   ROCKY_SUPPORT_PRODUCT_VERSION="8"
   Rocky Linux release 8.5 (Green Obsidian)

Comando utilizado

1
   cat /etc/*-release

Espacio en Disco

Información:

1
2
3
4
5
6
7
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  972M     0  972M   0% /dev
tmpfs          tmpfs     989M     0  989M   0% /dev/shm
tmpfs          tmpfs     989M   17M  973M   2% /run
tmpfs          tmpfs     989M     0  989M   0% /sys/fs/cgroup
/dev/sda1      xfs        40G  4.4G   35G  12% /
tmpfs          tmpfs     198M     0  198M   0% /run/user/1000

Comando utilizado

1
df -Th

Cantidad de memoria RAM

Información:

1
2
3
              total        used        free      shared  buff/cache   available
Mem:           1976         136        1319          16         521        1674
Swap:          2047           0        2047

Comando:

1
free -m

Versión del kernel de Linux

Información:

1
4.18.0-348.20.1.el8_5.x86_64

Comando:

1
uname -r

Características del CPU

Información:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 142
model name	: Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz
stepping	: 12
cpu MHz		: 2075.466
cache size	: 6144 KB
physical id	: 0
siblings	: 2
core id		: 0
cpu cores	: 2
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti fsgsbase avx2 invpcid rdseed clflushopt md_clear flush_l1d arch_capabilities
bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds
bogomips	: 4150.93
clflush size	: 64
cache_alignment	: 64
address sizes	: 39 bits physical, 48 bits virtual
power management:

processor	: 1
vendor_id	: GenuineIntel
cpu family	: 6
model		: 142
model name	: Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz
stepping	: 12
cpu MHz		: 2075.466
cache size	: 6144 KB
physical id	: 0
siblings	: 2
core id		: 1
cpu cores	: 2
apicid		: 1
initial apicid	: 1
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti fsgsbase avx2 invpcid rdseed clflushopt md_clear flush_l1d arch_capabilities
bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds
bogomips	: 4150.93
clflush size	: 64
cache_alignment	: 64
address sizes	: 39 bits physical, 48 bits virtual
power management:

Comando:

1
cat /proc/cpuinfo

IP Privada

Información:

1
2
3
4
5
6
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:fc:e9:96 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0
       valid_lft 83012sec preferred_lft 83012sec
    inet6 fe80::a00:27ff:fefc:e996/64 scope link 
       valid_lft forever preferred_lft forever

comando:

1
ip address show eth0

Resumen de realizados para el archivo comandos.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
cat <<EOF >comandos.sh
#!/bin/bash
rm -rf /usr/sbin/vbo*
dnf clean all
dnf makecache
dnf update -y
dnf install -y epel-release wget
dnf install -y nginx gcc make perl kernel-devel kernel-headers bzip2 dkms
sed -i s/^SELINUX=.*$/SELINUX=disabled/ /etc/selinux/config
sleep 5s
sed  -i 's/listen       80/listen       8088/g' /etc/nginx/nginx.conf
systemctl enable nginx
systemctl restart nginx
EOF

Instalación de VBoxGuestAdditions

1
2
3
4
5
6
7
8
#manual 
wget http://download.virtualbox.org/virtualbox/6.1.32/VBoxGuestAdditions_6.1.32.iso -P /tmp
mount /tmp/VBoxGuestAdditions_6.1.32.iso /mnt
/mnt/VBoxLinuxAdditions.run 
#o automático 
vagrant plugin install vagrant-vbguest
vagrant up
vagrant vbguest --do install

A este punto se debe reiniciar la máquina para que tome los cambios de VBoxLinuxAdditions.run

Estos datos deben verse usando localhost o el hostname del equipo cuyos puertos de servicio serán redirigidos a la máquina virtual.

Para presentar el archivo index.html a través de nginx :

1
cp /vagrant/index.html /usr/share/nginx/html/index.html

y desde la máquina anfitriona dirigirse a http://127.0.0.1:8080

Tareas de administración Linux

Crear el grupo de usuarios cloud. Crear el usuario ninja con los siguientes datos: a. Grupo principal: cloud b. Nombre completo: Cloud Ninja c. Contraseña: testninja

Script:

1
2
3
4
5
#!/bin/bash
groupadd cloud
adduser ninja -g cloud 
usermod -c "Cloud Ninja" ninja
echo -e "testninja\ntestninja" | passwd ninja

Crear un cronjob para el usuario ninja que guarde cada 15 minutos la fecha en formato Unix time y la carga de CPU en el archivo load.txt, este archivo deberá estar ubicado en el directorio home del usuario ninja. Asegurarse que en el archivo quede el histórico de todas la carga de la CPU

1
2
3
4
5
6
7
8
cat <<EOF >~/script.sh
#!/bin/bash
date +%s >>~/load.txt
ps -e -o pcpu,pmem,args --sort=pcpu | cut -d" " -f1-5 | tail >>~/load.txt
EOF
chmod +x ~/script.sh
echo "*/15  * * * * ninja /home/ninja/script.sh" >>/etc/crontab

Tareas de DevOps

  1. Instalar y configurar Git
  2. Crear un repositorio en GitHub (si no tiene cuenta en Github debe crearla).
  3. Configurar el acceso a Github desde la máquina virtual usando SSH
1
2
3
4
dnf install git gh vim -y
git config --global user.name "ninjaemail"
git config --global user.email ninjaemail@tuemail.com
git config --global core.editor vim

https://docs.github.com/es/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account

Inicializar repositorio local

1
2
3
4
git init -b main
git add . && git commit -m "initial commit"
gh auth login
gh repo create

Crear un branch con el contenido alterno de la página. Enviar este branch al repositorio en Github.

Hacer un Pull request entre ese branch y el master en GitHub.

Creando rama del repositorio alternol

1
2
3
4
5
6
7
8
9
git checkout -b alternol
git push origin alternol
git remote add alterno alternol
echo "new file" >new.txt
git add new.txt
git push --set-upstream origin alternol
git commit -m "2 commit"
git push -u origin alternol

Aquí desde tu cuenta en https://github.com/ puedes hacer el merge

1
2
3
git checkout main
git branch -a #Puedes verificar la selección de la rama
git tag 1.0.0
comments powered by Disqus