Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell

Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 111dx

por Raúl Unzué

Kubernetes sobre Hyper-V 624m6g

v6o2y

La virtualización se ha convertido en un estándar en entornos empresariales, y Kubernetes es el orquestador por excelencia para gestionar contenedores a gran escala. Si combinas ambas tecnologías en una infraestructura de Hyper-V, puedes lograr un entorno flexible, escalable y altamente automatizado.

Pero ¿por qué hacerlo manualmente si podemos automatizarlo? PowerShell nos permite desplegar un clúster de Kubernetes en Hyper-V de forma rápida y eficiente, asegurando una configuración homogénea y minimizando errores humanos.

En esta guía, te mostraremos paso a paso cómo automatizar la creación de máquinas virtuales mediante una plantilla de Debian, la configuración de redes, la instalación de Kubernetes y la validación del clúster, todo a través de PowerShell. Además, incluiremos pruebas de conectividad y monitoreo para garantizar que todo funcione correctamente dentro de tu red LAN.

Al final de esta guía, tendrás un clúster de Kubernetes funcional en Hyper-V, listo para desplegar aplicaciones de manera eficiente y sin intervención manual.

Requisitos previos 53h5i

Antes de ejecutar el script del Powershell (si queréis saber como construir vuestro primer script, os dejamos una entrada), asegúrate de contar con lo siguiente:

  • Mínimo Windows Server 2022 o Windows 10/11 Pro/Enterprise con Hyper-V activado. Lo podéis instalar con el siguiente comando:
    • Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
  • Mínimo 16 GB de RAM.
  • Procesador con virtualización habilitada (VT-x o AMD-V).
  • PowerShell con permisos de .
  • En nuestro caso, usaremos una plantilla de Debian Cloud para generar todas las máquinas virtuales. 
  • a internet en la máquina host para descargar paquetes.
  • Instalar paquete en plantilla "hv_kvp":

sudo apt update && sudo apt install linux-cloud-tools-common linux-cloud-tools-generic linux-cloud-tools-$(uname -r)

sudo systemctl enable hv-kvp-daemon

sudo systemctl start hv-kvp-daemon

  • Para instalar "cloud-init", que es una herramienta utilizada para la configuración automática de instancias en la nube o máquinas virtuales en su primer arranque. Permite personalizar servidores con configuraciones específicas como s, claves SSH, paquetes, scripts de inicialización y más, sin intervención manual:

sudo apt update && sudo apt install -y cloud-init

Para sellar la máquina virtual utilizar el siguiente comando:

sudo cloud-init clean --logs

  • Instalar Kubernetes en plantilla Debian:

apt install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common

mkdir -p /etc/apt/keyrings

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo tee /etc/apt/keyrings/kubernetes-apt-keyring.asc > /dev/null

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.asc] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list

apt update

apt install -y kubelet kube kubectl

apt-mark hold kubelet kube kubectl

  • Paquete ADK instalado en el host de Hyper-V:

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 1

Crear una Plantilla de Debian en Hyper-V 2u576h

Si utilizamos una plantilla pre-creada de Debian en Hyper-V, podemos clonar y personalizar las máquinas virtuales en el momento del arranque usando PowerShell y Cloud-Init.

Esta estrategia optimiza el despliegue, ya que evita reinstalar el sistema operativo desde cero y permite modificar cada nodo (master o worker) en función de su rol.

Os explicamos como lo podemos hacer:

  1. Descargamos la imagen oficial de Debian Cloud (Qcow2 o Raw), lo podéis hacer vía comando o directamente con la URL:
    • wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2
  2. Convierte la imagen a formato VHDX (para Hyper-V) con qemu-img:
    • qemu-img convert -f qcow2 -O vhdx debian-12-genericcloud-amd64.qcow2 debian-template.vhdx
  3. Crea una VM en Hyper-V con el disco debian-template.vhdx y Cloud-Init activado.
  4. Configura SSH y Cloud-Init en la plantilla:
    • apt update && apt install -y cloud-init

      systemctl enable cloud-init

    • cloud-init clean
    • Crea el archivo /etc/cloud/cloud.cfg.d/99-hyperv.cfg y añade:

      datasource_list: [NoCloud, None]
  5. Apaga la máquina y conviértela en una plantilla de solo lectura:
    • Set-VM -Name "Debian-Template" -CheckpointType Disabled

Script Powershell para generar plantilla de VM en Hyper-V 5w1z6y

  • Opcionalmente, podéis usar un script de powershell para generarla una vez parametrizada:

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 2

PowerShell: Script para Crear la Infraestructura 4o4e1e

El siguiente script, automatiza la creación del clúster Kubernetes generando las máquinas virtuales (1 Master y 2 Workers), configurando redes y preparando los nodos para Kubernetes:

 

# ========================

# CONFIGURACIÓN DEL SCRIPT

# Definimos variables de configuración

# ========================

# Variables de configuración

$VMSwitchName = "K8S-External-Network"

$VMPath = "D:\Hyper-V"

$CloudInitPath = "$VMPath\CloudInit"

$TemplateVHD = "$VMPath\Templates\debian-template.vhdx"

$OscdimgPath = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe"

# Validar si oscdimg.exe existe

if (!(Test-Path $OscdimgPath)) {

    Write-Host "Error: oscdimg.exe no encontrado en $OscdimgPath. Instala el Windows ADK."

    exit

}

# Crear directorio de Cloud-Init si no existe

if (!(Test-Path $CloudInitPath)) {

    Write-Host "Creando directorio de Cloud-Init..."

    New-Item -ItemType Directory -Path $CloudInitPath | Out-Null

}

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 3

# ========================

# SOLICITAR DATOS AL

# Pide un y contraseña para las VMs

# ========================

$name = Read-Host "Introduce el nombre de para los nodos"

$ = Read-Host "Introduce la contraseña para los nodos" -AsSecureString

$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($)

$Plain = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

# Generar clave SSH si no existe

$SSHKeyPath = "$env:PROFILE\.ssh\id_rsa"

if (!(Test-Path $SSHKeyPath)) {

    Write-Host "Generando clave SSH..."

    ssh-keygen -t rsa -b 4096 -N "" -f $SSHKeyPath

}

$SSHKeyPub = Get-Content "$SSHKeyPath.pub"

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 4

# ========================

# CREAR SWITCH VIRTUAL EXTERNO SI NO EXISTE

# Creamos la red para nuestras VMs

# ========================

if (!(Get-VMSwitch -Name $VMSwitchName -ErrorAction SilentlyContinue)) {

    $NetAdapter = (Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | Select-Object -ExpandProperty Name -First 1)

    if ($NetAdapter) {

        Write-Host "Creando switch virtual externo: $VMSwitchName en $NetAdapter"

        New-VMSwitch -Name $VMSwitchName -NetAdapterName $NetAdapter -AllowManagementOS $true

    } else {

        Write-Host "Error: No se encontró un adaptador de red activo."

        exit

    }

}

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 5

# ========================

# CREAR LAS VMs Y CONFIGURAR CLOUD-INIT

# Definimos las características de las VMs y los ficheros para Cloud-Init

# ========================

$VMs = @(

    @{ Name = "K8S-Master"; RAM = 4GB; U = 2; Role = "master"; IP = "192.168.2.120" },

    @{ Name = "K8S-Worker1"; RAM = 3GB; U = 2; Role = "worker"; IP = "192.168.2.121" },

    @{ Name = "K8S-Worker2"; RAM = 3GB; U = 2; Role = "worker"; IP = "192.168.2.122" }

)

foreach ($VM in $VMs) {

    $VHDPath = "$VMPath\$($VM.Name).vhdx"

    $CloudISO = "$CloudInitPath\$($VM.Name)-Config.iso"

    if (Get-VM -Name $VM.Name -ErrorAction SilentlyContinue) {

        Write-Host "La máquina virtual $($VM.Name) ya existe. Omitiendo..."

        continue

    }

    Write-Host "Creando VM: $($VM.Name)"

    Copy-Item -Path $TemplateVHD -Destination $VHDPath -Force

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 6

    # ========================

    # GENERAR ARCHIVOS DE CLOUD-INIT

    # ========================

    Write-Host "Generando archivos de Cloud-Init para $($VM.Name)..."

    # Meta-Data

    $MetaData = @"

instance-id: $($VM.Name)

local-hostname: $($VM.Name)

"@

    $MetaData | Set-Content -Path "$CloudInitPath\meta-data" -Encoding UTF8

    # -Data

    $Data = @"

#cloud-config

s:

  - default

  - name: ${name}

    sudo: ALL=(ALL) NOWD:ALL

    shell: /bin/bash

    ssh_authorized_keys:

      - ${SSHKeyPub}

    ssh_import_id:

      - gh:${name}

    lock_wd: false

    wd: "${Plain}"

    chwd: { expire: false }

    groups: sudo, s

    home: /home/${name}

chwd:

  list: |

    root:${Plain}

    ${name}:${Plain}

  expire: false

ssh_pwauth: true

disable_root: false

runcmd:

  - sudo apt-get update

  - sudo apt-get install -y qemu-guest-agent curl openssh-server net-tools

  - sudo systemctl enable --now qemu-guest-agent

  - sudo mkdir -p /home/${name}/.ssh

  - echo "${SSHKeyPub}" | sudo tee /home/${name}/.ssh/authorized_keys

  - sudo chown -R ${name}:${name} /home/${name}/.ssh

  - sudo chmod 700 /home/${name}/.ssh

  - sudo chmod 600 /home/${name}/.ssh/authorized_keys

  - echo "PermitRoot yes" | sudo tee -a /etc/ssh/sshd_config

  - echo "Authentication yes" | sudo tee -a /etc/ssh/sshd_config

  - echo "Allows ${name}" | sudo tee -a /etc/ssh/sshd_config

  - sudo systemctl restart sshd

  - sudo cloud-init clean

"@

    $Data | Set-Content -Path "$CloudInitPath\-data" -Encoding UTF8

    # Configuración de IP estática en la LAN

    $NetworkConfig = @"

version: 2

ethernets:

  eth0:

    addresses:

      - $($VM.IP)/24

    gateway4: 192.168.2.69

    nameservers:

      addresses:

        - 8.8.8.8

        - 1.1.1.1

"@

    $NetworkConfig | Set-Content -Path "$CloudInitPath\network-config" -Encoding UTF8

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 7

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 8

    # ========================

    # GENERAR ISO DE CLOUD-INIT

    # ========================

    Write-Host "Generando ISO de Cloud-Init para $($VM.Name)..."

    Start-Process -FilePath $OscdimgPath `

        -ArgumentList "-d -m `"$CloudInitPath`" `"$CloudISO`"" `

        -NoNewWindow -Wait

    if (!(Test-Path $CloudISO)) {

        Write-Host "ERROR: No se pudo generar el archivo Cloud-Init ISO en $CloudISO"

        exit

    }

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 9

    # ========================

    # CREAR VM

    # ========================

    New-VM -Name $VM.Name -MemoryStartupBytes $VM.RAM -Generation 2 `

           -VHDPath $VHDPath -SwitchName $VMSwitchName

    Set-VMProcessor -VMName $VM.Name -Count $VM.U

    Set-VMMemory -VMName $VM.Name -DynamicMemoryEnabled $true `

                 -MinimumBytes 512MB -MaximumBytes 8GB

    Add-VMDvdDrive -VMName $VM.Name

    Set-VMDvdDrive -VMName $VM.Name -Path $CloudISO

    # Configurar firmware

    Set-VMFirmware -VMName $VM.Name -EnableSecureBoot Off

    $HardDrive = Get-VMHardDiskDrive -VMName $VM.Name

    Set-VMFirmware -VMName $VM.Name -BootOrder $HardDrive

    # Iniciar VM

    Start-VM -Name $VM.Name

    Start-Sleep -Seconds 10

}

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 10

 

# ========================

# VALIDACIÓN DE RED

# Espera 60 segundos para obtener IP

# ========================

Write-Host "Esperando que las VMs obtengan IP..."

Start-Sleep -Seconds 60

Write-Host "Comprobando IPs de las VMs..."

foreach ($VM in $VMs) {

    $VMIP = (Get-VMNetworkAdapter -VMName $VM.Name).IPAddresses

    if ($VMIP) {

        Write-Host "$($VM.Name) tiene la IP: $VMIP"

    } else {

        Write-Host "ERROR: $($VM.Name) sigue sin IP."

    }

}

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 11

 

     # ========================

    # VALIDACIÓN DE CLOUD-INIT Y SSH

    # ========================

    Write-Host "Esperando que Cloud-Init termine en $($VM.Name)..."

    Start-Sleep -Seconds 120  # Espera inicial antes de validar

    

    Write-Host "Verificando conectividad con ${VM.IP}..."

    $pingTest = Test-Connection -ComputerName $VM.IP -Count 2 -Quiet

    if (-not $pingTest) {

        Write-Host "No se pudo hacer ping a ${VM.IP}. Revisa la configuración de red."

        continue

    }

    Write-Host "Intentando SSH a $($VM.Name) en ${VM.IP}..."

    for ($i=1; $i -le 5; $i++) {

        $SSHTest = ssh -o "StrictHostKeyChecking=no" -o "ConnectTimeout=5" "$name@${VM.IP}" "echo 'SSH funcionando'"

        if ($SSHTest -match "SSH funcionando") {

            Write-Host "SSH funcionando en $($VM.Name)."

            break

        } else {

            Write-Host "Intento $i No se pudo acceder por SSH a $($VM.Name). Reintentando..."

            Start-Sleep -Seconds 10

        }

    }

}

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 12

# ========================

# VALIDACIÓN DE CLUSTER KUBERNETES

# Validamos que el cluster Kubernetes está bien creado

# ========================

Write-Host "Validando el clúster Kubernetes..."

$MasterVM = "K8S-Master"

$K8SStatus = Invoke-Command -VMName $MasterVM -ScriptBlock {

    if (Test-Path "/etc/kubernetes/.conf") {

        $Status = kubectl get nodes --no-headers | ForEach-Object { $_ -match ' Ready ' }

        if ($Status) {

            return "OK"

        } else {

            return "ERROR"

        }

    } else {

        return "ERROR"

    }

}

if ($K8SStatus -eq "OK") {

    Write-Host "Kubernetes está funcionando correctamente en el nodo master."

} else {

    Write-Host "ERROR: Kubernetes no está correctamente configurado en el nodo master."

}

Write-Host "¡Clúster Kubernetes desplegado exitosamente!"

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 13

Ejecución Script Powershell 6n6v2u

Ejecuta PowerShell como y lanza el script de la siguiente forma:

Set-ExecutionPolicy By -Scope Process -Force

O lanzamos la aplicación Powershell_ISE o la consola de Powershell como :

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 14

Ejecutamos script, que irá haciendo varias validaciones:

.\Deploy-KubernetesCluster.ps1

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 15

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 16

Veremos como se van generando cada fichero de cloud-init:

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 17

Si todo ha ido correctamente, podréis ver las máquinas que irán arrancando una a una y el conmutador virtual creados:

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 18

Podremos acceder a cada máquina, ya sea vía SSH como vía consola:

Geeknetic Cómo Automatizar un Clúster de Kubernetes en Hyper-V con PowerShell 19

Y comprobar el estado de los nodos:

kubernetes@K8S-Master:~$ kubectl get node
 NAME STATUS ROLES AGE VERSION
 K8S-Master Ready master 6d v1.32.115
 K8S-Worker1 Ready 7m7s v1.32.115
 K8S-Worker2 Ready 6d v1.32.115

 

Conclusión: La automatización de procesos ahorra trabajo y fallos 2p722f

La automatización de procesos permite optimizar el tiempo y reducir la posibilidad de errores humanos. Al implementar soluciones automatizadas, se mejora la eficiencia, se minimizan fallos y se garantiza una mayor precisión en las tareas repetitivas. Esto no solo ahorra trabajo, sino que también facilita la gestión y el mantenimiento de sistemas complejos.

Fin del Artículo. ¡Cuéntanos algo en los Comentarios!

Temas Relacionados: Windows PowerShell Hyper-V Kubernetes
Redactor del Artículo: Raúl Unzué

Raúl Unzué 3e5u1i

Soy un apasionado de la virtualización con más de 20 años de experiencia, especializado en soluciones como VMware(premio vExpert y vExpert Pro desde 2013), Proxmox e Hyper-V. Durante mi carrera, he ayudado a empresas a optimizar sus infraestructuras TI mientras comparto mis conocimientos como redactor IT. Mi objetivo es traducir lo complejo en algo práctico y accesible, combinando teoría con experiencia real. Si te interesa la virtualización, las herramientas TI o simplemente aprender algo nuevo, espero ayudarte con mis artículos.