Note:

Crear pila de LAMP de varias máquinas virtuales en Oracle Virtualization

Introducción

En el núcleo de la solución Oracle Virtualization se encuentra el host de Oracle Linux KVM. Además de este hipervisor, puede ejecutar muchas máquinas virtuales, cada una de las cuales ejecuta uno de los sistemas operativos admitidos, incluidos Oracle Linux, RHEL, Windows, Ubuntu, Solaris y otros. Esta solución de virtualización se gestiona a través de Oracle Linux Virtualization Manager, que ofrece una única interfaz para mantener las cosas organizadas. Además de la gestión de varios hosts y varias máquinas virtuales, Oracle Linux Virtualization Manager permite funciones clave de la solución Oracle Virtualization. Por ejemplo, Oracle Linux Virtualization Manager proporciona alta disponibilidad automática con failover de VM, migración en directo de VM entre hosts sin tiempo de inactividad, control de acceso basado en roles y registro de auditoría, y flujos de trabajo simplificados de copia de seguridad y recuperación ante desastres. Estas funciones empresariales transforman Oracle Linux KVM de hosts individuales a una verdadera plataforma de virtualización empresarial.

En este tutorial, exploraremos la tecnología de hipervisor principal que impulsa Oracle Virtualization. La máquina virtual basada en núcleo (KVM) es un hipervisor de código abierto tipo 1 (bare-metal). Esta funcionalidad permite que un sistema host, como Oracle Linux, aloje varias máquinas virtuales (VM) o invitados cuando se ejecuta en hardware admitido.

En este tutorial se implementará Oracle Linux KVM para crear máquinas virtuales configuradas con aplicaciones de pila LAMP, lo que le permitirá alojar entornos de desarrollo web completos con componentes Linux, Apache, MySQL y PHP en varias máquinas virtuales.

Importante: Los dos códigos de aplicación de este laboratorio son solo para fines educativos. Están diseñados para ayudar a los desarrolladores a aprender y practicar las habilidades de desarrollo de aplicaciones con la pila LAMP. Estos códigos no están destinados a entornos de producción y no deben utilizarse tal cual en un entorno activo.

Objetivos

Requisitos

Cualquier sistema Oracle Linux con las siguientes configuraciones:

Paso 1: Despliegue de Oracle Linux

Nota: Si se ejecuta en su propio arrendamiento, lea el proyecto linux-virt-labs GitHub README.md y complete los requisitos antes de desplegar el entorno de prácticas.

  1. Abra un terminal desde Luna Desktop.

  2. Clone el proyecto linux-virt-labs GitHub.

    git clone https://github.com/oracle-devrel/linux-virt-labs.git
    
  3. Cambie al directorio de trabajo.

    cd linux-virt-labs/ol
    
  4. Instale las recopilaciones necesarias.

    ansible-galaxy collection install -r requirements.yml
    
  5. Despliegue el entorno de prácticas.

    ansible-playbook create_instance.yml -e localhost_python_interpreter="/usr/bin/python3.6" -e instance_ocpus="4" -e instance_memory="64"
    

    El entorno de prácticas libres necesita la variable adicional local_python_interpreter, que define ansible_python_interpreter para las reproducciones que se ejecutan en localhost. Esta variable es necesaria porque el entorno instala el paquete RPM para el SDK para Python de Oracle Cloud Infrastructure, que se encuentra en los módulos python3.6.

    La unidad de despliegue por defecto utiliza la CPU AMD y Oracle Linux 8. Para utilizar una CPU Intel, agregue -e instance_shape="VM.Standard3.Flex"

    Importante: Espere a que el cuaderno de estrategias se ejecute correctamente y alcance la tarea de pausa. En esta etapa del manual, se ha completado la instalación de Oracle Linux y las instancias están listas. Tome nota de la reproducción anterior, que imprime las direcciones IP públicas y privadas de los nodos que despliega y cualquier otra información de despliegue necesaria al ejecutar el ejercicio práctico.

Paso 2: Validar el entorno soporta la virtualización

  1. Abra un nuevo terminal desde Luna Desktop y conéctese mediante SSH a la instancia ol-node-01.

    ssh opc@<YOUR ol-node-01 PUBLIC_IP>
    
  2. Ejecute el siguiente comando para determinar el tipo de CPU.

    grep -e 'vendor_id' /proc/cpuinfo | uniq
    

    vendor_id informa AuthenticAMD para una CPU AMD o GenuinIntel para una CPU Intel.

  3. Compruebe si el hardware admite virtualización.

    Ejecute el comando que coincide con el tipo de CPU.

    1. Verifique que las extensiones de CPU AMD V existen.
    grep -w -o 'svm' /proc/cpuinfo | uniq
    
    1. Verifique que las extensiones de CPU Intel VT existen.
    grep -w -o 'vmx' /proc/cpuinfo | uniq
    

    La existencia de uno de estos indicadores en la salida del comando indica que este sistema admite la virtualización. También puede utilizar el comando lscpu y buscar la entrada Virtualization en la salida.

  4. Compruebe si hay módulos KVM cargados.

    lsmod | grep kvm
    

    La salida muestra los módulos de núcleo de KVM después de instalar paquetes de virtualización e iniciar el servicio libvirtd. En sistemas en la nube como OCI, estos módulos se cargan automáticamente cuando se inicia libvirtd, no durante la instalación del paquete. La secuencia de carga es: instalar paquetes → iniciar el servicio libvirtd → los módulos aparecen en la salida lsmod.

Paso 3: Instalación e inicio de KVM

  1. Compruebe la versión en ejecución de Oracle Linux.

    hostnamectl | grep 'Operating System'
    
  2. Instale los paquetes de software asociados para la virtualización de Oracle Linux.

    Estos comandos instalan los paquetes de virtualización, que incluyen libvirt, y otras dependencias en Oracle Linux. El paquete libvirt proporciona una biblioteca de software y una API para gestionar máquinas virtuales KVM e incluye el daemon libvirtd que se ejecuta en segundo plano para gestionar la gestión de máquinas virtuales real.

    sudo dnf module install -y virt
    
  3. Instalar virt-install: herramienta para crear y configurar máquinas virtuales (VM) mediante el hipervisor KVM (máquina virtual basada en núcleo).

    sudo dnf install -y virt-install
    
  4. Valide que la máquina host esté lista y configurada para ejecutar máquinas virtuales de libvirt.

    virt-host-validate
    

    Si se superan todas las comprobaciones, el sistema está preparado para crear máquinas virtuales. Si fallan las comprobaciones, siga las instrucciones para corregir el problema. Si alguna comprobación devuelve el valor WARN, considere seguir las instrucciones para mejorar las capacidades de virtualización.

  5. Inicie los servicios Systemd, lo que permite que se inicien automáticamente en cada inicio.

    sudo systemctl enable --now libvirtd.service
    
  6. Compruebe el estado de los servicios para confirmar que están activos y en ejecución.

    sudo systemctl status libvirtd.service
    

    La salida muestra el servicio como activado y en ejecución. Si es necesario, introduzca la letra 'q' para salir del modo de salida

Paso 4: Crear dos máquinas virtuales con imágenes de Oracle Cloud

  1. Cambie a la ubicación de almacenamiento de imágenes de KVM.

    cd /var/lib/libvirt/images
    
  2. Descargue la plantilla de VM de Oracle Linux.

    sudo curl -O https://yum.oracle.com/templates/OracleLinux/OL8/u10/x86_64/OL8U10_x86_64-kvm-b237.qcow2
    

    Crear VM-01 (base de datos)

  3. Cree un archivo de metadatos.

    cat << 'EOF' | sudo tee ~/meta-data > /dev/null
    instance-id: iid-local01
    local-hostname: vm-01
    EOF
    
  4. Cree un archivo de datos de usuario.

    cat << 'EOF' | sudo tee ~/user-data > /dev/null
    #cloud-config
    
    system_info:
      default_user:
        name: opc
    
    ssh_authorized_keys:
      - <paste_public_key_here>
    EOF
    
  5. Generar un par de claves SSH para una conexión segura a la máquina virtual

    ssh-keygen -t rsa -b 4096
    

    Pulse Enter para aceptar cada uno de los valores por defecto. El comando escribe el par de claves en el directorio .ssh del directorio raíz del usuario.

  6. Extraer la clave SSH pública generada
    SSHKEY=$(cat ~/.ssh/id_rsa.pub)
    
  7. Actualizar el archivo de datos de usuario con la clave SSH pública generada
    sed -i "s|<paste_public_key_here>|${SSHKEY}|g" ~/user-data
    
  8. Generar una imagen ISO que contenga los archivos de metadatos y datos de usuario
    sudo genisoimage -output /var/lib/libvirt/images/vm-01.iso -volid cidata -joliet -rock ~/user-data ~/meta-data
    
  9. Buscar la variante del sistema operativo que coincida con la imagen descargada
    osinfo-query os | grep ol8
    
  10. Copiar la imagen de Oracle Linux en una nueva imagen de disco para vm-01
    sudo cp /var/lib/libvirt/images/OL8U10_x86_64-kvm-b237.qcow2 /var/lib/libvirt/images/vm-01.qcow
    
  11. Crear una nueva máquina virtual denominada vm-01 con recursos y configuración especificados
    sudo virt-install --name vm-01 \
    --memory 2048 \
    --vcpus 2 \
    --disk /var/lib/libvirt/images/vm-01.qcow,device=disk,bus=virtio \
    --disk /var/lib/libvirt/images/vm-01.iso,device=cdrom \
    --os-type linux --os-variant ol8.10 \
    --virt-type kvm --graphics none \
    --network network=default,model=virtio \
    --noautoconsole \
    --import
    
  12. Mostrar todas las máquinas virtuales en ejecución
    sudo virsh list
    
  13. Recupere la dirección IP de la máquina virtual vm-01.

    sudo virsh net-dhcp-leases --network default
    
  14. Verifique que la máquina virtual funciona conectándose con ssh.

    ssh opc@<ip_address_of_vm-01>
    
  15. Obtenga detalles sobre la máquina virtual ejecutando hostnamectl.

    hostnamectl
    
  16. Salga del servidor vm-01 para continuar con el siguiente paso

    exit
    

    Puede verificar la versión y obtener detalles adicionales sobre el sistema operativo en la máquina virtual ejecutando hostnamectl.

    Crear VM-02 (servidor web)

  17. Crear un archivo de metadatos para vm-02

    cat << 'EOF' | sudo tee ~/meta-data > /dev/null
    instance-id: iid-local02
    local-hostname: vm-02
    EOF
    
  18. Generar una imagen ISO para vm-02
    sudo genisoimage -output /var/lib/libvirt/images/vm-02.iso -volid cidata -joliet -rock ~/user-data ~/meta-data
    
  19. Copiar la imagen de Oracle Linux en una nueva imagen de disco para vm-02
    sudo cp /var/lib/libvirt/images/OL8U10_x86_64-kvm-b237.qcow2 /var/lib/libvirt/images/vm-02.qcow
    
  20. Crear una nueva máquina virtual denominada vm-02 con recursos y configuración especificados
    sudo virt-install --name vm-02 \
    --memory 2048 \
    --vcpus 2 \
    --disk /var/lib/libvirt/images/vm-02.qcow,device=disk,bus=virtio \
    --disk /var/lib/libvirt/images/vm-02.iso,device=cdrom \
    --os-type linux --os-variant ol8.10 \
    --virt-type kvm --graphics none \
    --network network=default,model=virtio \
    --noautoconsole \
    --import
    
  21. Mostrar todas las máquinas virtuales en ejecución
    sudo virsh list
    
  22. Recupere la dirección IP de la máquina virtual vm-02.

    sudo virsh net-dhcp-leases --network default
    
  23. Verifique que la máquina virtual funciona conectándose con ssh.

    ssh opc@<ip_address_of_vm-02>
    
  24. Obtenga detalles sobre la máquina virtual ejecutando hostnamectl.

    hostnamectl
    
  25. Salga del servidor vm-02 para continuar con el siguiente paso

    exit
    
  26. Puede verificar la versión y obtener detalles adicionales sobre el sistema operativo en la máquina virtual ejecutando hostnamectl.

    hostnamectl
    

    Salida de ejemplo:

    [oracle@ol-node01 images]$ ssh opc@192.168.122.46
    The authenticity of host '192.168.122.46 (192.168.122.46)' can't be established.
    ECDSA key fingerprint is SHA256:xcuVfQdoFDCC72i7plD0OfqDTSBG6QWhOm5ti4HIKEs.
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added '192.168.122.46' (ECDSA) to the list of known hosts.
    
    [opc@vm-01 ~]$ hostnamectl
       Static hostname: vm-01
             Icon name: computer-vm
               Chassis: vm
            Machine ID: 30c9345b511448b681aafb3371de9792
               Boot ID: c2d5586b094f4d299a4ba6c05086d004
        Virtualization: kvm
      Operating System: Oracle Linux Server 8.10
           CPE OS Name: cpe:/o:oracle:linux:8:10:server
                Kernel: Linux 5.15.0-206.153.7.1.el8uek.x86_64
          Architecture: x86-64
    
  27. Extraiga la dirección IP de vm-01 y guárdela en la variable VM01_IP
     VM01_IP=$(sudo virsh net-dhcp-leases --network default | grep vm-01 | tail -1 | awk '{print $5}' | cut -d'/' -f1)
    
  28. Extraer la dirección IP de vm-02 y guardarla en la variable VM02_IP
     VM02_IP=$(sudo virsh net-dhcp-leases --network default | grep vm-02 | tail -1 | awk '{print $5}' | cut -d'/' -f1)
    
  29. Asegúrese de que la dirección IP de las máquinas virtuales se haya guardado correctamente:
     echo "VM-01 (Web): $VM01_IP"
    
     echo "VM-02 (Web): $VM02_IP"
    
  30. Prueba del comando SSH para las máquinas virtuales
     ssh -o ConnectTimeout=10 opc@$VM01_IP "echo 'VM-01 OK'"
    
     ssh -o ConnectTimeout=10 opc@$VM02_IP "echo 'VM-02 OK'"
    

Paso 5: Configurar MySQL en VM-01

Instalar MySQL

  1. Desde la instancia ol-node-01, SSH establece una conexión SSH a VM-01
     ssh opc@$VM01_IP
    
  2. Descargue la configuración del repositorio MySQL
     sudo yum -y install https://dev.mysql.com/get/mysql84-community-release-el8-1.noarch.rpm
    
  3. Desactive el módulo MySQL por defecto para evitar conflictos
     sudo yum -y module disable mysql
    
  4. Instalar el servidor y el cliente MySQL
     sudo yum install -y mysql mysql-server
    
  5. Iniciar el servicio MySQL
     sudo systemctl start mysqld
    
  6. Activar el servicio MySQL para que se inicie al iniciar
     sudo systemctl enable mysqld
    
  7. Permitir tráfico MySQL entrante a través del firewall
     sudo firewall-cmd --permanent --add-service=mysql
    
  8. Volver a cargar configuración de firewall para aplicar cambios
     sudo firewall-cmd --reload
    

    Configurar MySQL

  9. Extraer contraseña de usuario root temporal del log MySQL
     TEMP_PASS=$(sudo grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
    
  10. Inicie sesión en MySQL con contraseña de usuario root temporal
     mysql -uroot -p$TEMP_PASS --connect-expired-password
    
  11. Cambiar contraseña de usuario root a un valor seguro
     ALTER USER 'root'@'localhost' IDENTIFIED BY 'Welcome#123';
    
  12. Crear usuario 'admin' con una contraseña segura
     CREATE USER 'admin'@'%' IDENTIFIED BY 'Welcome#123';
    
  13. Otorgar todos los privilegios al usuario 'admin'
     GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;
    
  14. Crear usuario 'empuser' con una contraseña segura
     CREATE USER 'empuser'@'%' IDENTIFIED BY 'Welcome#123';
    
  15. Otorgar todos los privilegios a 'empuser'
     GRANT ALL PRIVILEGES ON *.* TO 'empuser'@'%' WITH GRANT OPTION;
    
  16. Volver a cargar tablas de privilegios para aplicar cambios
     FLUSH PRIVILEGES;
    
  17. Salir del shell MySQL
     \q
    
  18. Salir de la sesión SSH de VM-01
     exit
    

Paso 6: Configurar Apache/PHP en VM-02

  1. Desde la instancia ol-node-01, SSH establece una conexión SSH a VM-02
     ssh opc@$VM02_IP
    
  2. Instalar el servidor Apache HTTP
     sudo yum install -y httpd
    
  3. Instalar PHP 8.2 y sus dependencias
     sudo dnf install -y @php:8.2
    
  4. Instalar extensiones PHP MySQL y JSON
     sudo yum install -y php-mysqlnd php-json
    
  5. Activar e iniciar el servidor Apache HTTP
     sudo systemctl enable --now httpd
    
  6. Permitir tráfico HTTP entrante en el puerto 80
     sudo firewall-cmd --permanent --add-port=80/tcp
    
  7. Volver a cargar configuración de firewall para aplicar cambios
     sudo firewall-cmd --reload
    
  8. Permitir que Apache se conecte a los recursos de red
     sudo setsebool -P httpd_can_network_connect 1
    
  9. Salir de la sesión SSH de VM-02
     exit
    

Paso 7: Prueba de Apache

  1. Mostrar la dirección IP de VM-02 YOUR VM_02 IP:
     echo "VM-02 (Web): $VM02_IP"
    
  2. Abra un nuevo terminal desde Luna Desktop y cree un túnel SSH para acceder al servidor web VM-02 desde la máquina local

    … asegúrese de sustituir primero los **** y los ****

     ssh -L 8081:<YOUR VM_02 IP>:80 opc@<YOUR ol-node-01 PUBLIC_IP>
    
  3. Utilice un explorador de Luna o un entorno local para probar Apache accediendo al servidor web a través del túnel SSH
     http://localhost:8081
    

    Importante: Deje el túnel SSH y el explorador abiertos para su uso posterior

Paso 8: Crear Aplicación de Prueba


  1. Vuelva a la instancia ssh opc@ol-node-01

  2. Recuperar la dirección IP de VM-01 de los permisos de DHCP
     VM01_IP=$(sudo virsh net-dhcp-leases --network default | grep vm-01 | tail -1 | awk '{print $5}' | cut -d'/' -f1)
    
  3. Recuperar la dirección IP de VM-02 de los permisos DHCP
     VM02_IP=$(sudo virsh net-dhcp-leases --network default | grep vm-02 | tail -1 | awk '{print $5}' | cut -d'/' -f1)
    
  4. Desde la instancia ol-node-01, SSH establece una conexión SSH a VM-02
     ssh opc@$VM02_IP
    
  5. Crear una página de información de PHP para mostrar la configuración de PHP
     sudo tee /var/www/html/info.php > /dev/null << 'EOF'
     <?php phpinfo(); ?>
     EOF
    
  6. Crear aplicación de prueba de conexión de base de datos

     sudo tee /var/www/html/dbtest.php > /dev/null << 'EOF'
     <?php
     echo "<h1>Multi-VM LAMP Stack Test</h1>";
    
     // Database connection details
     define('DB_SERVER', '$VM01_IP');
     define('DB_USERNAME', 'admin');
     define('DB_PASSWORD', 'Welcome#123');
     define('DB_NAME', 'mysql');
    
     echo "<p>Testing connection to MySQL at: " . DB_SERVER . "</p>";
    
     // Test network connectivity
     $fp = @fsockopen(DB_SERVER, 3306, $errno, $errstr, 5);
     if (!$fp) {
         echo "<p style='color: red;'>ERROR: Cannot reach MySQL server</p>";
         echo "<p>Error: $errstr ($errno)</p>";
     } else {
         echo "<p style='color: green;'>✓ Network connection successful</p>";
         fclose($fp);
            
         // Test MySQL connection
         $link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
         if($link === false){
             echo "<p style='color: red;'>ERROR: Could not connect to MySQL</p>";
             echo "<p>Error: " . mysqli_connect_error() . "</p>";
         } else {
             echo "<p style='color: green;'>✓ Successfully Connected to MySQL!</p>";
             echo "<p>MySQL Version: " . mysqli_get_server_info($link) . "</p>";
             echo "<p>Host Info: " . mysqli_get_host_info($link) . "</p>";
             mysqli_close($link);
         }
     }
     ?>
     EOF
    
  7. Definir permisos de archivo de aplicación
     sudo chown apache:apache /var/www/html/*.php
    
  8. Actualice la línea define('DB_SERVER', '$VM01_IP'); cambiando el valor de $VM01_IP con el valor de dirección IP vm-01 guardado
     sudo vi /var/www/html/dbtest.php
    

    Salida de ejemplo:

    ``texto … código antes de definir('DB_SERVER', '$VM01_IP'); … código después de definir('DB_SERVER', '192.168.122.???');

  9. Salir de VM-02

     exit
    

Paso 9: Acceder a la aplicación Webserver y Database Test


  1. Si se cierra el túnel SSH, cree para la prueba básica
     ssh -L 8081:$VM02_IP:80 opc@<YOUR ol-node-01 PUBLIC_IP>
    
  2. Prueba básica de LAMP Examine para:
     http://localhost:8081/info.php
    
  3. Demostración de prueba básica de Database para:
    http://localhost:8081/dbtest.php
    

Resultados Esperados:

Paso 10: creación y carga de la base de datos de empleados

  1. Debe estar en la instancia ssh opc@ol-node-01

  2. Recuperar la dirección IP de VM-01 de los permisos de DHCP
     VM01_IP=$(sudo virsh net-dhcp-leases --network default | grep vm-01 | tail -1 | awk '{print $5}' | cut -d'/' -f1)
    
  3. Recuperar la dirección IP de VM-02 de los permisos DHCP
     VM02_IP=$(sudo virsh net-dhcp-leases --network default | grep vm-02 | tail -1 | awk '{print $5}' | cut -d'/' -f1)
    
  4. Desde la instancia SSH opc@ol-node-01, establezca una conexión SSH a VM-01
     ssh opc@$VM01_IP
    
  5. Cambiar a la carpeta /tmp
     cd /tmp
    
  6. Descargar base de datos de ejemplo de empleado MySQL
     sudo curl -L -o employees_db_full.zip "https://objectstorage.us-ashburn-1.oraclecloud.com/p/5UYZYk1vh241OqeHp_J0xnzBpzUOxZtTgaqCH16OP7HpOjC71W207gAY9EY1rW2U/n/idazzjlcjqzj/b/mysql-ee-downloads/o/employees_db_full.zip"
    
  7. Instalar herramientas de compresión
     sudo dnf install -y unzip
    
  8. Extraer la base de datos
     sudo unzip employees_db_full.zip
    
     cd employees_db_full
    
  9. Carga de la base de datos
     mysql -u admin -pWelcome#123 < employee.sql
    
  10. Verificar base de datos cargada
     mysql -u admin -pWelcome#123 -e "USE employee; SHOW TABLES; SELECT COUNT(*) FROM employee;"
    
  11. Salir de la máquina virtual de base de datos
     exit
    

Paso 11: Crear Aplicación Web de Base de Datos de Empleados

  1. Desde la instancia ol-node-01, SSH establece una conexión SSH a VM-02
     ssh opc@$VM02_IP
    
  2. Crear aplicación profesional de base de datos de empleados
     sudo tee /var/www/html/employee.php > /dev/null << 'EOF'
     <!DOCTYPE html>
     <html lang="en">
     <head>
         <meta charset="UTF-8">
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
         <title>Employee Database - Multi-VM LAMP Demo</title>
         <style>
             body { 
                 font-family: Arial, sans-serif; 
                 max-width: 1200px; 
                 margin: 0 auto; 
                 padding: 20px;
                 background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
             }
             .header { 
                 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                 color: white; 
                 text-align: center; 
                 padding: 30px;
                 border-radius: 15px;
                 margin-bottom: 20px;
                 box-shadow: 0 8px 16px rgba(0,0,0,0.1);
             }
             .info-box { 
                 background: rgba(255,255,255,0.9);
                 padding: 25px; 
                 border-radius: 12px;
                 box-shadow: 0 4px 8px rgba(0,0,0,0.1);
                 margin-bottom: 20px;
                 backdrop-filter: blur(10px);
             }
             .success { color: #28a745; font-weight: bold; }
             .error { color: #dc3545; font-weight: bold; }
             table { 
                 width: 100%; 
                 border-collapse: collapse; 
                 margin: 20px 0;
                 background: rgba(255,255,255,0.9);
                 border-radius: 12px;
                 overflow: hidden;
                 box-shadow: 0 4px 8px rgba(0,0,0,0.1);
             }
             th, td { 
                 padding: 15px; 
                 text-align: left; 
                 border-bottom: 1px solid #ddd;
             }
             th { 
                 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                 color: white;
                 font-weight: bold;
             }
             tr:hover { background-color: rgba(102, 126, 234, 0.1); }
             .stats { 
                 display: grid; 
                 grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); 
                 gap: 20px; 
                 margin: 20px 0; 
             }
             .stat-card { 
                 background: white; 
                 padding: 20px; 
                 border-radius: 10px; 
                 text-align: center; 
                 box-shadow: 0 4px 8px rgba(0,0,0,0.1);
             }
             .stat-number { font-size: 2em; font-weight: bold; color: #667eea; }
         </style>
     </head>
     <body>
         <div class="header">
             <h1>🏢 Employee Database Demo</h1>
             <p>MySQL Employee Sample Database on Multi-VM Architecture</p>
         </div>
    
         <?php
         // Database connection details
         define('DB_SERVER', '$VM01_IP');
         define('DB_USERNAME', 'empuser');
         define('DB_PASSWORD', 'Welcome#123');
         define('DB_NAME', 'employee');
    
         try {
             // Connect to MySQL database on separate VM
             $pdo = new PDO("mysql:host=" . DB_SERVER . ";dbname=" . DB_NAME, DB_USERNAME, DB_PASSWORD);
             $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                
             echo '<div class="info-box success">';
             echo '<h2>✅ Connected to Employee Database</h2>';
             echo '<p><strong>Database Server:</strong> ' . DB_SERVER . ' (vm-01)</p>';
             echo '<p><strong>Web Server:</strong> ' . gethostname() . ' (vm-02)</p>';
             echo '</div>';
                
             // Get database statistics
             $stats = [];
                
             $stmt = $pdo->query("SELECT COUNT(*) as count FROM employee");
             $stats['employee'] = $stmt->fetch()['count'];
                
             $stmt = $pdo->query("SELECT COUNT(*) as count FROM department");
             $stats['departments'] = $stmt->fetch()['count'];
                
             $stmt = $pdo->query("SELECT COUNT(*) as count FROM salary");
             $stats['salaries'] = $stmt->fetch()['count'];
                
             $stmt = $pdo->query("SELECT COUNT(*) as count FROM title");
             $stats['titles'] = $stmt->fetch()['count'];
                
             echo '<div class="info-box">';
             echo '<h2>📊 Database Statistics</h2>';
             echo '<div class="stats">';
             echo '<div class="stat-card"><div class="stat-number">' . number_format($stats['employee']) . '</div><div>Employee</div></div>';
             echo '<div class="stat-card"><div class="stat-number">' . number_format($stats['departments']) . '</div><div>Departments</div></div>';
             echo '<div class="stat-card"><div class="stat-number">' . number_format($stats['salaries']) . '</div><div>Salary Records</div></div>';
             echo '<div class="stat-card"><div class="stat-number">' . number_format($stats['titles']) . '</div><div>Job Titles</div></div>';
             echo '</div>';
             echo '</div>';
                
             // Show recent employee
             echo '<div class="info-box">';
             echo '<h2>👥 Sample Employee Data</h2>';
             $stmt = $pdo->query("SELECT emp_no, first_name, last_name, gender, hire_date FROM employee ORDER BY hire_date DESC LIMIT 20");
             $employee = $stmt->fetchAll();
                
             echo '<table>';
             echo '<thead><tr><th>Employee #</th><th>First Name</th><th>Last Name</th><th>Gender</th><th>Hire Date</th></tr></thead>';
             echo '<tbody>';
                
             foreach ($employee as $emp) {
                 echo '<tr>';
                 echo '<td>' . htmlspecialchars($emp['emp_no']) . '</td>';
                 echo '<td>' . htmlspecialchars($emp['first_name']) . '</td>';
                 echo '<td>' . htmlspecialchars($emp['last_name']) . '</td>';
                 echo '<td>' . htmlspecialchars($emp['gender']) . '</td>';
                 echo '<td>' . htmlspecialchars($emp['hire_date']) . '</td>';
                 echo '</tr>';
             }
             echo '</tbody></table>';
             echo '</div>';
                
             // Show departments
             echo '<div class="info-box">';
             echo '<h2>🏬 Departments</h2>';
             $stmt = $pdo->query("SELECT dept_no, dept_name FROM department ORDER BY dept_name");
             $departments = $stmt->fetchAll();
                
             echo '<table>';
             echo '<thead><tr><th>Department Code</th><th>Department Name</th></tr></thead>';
             echo '<tbody>';
                
             foreach ($departments as $dept) {
                 echo '<tr>';
                 echo '<td>' . htmlspecialchars($dept['dept_no']) . '</td>';
                 echo '<td>' . htmlspecialchars($dept['dept_name']) . '</td>';
                 echo '</tr>';
             }
             echo '</tbody></table>';
             echo '</div>';
                
         } catch (PDOException $e) {
             echo '<div class="info-box error">';
             echo '<h2>❌ Database Connection Error</h2>';
             echo '<p>Error: ' . htmlspecialchars($e->getMessage()) . '</p>';
             echo '</div>';
         }
         ?>
    
         <div class="info-box">
             <h2>🏗️ Multi-VM Architecture</h2>
             <p><strong>Database VM (vm-01):</strong> MySQL Server with Employee Database</p>
             <p><strong>Web VM (vm-02):</strong> Apache + PHP Web Application</p>
             <p><strong>Data Source:</strong> MySQL Sample Employee Database</p>
             <p><strong>Records:</strong> 300,000+ employee, 400,000+ salary records</p>
         </div>
     </body>
     </html>
     EOF
    
  3. Definir permisos adecuados
     sudo chown apache:apache /var/www/html/employee.php
    
  4. Actualice la línea define('DB_SERVER', '$VM01_IP'); cambiando el valor de $VM01_IP con el valor de dirección IP guardado
     sudo vi /var/www/html/employee.php
    

    Salida de ejemplo:

    ``texto … código antes de definir('DB_SERVER', '$VM01_IP'); … código después de definir('DB_SERVER', '192.168.122.???');

  5. Salir de la VM del servidor web
     exit
    

Paso 12: Acceder a la aplicación para empleados

  1. Si se cierra el túnel SSH, cree para la prueba básica
     ssh -L 8081:$VM02_IP:80 opc@<YOUR ol-node-01 PUBLIC_IP>
    
  2. Demostración de la base de datos de empleados para:
     http://localhost:8081/employee.php
    

Resultados Esperados:


Aplicaciones disponibles:

🔧 Prueba básica de LAMP (http://localhost:8081/dbtest.php)

🏢 Demostración de la base de datos del empleado (http://localhost:8081/employee.php)


Comandos de gestión esenciales

Gestión de VM

  1. Mostrar las máquinas virtuales en ejecución y su estado
     sudo virsh list
    
  2. Iniciar VM-01
     sudo virsh start vm-01
    
  3. Apagar VM-01
     sudo virsh shutdown vm-01
    
  4. Mostrar permisos de DHCP para máquinas virtuales en la red por defecto
     sudo virsh net-dhcp-leases --network default
    

Configuración para ejecutar este laboratorio en Oracle Cloud Infrastructure

  1. Configuración de red virtual en la nube `` Navegar: redes → Redes virtuales en la nube → Iniciar asistente de VCN
    • Nombre: ol-vcn-01
    • Crear VCN Navegar: Redes → Redes virtuales en la nube → kvm-network → Listas de seguridad Agregar estas reglas de entrada:
    • SSH: origen 0.0.0.0/0, puerto TCP 22
    • HTTP: Origen 0.0.0.0/0, puerto TCP 80 ```
  2. Configuración de instancia informática:
         Navigation: Hamburger Menu → Compute → Instances → Create Instance
    
         Configuration:
         - Name: ol-node-01
         - Image: Oracle Linux 8 (Latest)
         - Shape: VM.Standard.E4.Flex (4 OCPUs, 16GB RAM)
         - Boot Volume: 100 GB
         - VCN: ol-vcn-01 
         - Subnet: Public subnet ol-vcn-01
         - Assign Public IP: Yes
         - Add SSH Key: Upload your public key
    
  3. Probar IP pública de Compute con SSH
     ssh opc@<ol-vcn-01_PUBLIC_IP>
    
  4. Continúe con el Paso 2: Validar el entorno soporta la virtualización

Pasos Siguientes

Aprenda a gestionar hosts y vms con Oracle Linux Virtual Manager (OLVM)

Más recursos de aprendizaje

Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en un explorador de Oracle Learning.

Para obtener documentación sobre el producto, visite Oracle Help Center.