Saltar a contenido

MicroK8s

MicroK8s es una distribución ligera de Kubernetes desarrollada por Canonical (la empresa detrás de Ubuntu), diseñada para ser fácil de instalar, mantener y ejecutar en:

  • Desarrolladores locales (portátiles o sobremesa)
  • Sistemas edge o embebidos
  • Entornos de pruebas
  • Entornos de producción pequeños o medianos

Introducción

image.png

MicroK8s - Zero-ops Kubernetes for developers, edge and IoT

MicroK8s - MicroK8s documentation - home

Características

Característica Detalle
🧩 Instalación sencilla Un solo comando: sudo snap install microk8s --classic
📦 Todo en uno Incluye kubectl, containerd, kubelet, kube-apiserver, etc.
🚀 Autoconfigurado No necesitas configurar certificados, flannel, DNS, etc.
🔌 Addons activables Como ingress, dns, helm, prometheus, istio, etc.
🧱 Soporte de clúster Puedes unir varios nodos y crear un clúster HA
📉 Bajo consumo de recursos Ideal para dispositivos edge (Raspberry Pi, Intel NUC, etc.)
✅ Certificado CNCF Es una distribución Kubernetes 100% certificada

Manifiesto

image.png

Un manifiesto en Kubernetes es simplemente otra forma de llamar a un archivo declarativo YAML que describe la configuración de un recurso en el clúster.

En otras palabras:
👉 "manifiesto" = archivo YAML que define un recurso de Kubernetes

Se le dice manifiesto porque "declara" de manera formal el estado deseado de un recurso dentro de Kubernetes. Es como una "declaración oficial" de cómo debe ser un Deployment, un Pod, un Service, etc.

Elementos

Un manifiesto en Kubernetes siempre tendrá al menos estas secciones:

  1. apiVersion: La versión de la API de Kubernetes que se usará.

  2. kind: El tipo de recurso que quieres crear (Pod, Deployment, Service, etc.).

  3. metadata: Información como el nombre del recurso y etiquetas.

  4. spec: La especificación detallada de cómo debe comportarse ese recurso.


📝 Ejemplo de un manifiesto

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80

Este sería un manifiesto de Pod que puedes aplicar en Kubernetes.

Contenido

Un YAML de Kubernetes describe recursos como:

  • Pods
  • Deployments
  • Services
  • ConfigMaps
  • Secrets
  • Ingress, etc.

Puedes tener múltiples manifiestos en un solo archivo YAML, separados con ---, alternativamente puedes tener un manifiesto por archivo si prefieres mantener todo modular.

Aplicación de un manifiesto

kubectl apply -f mi-fichero.yaml

Kubernetes toma este manifiesto y se asegura de crear el recurso exactamente como lo describes. si el recurso ya está creado, Kubernetes lee el archivo, compara el estado deseado con el estado actual y concilia la diferencia para que tu aplicación quede como tú la definiste en el YAML.

POD

image.png

Un Pod en Kubernetes es la unidad más pequeña de despliegue y ejecución dentro del clúster. Un pod encapsula uno o más contenedores que comparten el mismo entorno de red, almacenamiento y configuración.

Características principales de un pod:

  1. Uno o varios contenedores: Aunque lo más común es que un pod contenga un solo contenedor, puede tener varios (por ejemplo, un contenedor principal y un "sidecar" para tareas auxiliares).
  2. Red compartida: Todos los contenedores dentro del pod comparten la misma dirección IP, el mismo puerto de red y las mismas interfaces de red.
  3. Volúmenes compartidos: Los contenedores dentro del pod pueden compartir volúmenes para intercambiar datos entre ellos.
  4. Ciclo de vida conjunto: Los contenedores dentro de un pod siempre se ejecutan juntos en el mismo nodo y se gestionan como una unidad. Si el pod muere, todos los contenedores dentro de él también se detienen.

📝 Manifiesto de Pod:

vi myapp.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: httpd:latest
    ports:
    - containerPort: 80

🔧 Comandos para PODs

# despliegue del Pod
kubectl apply -f myapp.yaml

# Eliminar el Pod
kubectl delete -f myapp.yaml

# Devuelve el listado de pods
kubectl get pods

# Describe un pod
kubectl describe pod <name>

# Devuelve el consumo de recursos de un nodo
kubectl top pod <name> 

# Ejecutar un comando sobre un contenedor
kubectl exec <pod> -c <contenedor> <comando>

# Copia un fichero en un contenedor
kubectl cp /tmp/foo <pod-name>:/tmp/bar -c <container-name>

# Consulta de los de un contenedor
kubectl logs <pod-name> -c <container-name>

# Port forwarding
kubectl port-forward --address 0.0.0.0 pod/<pod-name> <host-port>:<pod-port>

Namespace

image.png

Los namespaces en Kubernetes son una forma de aislar y organizar recursos dentro de un mismo clúster.

Piensa en ellos como "espacios de trabajo" o "compartimentos" virtuales donde puedes tener recursos que no interfieren entre sí, aunque tengan el mismo nombre.

Utilidad

  1. Separar entornos: Puedes tener un namespace para desarrollo, otro para testing y otro para producción dentro del mismo clúster.
  2. Evitar conflictos de nombres: Puedes tener un Deployment llamado web-app en dos namespaces diferentes sin que choquen entre ellos.
  3. Aplicar políticas y límites:

    • Puedes aplicar quotas de recursos por namespace (CPU, memoria).
    • Puedes definir reglas de seguridad o control de acceso (RBAC) por namespace.
    • Facilitar la administración: En clústeres grandes, los namespaces ayudan a que los equipos trabajen de manera aislada y organizada.

Namespaces por defecto

  • default: Namespace por defecto donde se crean los recursos si no especificas otro.
  • kube-system: Recursos internos del sistema de Kubernetes (DNS, kube-proxy, etc.).
  • kube-public: Datos accesibles de forma pública dentro del clúster (rara vez se usa directamente).
  • kube-node-lease: Namespace para gestionar heartbeats de los nodos (para detectar si un nodo está vivo).

🔧 Comandos para trabajar con Namespaces:

# Devuelve el listado de namespaces
kubectl get namespaces

# Crea un namespace
kubectl create namespace <nombre>

# Especifical el namespace en el cliente kubectl
kubectl apply -f pod.yaml --namespace=<nombre>

# Establecer un determinado namespace como predeterminado
kubectl config set-context --current -–namespace=<nombre>

Definir un namespace dentro de un YAML

metadata:
  name: myapp
  namespace: desarrollo

Service

image.png

Un Service en Kubernetes es un recurso que proporciona una abstracción para exponer y acceder a un conjunto de pods de manera estable y confiable. Los pods son efímeros y sus IPs pueden cambiar, por lo que un Service actúa como un punto fijo de entrada que redirige el tráfico a los pods correctos, incluso si estos son recreados o se mueven a otro nodo.

Funciones principales de un servicio:

  1. Descubrimiento y balanceo de carga:

    • Distribuye automáticamente el tráfico entre los pods que coincidan con el selector definido.
    • Dirección IP estable:

    • Mientras que los pods tienen IPs dinámicas, el Service proporciona una IP virtual estable (ClusterIP) o un nombre DNS interno.

    • Exposición de la aplicación:

    • Puede exponer una aplicación internamente dentro del clúster o externamente hacia internet.

Tipos de servicios en Kubernetes:

  1. ClusterIP (por defecto):

    • Expone el servicio internamente dentro del clúster. No es accesible desde fuera.
    • NodePort:

    • Abre un puerto en cada nodo del clúster y redirige el tráfico a los pods.

    • LoadBalancer:

    • Crea un balanceador de carga externo (si el clúster está en una nube como AWS, GCP, Azure) y lo conecta al servicio.

    • ExternalName:

    • No redirige tráfico, pero mapea un nombre DNS interno a un nombre DNS externo.

📝 Manifiesto de "Service" tipo NodePort

---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Funcionamiento

  • El selector app: myapp hace que este Service envíe tráfico a todos los pods que tengan la etiqueta app=myapp.
  • El puerto 80 del Service se mapea al puerto 80 del pod (targetPort).

🔧 Comandos

# Aplica el manifiesto o los cambios
kubectl apply -f myapp.yaml

# Elimina el manifiesto 
kubectl delete -f myapp.yaml

# Comprueba
kubectl get all

NAME        READY   STATUS    RESTARTS   AGE
pod/myapp   1/1     Running   0          15m

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        44h
service/service1     NodePort    10.96.146.193   <none>        80:31926/TCP   15m

Deploymentimage.png

Un deployment en Kubernetes es un recurso que gestiona y mantiene el ciclo de vida de un conjunto de réplicas de un pod de manera declarativa. Es uno de los objetos más utilizados en Kubernetes, ya que te permite:

  1. Desplegar una aplicación: Define qué imagen de contenedor se debe usar, cuántas réplicas deben ejecutarse y cómo deben exponerse.
  2. Actualizar la aplicación sin tiempo de inactividad: Permite hacer rolling updates (actualizaciones progresivas) de los pods, minimizando la posibilidad de interrupciones.
  3. Gestionar el estado deseado: Kubernetes se asegura de que siempre haya el número de réplicas especificadas corriendo; si un pod falla, automáticamente se crea uno nuevo.
  4. Rollback: Puedes revertir a una versión anterior si una actualización falla.

📝 Manifiesto de "Deployment"

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp-container
          image: httpd:latest
          ports:
            - containerPort: 80

✅ Conceptos clave:

  • replicas: número de instancias de un pod.
  • selector: cómo Kubernetes identifica los pods que pertenecen a este deployment.
  • template: especifica la plantilla de los pods (contenedores, puertos, variables de entorno, etc.).
  • strategy: (opcional) puedes definir estrategias de despliegue como RollingUpdate o Recreate.

🔧 Comandos para deployments

# Aplica el manifiesto o los cambios
kubectl apply -f myapp.yaml

# Elimina el manifiesto 
kubectl delete -f myapp.yaml

# Comprueba deployments
kubectl get deployments

# Escala el despliegue
kubectl scale --replicas 2 deployment/myapp

Despliegue

image.png

Kubernetes de alta disponibilidad, con gestión de operaciones totalmente automatizada y sin interrupciones, desde estaciones de trabajo de desarrolladores hasta producción.

Entorno

  -----------+-----------------------------+-----------------------------+------------
             |                             |                             |
       192.168.1.251                 192.168.1.252                192.168.1.253
  +----------+------------+    +-----------+------------+   +------------+------------+
  | [k8s1.cluster.local]  |    |  [k8s2.cluster.local]  |   |  [k8s3.cluster.local]   |
  |     Control Plane     |    |      Worker Node       |   |      Worker Node        | 
  +------------------ ----+    +------------------------+   +-------------------------+

3 x servidores ubuntu 26.04

El dominio estándar en Kubernetes es <em>cluster.local</em>. Funciona bien en la mayoría de los casos y es importante para la resolución de nombres entre servicios.

Adicionalmente puedes añadir al fichero de resolución local de cada host /etc/hosts las siguientes lineas:

192.168.1.251   k8s1.cluster.local   k8s1
192.168.1.252   k8s2.cluster.local   k8s2
192.168.1.253   k8s3.cluster.local   k8s3

Instalación

MicroK8s instalará un Kubernetes minimalista y ligero que podrás ejecutar y usar en prácticamente cualquier máquina. Se instala en un instante:

# Instala la versión mas reciente estable de  Microk8s
sudo snap install microk8s --classic

# Evita auto-actualizaciones de Microk8s
sudo snap refresh --hold microk8s

MicroK8s crea un grupo para permitir el uso sin problemas de comandos que requieren privilegios de administrador. Para agregar su usuario actual al grupo y obtener acceso al directorio de caché .kube, ejecute los siguientes comandos:

sudo usermod -a -G microk8s $USER
mkdir -p ~/.kube
chmod 0700 ~/.kube
# Volver a ingresar a la sesión para que se aplique
su - $USER

Comandos

# Comprobar estado
microk8s status --wait-ready

# Ver nodos
microk8s kubectl get nodes

# Ver servicios
microk8s kubectl get services

Para usar solo el comando kubectl añadir al fichero ~/.bash_aliases la linea

echo "alias kubectl='microk8s kubectl'" >> ~/.bash_aliases && source ~/.bash_aliases

Clúster

Añadir nodos

Para crear un clúster a partir de dos o más instancias de MicroK8s en ejecución, utilice el comando microk8s add-node. La instancia de MicroK8s en la que se ejecuta este comando será un nodo master alojará el "control plane" de Kubernetes:

microk8s add-node

El comando devolverá algunas instrucciones de unión que deben ejecutarse en la instancia de MicroK8s que desea unir al clúster:

microk8s join 192.168.1.230:25000/92b2db237428470dc4fcfc4ebbd9dc81/2c0cb3284b05

Eliminar nodos

# En el nodo a eliminar
microk8s leave

# En el nodo master
microk8s remove-node <IP_nodo_a_eliminar>

Addons

image.png

MicroK8s utiliza el mínimo de componentes para un Kubernetes puro y ligero. Sin embargo, hay muchas funciones adicionales disponibles  "addons" que son componentes preconfigurados que proporcionarán capacidades adicionales.

MicroK8s - MicroK8s Addons

Puedes consultar la lista de complementos disponibles e instalados en cualquier momento ejecutando:

microk8s status

El complemento «hostpath-storage» proporciona espacio de directorio en el host. No se usa en cluster

Dashboard

image.png

El repositorio oficial fue movido a **`kubernetes-retired/dashboard`** y está **archivado (read-only) desde el 21 de enero de 2026**, indicando explícitamente que **no se mantiene** y recomendando [**Headlamp**](https://bookstack.ictiberia.com/books/ubuntu/page/headlamp "Headlamp") como alternativa.

Ingress

image.png

Este complemento añade un controlador de entrada NGINX para MicroK8. Se habilita ejecutando el comando:

microk8s enable ingress

Con Ingress habilitado, se puede crear una regla de tipo "ingress" HTTP/HTTPS. por ejemplo:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: http-ingress
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: some-service
            port:
              number: 80

Cert-Manager

image.png

Cert-Manager es la solución estándar para la gestión de certificados en clústeres de Kubernetes. Se habilita ejecutando el comando:

microk8s enable cert-manager

ClusterIssuer

Se utiliza un recurso ClusterIssuer para configurar una cuenta con Let's Encrypt. Solo necesita una dirección de correo electrónico (asegúrese de usar una válida).Global -> para todo el clúster

  • Se aplica una sola vez y puedes usarlo en cualquier namespace.
  • Ideal para producción cuando quieres certificados automáticos a nivel de clúster.

Manifiesto "letsencrypt-staging*.yaml*"

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # The ACME server URL
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: user@example.com
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-staging
    # Enable the HTTP-01 challenge provider
    solvers:
      - http01:
          ingress:
            class: public

Manifiesto "letsencrypt-prod*.yaml*":

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: user@example.com
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-prod
    # Enable the HTTP-01 challenge provider
    solvers:
      - http01:
          ingress:
            class: public
# ClusterIssuer test
kubectl apply -f letsencrypt-staging.yaml

# ClusterIssuer Producción
kubectl apply -f letsencrypt-prod.yaml

Comprobación

# Lista ClusterIssuers
kubectl get clusterissuer

# Obtener detalles del ClusterIssuer
kubectl describe clusterissuer letsencrypt-staging
kubectl describe clusterissuer letsencrypt-prod

Persistent Volumes

image.pngSi se utiliza el almacenamiento simple proporcionado por el complemento de almacenamiento hostpath, hay que tener en cuenta que solo estará disponible para los nodos en los que se haya habilitado. Para el almacenamiento en clúster, se debe configurar un almacenamiento alternativo.

NFS

image.png

CSI driver para NFS

En la práctica debes instalar `nfs-common` en **todos los nodos worker/control-plane donde puedan ejecutarse pods que monten PVCs NFS**.

# instala nfs-common en todos los nodos del cluster
sudo apt update
sudo apt install -y nfs-common

# comprueba cambiando la IP del NFS server
which mount.nfs
showmount -e 10.0.0.42 

Habilite el complemento Helm3 (si aún no está habilitado) y agregue el repositorio para el controlador NFS CSI:

microk8s enable helm3
microk8s helm3 repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
microk8s helm3 repo update

Instalar el driver de Helm en el espacio de nombres kube-system:

microk8s helm3 install csi-driver-nfs csi-driver-nfs/csi-driver-nfs \
    --namespace kube-system \
    --set kubeletDir=/var/snap/microk8s/common/var/lib/kubelet

En este punto, se pueden listar los controladores CSI disponibles en el clúster de Kubernetes.

microk8s kubectl get csidrivers

NAME             ATTACHREQUIRED   PODINFOONMOUNT   STORAGECAPACITY   TOKENREQUESTS   REQUIRESREPUBLISH   MODES        AGE
nfs.csi.k8s.io   false            false            false    

StorageClass para NFS

Crear una clase de almacenamiento de Kubernetes que utilice el controlador CSI nfs.csi.k8s.io. Suponiendo que haya configurado un recurso compartido NFS /volume1/k8s y que la dirección de su servidor NFS sea 10.0.0.42

# sc-nfs.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
  server: 10.0.0.42
  share: /volume1/k8s
  subDir: "${pvc.metadata.namespace}/${pvc.metadata.name}"
  onDelete: retain
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: Immediate
mountOptions:
  - hard
  - nfsvers=4.0

Cada PVC queda ordenado por namespace y nombre dentro del NFS. El CSI NFS soporta sustitución con `${pvc.metadata.name}`, `${pvc.metadata.namespace}` y `${pv.metadata.name}`

# aplica el maniefiesto creado 
kubectl apply -f sc-nfs.yaml

# Comprueba
kubectl get storageclass

NAME      PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-csi   nfs.csi.k8s.io   Retain          Immediate           true                   17s

PersistentVolumeClaim

El último paso consiste en crear un nuevo PersistentVolumeClaim utilizando la clase de almacenamiento nfs-csi. Esto es tan sencillo como especificar storageClassName: nfs-csi en la definición del PVC.

# pvc-nfs.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  storageClassName: nfs-csi
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 5Gi
# aplica el maniefiesto creado 
kubectl apply -f pvc-nfs.yaml

# Comprueba
kubectl describe pvc my-pvc

Headlamp

image.png

Headlamp es una interfaz de usuario de Kubernetes fácil de usar centrada en la extensibilidad

# 1) Añadir repo Helm de Headlamp
microk8s helm3 repo add headlamp https://kubernetes-sigs.github.io/headlamp/
microk8s helm3 repo update

# 2) Instalar en kube-system (o crea un namespace propio si prefieres)
microk8s helm3 install headlamp headlamp/headlamp -n kube-system

Acceso rápido (sin Ingress): port-forward

microk8s kubectl -n kube-system get svc | grep headlamp
microk8s kubectl -n kube-system port-forward svc/headlamp 8080:80 --address 0.0.0.0

Abres http://<IP-del-nodo>:8080.

Inicio de sesión

Headlamp permite login con bearer token (ServiceAccount) o con certificado cliente; lo habitual es token + RBAC.

Service Account token
#Create a Service Account:
kubectl -n kube-system create serviceaccount headlamp-admin

# Give admin rights to the account
kubectl create clusterrolebinding headlamp-admin \
--serviceaccount=kube-system:headlamp-admin \
--clusterrole=cluster-admin

# Create the token
kubectl create token headlamp-admin -n kube-system

Argo CD

**Argo CD** es una popular h**erramienta declarativa de entrega continua (Continuous Delivery / CD) diseñada específicamente para Kubernetes**, la cual opera bajo el enfoque **GitOps**. Actúa como el puente automatizado entre tu repositorio de código y tu infraestructura.
¿Cómo funciona?
- **Git como fuente de la verdad:** Toda la configuración y los manifiestos de tus aplicaciones (archivos YAML, Helm charts, Kustomize) se almacenan en un repositorio Git. - **Monitoreo continuo:** Argo CD se instala como un controlador dentro de tu clúster de Kubernetes y supervisa constantemente el estado actual de tus aplicaciones. - **Sincronización:** Compara el estado real de los pods y servicios en tu clúster con el estado deseado definido en Git. Si detecta una diferencia, puede alertarte o sincronizar automáticamente los cambios para que tu clúster coincida exactamente con lo que está en tu repositorio.
Beneficios principales
- **Despliegues automatizados:** Olvídate de ejecutar comandos manuales como `kubectl apply`. Los despliegues ocurren de forma automática cuando subes cambios a Git. - **Trazabilidad y auditoría:** Cada cambio realizado queda registrado en el historial de Git, sabiendo exactamente qué versión está desplegada y quién la modificó. - **Interfaz visual:** Incluye un dashboard web que te permite ver el estado de tus aplicaciones y la topología de tu infraestructura en tiempo real. - **Recuperación ante desastres:** Si un contenedor se elimina accidentalmente o falla, Argo CD lo detecta y lo restaura al estado deseado.

Instalación

kubectl create namespace argocd

kubectl apply -n argocd --server-side --force-conflicts \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

kubectl -n argocd get pods -o wide
kubectl -n argocd rollout status deploy/argocd-server

Instalar Argo CD CLI

VERSION=$(curl -L -s https://raw.githubusercontent.com/argoproj/argo-cd/stable/VERSION)

curl -sSL -o argocd-linux-amd64 \
  "https://github.com/argoproj/argo-cd/releases/download/v${VERSION}/argocd-linux-amd64"

sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm argocd-linux-amd64

argocd version --client

En microk8s puede aparecer el error: `"invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable"`. Significa que el binario `argocd` no está encontrando configuración de Kubernetes. Es típico en MicroK8s cuando `kubectl` funciona porque es alias/wrapper de `microk8s kubectl`, pero no existe un `~/.kube/config` estándar para otras herramientas.

Para corregirlo:

echo 'export KUBECONFIG=/var/snap/microk8s/current/credentials/client.config' >> ~/.bashrc
source ~/.bashrc
Iniciar sesión mediante la CLI
La contraseña inicial para la cuenta de administrador se genera automáticamente y se almacena como texto sin cifrar en el campo contraseña, en un secreto llamado argocd-initial-admin-secret en el espacio de nombres de instalación de Argo CD.
argocd admin initial-password -n argocd

Una vez que haya cambiado la contraseña, debe eliminar el secreto argocd-initial-admin-secret del espacio de nombres de Argo CD. Este secreto solo sirve para almacenar la contraseña generada inicialmente en texto plano y puede eliminarse sin problemas en cualquier momento.

Acceder a la UI de Argo CD

Mediante port-forward

kubectl -n argocd port-forward svc/argocd-server 8080:443 --address 0.0.0.0 &

k9s

image.png

https://k9scli.io/

  • K9s es una herramienta de línea de comandos interactiva para Kubernetes.
  • Te permite navegar, monitorizar y gestionar clústeres de K8s desde la terminal.

Características

  1. Navegación rápida

    • Pulsa : y escribe recursos (pods, deployments, svc, ingress, etc.) y navega entre ellos.
    • Usa arrow keys para moverte, enter para abrir detalles de un pod o contenedor.
    • Logs en tiempo real

    • Selecciona un pod y pulsa l para ver logs.

    • Puedes seguir logs de todos los contenedores de un pod o filtrarlos.
    • Acciones sobre pods y recursos

    • Reiniciar (r), borrar (d), escalar (s) deployments directamente desde la UI de terminal.

    • Filtrado y búsqueda

    • Ctrl+f para buscar pods por nombre, label o status.

    • Filtrar por namespace: :ns <nombre_namespace>.
    • Soporte multi-clúster

    • Detecta todos los contextos de tu kubeconfig.

    • Cambia rápidamente de un clúster a otro (:ctx <context>).
    • Temas y colores

    • Muestra pods en verde/amarillo/rojo según estado, con alertas visuales.

    • Personalizable mediante config file.

Ventajas

  • Muy rápido, todo en terminal.
  • Ideal para operaciones de emergencia sin abrir UI web.
  • Compatible con cualquier clúster K8s (MicroK8s, k3s, EKS, AKS, GKE…).
  • Ligero, no necesita navegador ni plugins externos.

Instalación

Windows

1️⃣ Instalar

Usando un terminal en modo administrador de PowerShell

# Install chocolatey
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

# instala via chocolatey
choco install k9s

# Ejecuta k9s
k9s

2️⃣ Exportar kubeconfig de MicroK8s

MicroK8s guarda su configuración dentro del nodo Linux. Necesitas copiarla a Windows.

En el nodo <span class="hljs-comment">MicroK8s</span>

sudo microk8s config 

Esto imprime el contenido del kubeconfig.

  • Copia todo el contenido a un archivo microk8s-config.yaml en tu máquina Windows, por ejemplo:
C:\Users\<usuario>\.kube\config-microk8s.yaml
3️⃣ Conectar K9s al clúster MicroK8s
1. En Windows, define la variable de entorno `KUBECONFIG` apuntando al archivo que creaste:
setx KUBECONFIG "C:\Users\<usuario>\.kube\config-microk8s.yaml"

No olvides especificar tu usuario y cierra y abre PowerShell de nuevo para que se aplique.

2. Abre K9s:

k9s

Comandos básicos

Tecla / ComandoAcción
:nsListar y cambiar namespaces
:ctxListar y cambiar contextos de kubeconfig
:pods o :poListar todos los pods del namespace activo
:deployments o :deployListar deployments
:svcListar servicios
:ing o :ingressListar ingress
lVer logs del pod seleccionado
sAbrir shell en el pod seleccionado
dEliminar recurso seleccionado
rReiniciar pod o deployment seleccionado
ctrl+aMostrar todos los recursos en el namespace
/Filtrar la lista actual por nombre o label
0-9Navegar entre columnas en algunas vistas (logs, métricas)
qSalir de K9s o cerrar panel
:Abrir barra de comandos (para escribir recursos o cambiar namespace/context)
?Ayuda rápida dentro de K9s

How to install a Windows 11 VM using LXD | Ubuntu

IA

Conceptos

image.png

La IA (Inteligencia Artificial) es una rama de la informática que busca crear máquinas o programas capaces de realizar tareas que normalmente requieren inteligencia humana.

Estas tareas incluyen cosas como:

  • Reconocimiento de voz o imágenes (por ejemplo, cuando tu teléfono entiende lo que dices).
  • Toma de decisiones (como los sistemas que recomiendan películas o rutas de viaje).
  • Aprendizaje automático (machine learning), donde las máquinas aprenden de los datos sin ser programadas explícitamente para cada tarea.
  • Procesamiento del lenguaje natural, que permite a los sistemas entender y responder en lenguaje humano (como yo 😊).

En resumen, la IA trata de imitar la forma en que las personas piensan, aprenden y resuelven problemas, pero usando algoritmos y datos.

Arquitectura

              ┌───────────────────────────────────────────────────────────────┐
              │                        USUARIO                                │
              │───────────────────────────────────────────────────────────────│
              │  💬 Usa navegador web (Chrome, Firefox, etc.)                 │
              │  🌐 Accede a http://tu-servidor:3000                          │
              └───────────────┬───────────────────────────────────────────────┘
                              │ 1️⃣ Escribe / envía prompt
                              ▼
        ┌──────────────────────────────────────────────────────────────────────┐
        │                      🖥️  Open WebUI (contenedor Docker)              │
        │──────────────────────────────────────────────────────────────────────│
        │ - Interfaz tipo ChatGPT                                              │
        │ - Guarda historiales de chat (persistencia)                          │
        │ - Tiene “Knowledge Base” (memoria larga / aprendizaje)               │
        │ - Llama al modelo LLM a través de API local                          │
        └───────────────┬──────────────────────────────────────────────────────┘
                        │ 2️⃣ Envía prompt al motor de IA local (Ollama)
                        ▼
        ┌──────────────────────────────────────────────────────────────────────┐
        │                 🧠 Ollama (host, fuera del contenedor)               │
        │──────────────────────────────────────────────────────────────────────│
        │ - Maneja modelos LLM (Llama 3, Mistral, Phi-3, etc.)                 │
        │ - Usa GPU vía CUDA para acelerar inferencia                          │
        │ - Expone API local http://localhost:11434                            │
        │ - Compatible con múltiples modelos y embeddings                      │
        └───────────────┬──────────────────────────────────────────────────────┘
                        │ 3️⃣ Llama a la GPU para procesar el modelo
                        ▼
        ┌──────────────────────────────────────────────────────────────────────┐
        │             ⚙️ NVIDIA Container Toolkit + Drivers CUDA               │
        │──────────────────────────────────────────────────────────────────────│
        │ - “Puentea” la GPU física hacia los contenedores                     │
        │ - Permite ejecutar CUDA/Tensor ops dentro de Docker                  │
        │ - Asegura compatibilidad entre driver y librerías del contenedor     │
        └───────────────┬──────────────────────────────────────────────────────┘
                        │ 4️⃣ Acceso a la GPU física
                        ▼
        ┌──────────────────────────────────────────────────────────────────────┐
        │                 💻 GPU Física (RTX, CUDA cores, VRAM)                │
        │──────────────────────────────────────────────────────────────────────│
        │ - Ejecuta el modelo LLM en paralelo masivo                           │
        │ - Usa librerías CUDA/cuDNN/TensorRT instaladas en Ubuntu             │
        │ - Devuelve resultados procesados a Ollama                            │
        └──────────────────────────────────────────────────────────────────────┘

Modelos

image.png

Un modelo de inteligencia artificial es un programa entrenado para aprender patrones a partir de datos (como texto, imágenes o sonidos), y luego usar esos patrones para hacer tareas “inteligentes”, por ejemplo:

  • Entender preguntas
  • Escribir texto
  • Traducir
  • Reconocer imágenes o voz

🔹 Un modelo de IA aprende de muchos ejemplos y luego predice o genera cosas nuevas que tienen sentido.

🔹Un modelo de IA es un sistema entrenado para hacer una tarea específica.

🔹 Cada tipo de modelo de IA se especializa en un tipo de información.
🔹 Algunos (como los multimodales) combinan varios tipos a la vez.
🔹 Los modelos de lenguaje grandes (LLMs) son los más usados hoy por su versatilidad (chat, análisis, generación, etc.).


Tipos

image.png

Los tipos de modelos se diferencian por el tipo de datos que usan (texto, imagen, sonido, etc.) y lo que saben hacer (predecir, clasificar, generar, etc.).

| Tipo de modelo | Qué hace | Ejemplos | | --- | --- | --- | | **1. Modelos de lenguaje (LLMs)** | Entienden y generan texto, mantienen conversaciones, escriben, traducen. | ChatGPT, Llama 3, Mistral, Gemini, Claude | | **2. Modelos de visión** | Reconocen y analizan imágenes o videos. | YOLO, CLIP, ResNet, OpenCV, SAM (Segment Anything) | | **3. Modelos de voz y audio** | Reconocen voz o generan audio y música. | Whisper (transcripción), TTS (Text-to-Speech), MusicGen | | **4. Modelos multimodales** | Combinan texto, imágenes, audio o video para razonar con varios tipos de datos a la vez. | GPT-4o, Gemini 1.5, Claude 3.5, Kosmos-2 | | **5. Modelos de recomendación** | Predicen qué te gustará (productos, películas, música). | Netflix, Amazon, TikTok, Spotify | | **6. Modelos predictivos / analíticos** | Detectan patrones y hacen pronósticos basados en datos numéricos. | Modelos de predicción de ventas, clima, finanzas | | **7. Modelos generativos** | Crean contenido nuevo: texto, imágenes, código, video o música. | DALL·E, Stable Diffusion, Midjourney, Code Llama | | **8. Modelos de refuerzo (Reinforcement Learning)** | Aprenden a tomar decisiones por ensayo y error. | AlphaGo, agentes de videojuegos, robots autónomos | | **9. Modelos de embeddings / vectoriales** | Representan texto o imágenes como números para comparar similitud. | OpenAI Embeddings, Nomic, Sentence Transformers |

Modelos populares por tipo

| Área | Modelos conocidos | | --- | --- | | Texto / conversación | ChatGPT, Claude, Llama, Mistral, Phi | | Imagen | Stable Diffusion, Midjourney, DALL·E, CLIP | | Audio / voz | Whisper, Bark, MusicGen | | Multimodal (todo en uno) | GPT-4o, Gemini 1.5, Claude 3.5, Kosmos | | Código / programación | Code Llama, StarCoder, DeepSeek Coder | | Recomendaciones | Matrix Factorization, Transformers, DeepFM |

Terminología

Parámetros

Son las “conexiones internas” del cerebro del modelo. Cada parámetro guarda un número que el modelo ajustó mientras aprendía. Un modelo tiene capas de redes neuronales con miles de millones de parámetros (sus “neuronas”). Durante el entrenamiento, el modelo ajusta esos parámetros para aprender relaciones entre los datos.

  • El número define el tamaño: Un modelo de 8B (como Llama 3.1) tiene 8.000 millones de parámetros.
  • Regla física: A más parámetros, la IA es más inteligente, pero requiere más memoria VRAM en GPU para funcionar.

Por ejemplo:

  • llama3.1:70b tiene 70 mil millones de parámetros.(ocupa decenas de GB).
  • Esos son los “pesos” de una red neuronal, como las sinapsis de un cerebro.
  • Cuantos más parámetros, más conocimiento y más capacidad de razonamiento.

🔹 “B” = *billones de parámetros* 🔹 Más parámetros = más inteligencia, más tamaño, más consumo 🔹 “70B” = modelo muy grande, con calidad similar a ChatGPT avanzado

Tokens

Los tokens son las unidades de texto que el modelo procesa o genera. No son palabras exactamente, sino pedacitos de palabras.

Los tokens son las piezas del texto que entran o salen del modelo cuando conversas.

Cuando tú hablas con él, el modelo usa lo que aprendió para procesar tus tokens (las partes de texto que le mandas) y generar una respuesta.

Cuantización (Quantization)
Es la técnica de **compresión** que permite que un modelo gigante quepa en tu servidor. Los pesos originales son números matemáticos de alta precisión muy pesados (16 bits / FP16). La cuantización los reduce (por ejemplo, a 4 bits / Q4).
  • El beneficio: Reduce el peso del modelo a la cuarta parte (de 32 GB a solo 8 GB de VRAM) perdiendo menos del 1% de inteligencia. Es lo que permite que tu GPU L4 rinda al máximo.
Ventana de Contexto (Context Window)
Es la **memoria a corto plazo** de la IA en un chat. Define cuántos tokens (texto) puede recordar el modelo entre tu pregunta, sus respuestas anteriores y las instrucciones del sistema en una misma sesión.
  • Los modelos modernos tienen ventanas enormes (ej. Llama 3.1 soporta 128.000 tokens).
  • Impacto: Aunque el modelo soporte mucho, a mayor contexto usado por un usuario, más VRAM consume.
Temperatura (Temperature)
Es el parámetro que controla la **creatividad o aleatoriedad** de las respuestas del modelo. Se mide en una escala de 0.0 a 1.0 (o a veces hasta 2.0):
  • Temperatura baja (0.0 - 0.2): Respuestas lógicas, precisas y repetitivas. Ideal para programación, matemáticas o análisis de datos.
  • Temperatura alta (0.7 - 1.0): Respuestas creativas, variadas y fluidas. Ideal para lluvia de ideas o redacción de textos.
Prompt del Sistema (System Prompt)
Es la **personalización o rol inicial** que le das a la IA antes de que el usuario empiece a hablar. Define las reglas de comportamiento, el tono y las restricciones del modelo (por ejemplo: *"Eres un profesor de química estricto que solo responde en español"*). El usuario no lo ve directamente, pero el modelo lo obedece durante todo el chat.

Resumen
| Término | Qué significa | Ejemplo | | --- | --- | --- | | **Modelo de IA** | Un cerebro artificial entrenado para hacer una tarea. | ChatGPT, Llama, Mistral | | **Entrenamiento** | El proceso donde aprende de muchos datos. | Leer millones de textos | | **Parámetros** | Las conexiones o “neuronas” que guardan lo aprendido. | 70 B en Llama 3 – 70B | | **Tokens** | Las piezas de texto que el modelo lee o genera. | “Hola mundo” → 3 tokens |

Ollama

image.png

Ollama es una herramienta y plataforma diseñada para ejecutar modelos de lenguaje grandes (LLMs) de manera local en tu computadora, sin depender de servidores en la nube.

En términos simples, es una forma de usar modelos tipo ChatGPT o LLaMA directamente en tu máquina.

  • Permite descargar y correr modelos de IA (como LLaMA 2, Mistral, Gemma, Phi-3, etc.) en tu propio equipo.
  • Proporciona una interfaz de línea de comandos (CLI) y una API local, con la que puedes integrar los modelos en tus propias aplicaciones.
  • Se encarga de gestionar la descarga, ejecución y optimización del modelo, para que no tengas que configurar manualmente entornos complejos.

Enlaces

Características

  • Ejecución local: todos los cálculos se hacen en tu computadora (no se envían datos a la nube).
  • Compatibilidad multiplataforma: disponible para macOS, Windows y Linux.
  • Modelos variados: soporta modelos de código abierto como LLaMA 2, Mistral, Gemma, Phi-3, Command-R, entre otros.
  • Integración sencilla: se puede usar desde terminal o con peticiones HTTP a http://localhost:11434.
  • Privacidad y control: ideal si quieres mantener tus datos en local o experimentar con IA sin depender de OpenAI, Anthropic, etc.

Requisitos

Instalación

Baremetal

curl -fsSL https://ollama.com/install.sh | sh

# Arranca el servicio (si no arrancó solo):
sudo systemctl enable --now ollama

Docker

Creando el directorio para los servicios

mkdir -p ~/projects/ollama
cd ~/projects/ollama
# guarda aquí el compose.yaml

compose.yaml

services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama:/root/.ollama
    environment:
      - OLLAMA_NUM_PARALLEL=4      # Permite procesar hasta 4 peticiones simultáneas en la GPU L4
      - OLLAMA_MAX_LOADED_MODELS=1 # Mantiene un solo modelo en VRAM para evitar saturación
    restart: unless-stopped
    #  ===== Recursos y GPU NVIDIA ===== (requiere nvidia-container-toolkit en el host)
    deploy:
      resources:
        reservations:
          devices:
          - driver: nvidia
            capabilities: ["gpu"]
            count: all
        limits: #  Control de recursos para Ollama 
          cpus: '10.0'       # Máximo 10 cores lógicos simultáneos
          memory: 24gb       # Espacio de sobra para Llama 3.1 8B y picos de contexto
    # =========================== 
volumes:
  ollama:

CLI

# Arranca el stack
sudo docker compose up -d
# Comprueba los logs de ollama
sudo docker logs -n 200 -f ollama
# apaga el stack
sudo docker compose down
# Conectar al shell del contenedor ollama
sudo docker exec -it ollama bash
# Lista los modelos instalados
ollama list
# Descarga un modelo sin ejecutarlo
ollama pull phi3
# Muestra información de un modelo
ollama show llama3.1
# ejecuta un modelo
ollama run llama3.1
# Elimina un modelo
ollama rm mistral

Open WebUI

image.png

🏡 Home | Open WebUI

Open WebUI (antes conocida como Ollama WebUI) es una interfaz gráfica web de código abierto que te permite usar modelos de lenguaje locales (como los de Ollama, LM Studio, o incluso GPTs remotos) desde una experiencia parecida a ChatGPT — pero en tu propia computadora o servidor, sin depender de la nube.

En pocas palabras:

Convierte Ollama en un ChatGPT local.

Con Open WebUI, obtienes una interfaz moderna (accesible desde tu navegador) donde puedes:

  • Chatear con modelos locales como Mistral, LLaMA 3, Phi-3, etc.
  • Crear y guardar “personas” o prompts personalizados (como GPTs locales).
  • Subir archivos y pedirle al modelo que los analice.
  • Administrar varios modelos desde un mismo panel.
  • Integrar extensiones o conectarlo con APIs externas.

Open WebUI corre dentro de Docker y usa Ollama o PyTorch como backend IA.

Funciones

Función Descripción
💬 Chat multihilo Guarda y organiza tus conversaciones.
🧠 Compatibilidad con Ollama Usa modelos locales fácilmente.
🌍 Integración con OpenAI y otros backends También puede conectarse a GPT-4, Claude, etc.
🧩 Soporte para plugins y herramientas Puedes ampliar sus funciones (por ejemplo, para buscar en la web o ejecutar código).
📄 Análisis de archivos Puedes subir PDFs, TXT o CSV y hacerle preguntas al modelo.
🛡️ Privacidad total Todos los datos se quedan en tu equipo si solo usas Ollama.

Instalar

Después de instalar Ollama, puedes desplegar Open WebUI como contenedor docker ampliando el fichero compose.yaml con el contenido:

---
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    deploy:
      resources:
        limits:
          cpus: '2.0'        # La interfaz web es ligera, 2 cores bastan
          memory: 2gb
    volumes:
      - open_webui:/app/backend/data
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
      - WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY}
      - ENABLE_SIGNUP=false
      - DEFAULT_USER_ROLE=user
      # ===== CONFIGURACIÓN DE BÚSQUEDA WEB AUTOMÁTICA =====
      - ENABLE_RAG_WEB_SEARCH=True       # Activa la búsqueda web de forma global al iniciar
      - RAG_WEB_SEARCH_ENGINE=ddgs       # Selecciona DuckDuckGo (Gratis y sin requerir APIs externas)
      - WEB_SEARCH_CONCURRENT_REQUESTS=1 # Crítico multiusuario: Encola las búsquedas para evitar bloqueos por IP
    depends_on:
      - ollama
    restart: unless-stopped
    networks:
      - default
      - proxy 

volumes:
  open_webui:  

networks:
  default:
  proxy:
    external: true

Comandos:

# Arranca el stack
sudo docker compose up -d
# Comprueba los logs de open-webui
sudo docker logs -n 200 -f open-webui
# apaga el stack
sudo docker compose down

Ahora ya puedes acceder a Open WebUI en http://IP-Host:8080

Personalización

Entra ID

🌍 Microsoft Environment Variable Configuration | Open WebUI

🌍 Cómo registrar una aplicación en Entra ID de Microsoft - Microsoft identity platform | Microsoft Learn

Añade a docker-compose.yaml en la sección de variables:

      # SSO Microsoft Entra ID (OIDC)
      - ENABLE_OAUTH_SIGNUP=true
      - MICROSOFT_CLIENT_ID=${CLIENT_ID}
      - MICROSOFT_CLIENT_SECRET=${CLIENT_SECRET}
      - MICROSOFT_CLIENT_TENANT_ID=${TENANT_ID}
      - MICROSOFT_OAUTH_SCOPE=openid email profile
      - MICROSOFT_REDIRECT_URI=https://${FQDN}/oauth/microsoft/callback
      - OPENID_PROVIDER_URL=https://login.microsoftonline.com/${TENANT_ID}/v2.0/.well-known/openid-configuration

fichero .env

FQDN="ia.dominio.com"
TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
CLIENT_SECRET=xxxxx~xxxxxxxxxxxxxxxxxxxxxxxxxx