Kubernetes,  QNAP

kubernetes. k0s – MinIO, guardando objetos en el cluster

MinIO es un servidor de almacenamiento en la nube compatible con Amazon S3, liberado bajo Licencia Apache v2. Como almacén de objetos, MinIO puede almacenar datos desestructurados como fotos, vídeos, archivos de registro, copias de seguridad e imágenes de contenedor. Esto es lo que dice la Wikipedia, pero vamos, que sirve para guardar archivos junto con información relativa a éstos (metadatos). No voy a entrar en detalles, siendo lo más me interesa la total integración de MinIO en Kubernetes.

Al lío! Lo primero que quiero indicar es que esta, es una instalación de prueba, con un único servidor y que no es aconsejable usar en un entorno productivo. Sí que sirve, para evaluar su funcionamiento y si hace lo que necesitamos, se debe realizar una instalación con todos sus componentes.

Os describo ciertos elementos que son necesarios para que se levante correctamente el POD/Server. Por un lado, los comandos que levantan el servicio y por otro las variables necesarias. De los comandos, es importante en que puerto levantamos la consola de administración, en mi caso en el 9090. De las variables; las dos primeras son necesarias para que funcione bien la consola y las otras dos están claras.

  - args:
    - minio server /data --console-address ":9090"
    command:
    - /bin/bash
    - -c
    env:
    - name: MINIO_BROWSER_REDIRECT_URL
      value: "https://minio.tufqdn.com/console"
    - name: MINIO_SERVER_URL
      value: "https://minio.tufqdn.com"
    - name: MINIO_ROOT_USER
      value: "minioadmin"
    - name: MINIO_ROOT_PASSWORD
      value: "miniopasswd"

Para el almacenamiento, simplemente (como hago habitualmente) monto un volumen nfs desde el NAS y así obtengo la persistencia necesaria. En este recurso nfs se guarda tanto la configuración como el dato. En la image se puede ver un Bucket (el contenedor de objetos) con nombre hass y un directorio oculto con la configuración.

El Deployment completo sería tal que así.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: minio
  name: minio
  namespace: minio
spec:
  replicas: 1
  selector:
    matchLabels:
      app: minio
  template:
    metadata:
      labels:
        app: minio
    spec:
      containers:
      - args:
        - minio server /data --console-address ":9090"
        command:
        - /bin/bash
        - -c
        env:
        - name: MINIO_BROWSER_REDIRECT_URL
          value: "https://minio.tufqdn.com/console"
        - name: MINIO_SERVER_URL
          value: "https://minio.tufqdn.com"
        - name: MINIO_ROOT_USER
          value: "minioadmin"
        - name: MINIO_ROOT_PASSWORD
          value: "miniopasswd"
        image: minio/minio:RELEASE.2024-01-18T22-51-28Z
        imagePullPolicy: Always
        name: minio
        volumeMounts:
        - mountPath: /data
          name: minio-storage
      volumes:
      - name: minio-storage
        nfs:
          path: /minio
          server: tuserver

Ya tenemos el Deploy, ahora tenemos que exponerlo con un par de servicios. El primero va a exponer la API de MinIO y el segundo la Consola.

apiVersion: v1
kind: Service
metadata:
  labels:
    app: minio
  name: minio-api
  namespace: minio
spec:
  ports:
  - port: 9000
    protocol: TCP
    targetPort: 9000
    name: minio-api
  selector:
    app: minio
  type: ClusterIP
  
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: minio
  name: minio-console
  namespace: minio
spec:
  ports:
  - port: 9090
    protocol: TCP
    targetPort: 9090
    name: minio-console
  selector:
    app: minio
  type: ClusterIP

Por último, es necesario exponer al mundo entero (si es lo que quieres, claro) los servicios anteriores con un par de Ingress. Están montados de manera que bajo un mismo registro DNS puedes acceder a la api, escribiendo minio.tufqdn.com, o la consola añadiendo un /console. Los Ingress y el propio MinIO están montados de manera que si en un navegador escribes minio.tufqdn.com se redirigen las peticiones a /console y si estás usando la API de queda en /.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-production
    nginx.ingress.kubernetes.io/rewrite-target: /$1
  name: minio-console
  namespace: minio
spec:
  rules:
    - host: minio.tufqdn.com
      http:
        paths:
        - path: /console/(.*)
          pathType: ImplementationSpecific
          backend:
            service:
              name: minio-console
              port:
                number: 9090
  tls:
    - hosts:
      - minio.tufqdn.com
      secretName: minio-cert
      
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-production
  name: minio-api
  namespace: minio
spec:
  rules:
    - host: minio.tufqdn.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: minio-api
              port:
                number: 9000
  tls:
    - hosts:
      - minio.tufqdn.com
      secretName: minio-cert

Una vez que levanta todo ya tienes disponible la API y la Consola. Recuerda que las credenciales las has establecido en una variable de entorno.

Simplemente y para finalizar es posible que te interese que existe una integración para HomeAssistant de MinIO, aunque esto ya será para otro día.

minio:
  host: minio.tufqdn.com
  port: 9000
  access_key: ACCESS_KEY
  secret_key: SECRET_KEY
  secure: false
  listen:
    - hass