Instalación de kubernetes k3s en Debian 12

kubernetes-k3s

¿Que es kubernetes k3s?

K3s es una distribución de Kubernetes de código abierto, que nos permite desplegar un clúster de Kubernetes ligero y certificado por CNCF (Cloud Native Computing Foundation) en cualquier máquina Linux.

Requisitos

  • Sistema Debian 12 actualizado.
  • Privilegios de root o sudo.
  • Acceso a internet.
  • tener instalado el paquete curl en todos los nodos.

Instalacion del nodo master

Para instalar k3s en el nodo master, ejecutamos el siguiente comando:

root@k3s-master:~# curl -sfL https://get.k3s.io | sh -

esta instalación nos agregará las siguientes utilidades en el nodo master:

  • kubectl: es una herramienta de línea de comandos que nos permite ejecutar comandos contra clústeres de Kubernetes.

  • crictl: es una herramienta de línea de comandos que nos permite depurar contenedores.

  • k3s-killall.sh: es un script que nos permite detener todos los procesos de k3s.

  • k3s-uninstall.sh: es un script que nos permite desinstalar k3s.

Para comprobar que k3s está en ejecución, utilizamos el siguiente comando:

root@k3s-master:~# systemctl status k3s

● k3s.service - Lightweight Kubernetes
     Loaded: loaded (/etc/systemd/system/k3s.service; enabled; preset: enabled)
     Active: active (running) since Sun 2023-11-12 17:50:35 CET; 52s ago
       Docs: https://k3s.io
    Process: 963 ExecStartPre=/bin/sh -xc ! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service (code=exited, status=0/SUCCE>
    Process: 965 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS)
    Process: 970 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
   Main PID: 971 (k3s-server)
      Tasks: 88
     Memory: 1.4G
        CPU: 32.333s
     CGroup: /system.slice/k3s.service
             ├─ 971 "/usr/local/bin/k3s server"
             ├─1030 "containerd "
             ├─1787 /var/lib/rancher/k3s/data/bf3548384eaabb3435bf08112f1b0cba1afc5add6a6f2f2372aa2906a598fd04/bin/containerd-shim-ru>
             ├─1825 /var/lib/rancher/k3s/data/bf3548384eaabb3435bf08112f1b0cba1afc5add6a6f2f2372aa2906a598fd04/bin/containerd-shim-ru>
             ├─1860 /var/lib/rancher/k3s/data/bf3548384eaabb3435bf08112f1b0cba1afc5add6a6f2f2372aa2906a598fd04/bin/containerd-shim-ru>
             ├─2780 /var/lib/rancher/k3s/data/bf3548384eaabb3435bf08112f1b0cba1afc5add6a6f2f2372aa2906a598fd04/bin/containerd-shim-ru>
             └─2863 /var/lib/rancher/k3s/data/bf3548384eaabb3435bf08112f1b0cba1afc5add6a6f2f2372aa2906a598fd04/bin/containerd-shim-ru>

Instalacion de los nodos worker

Para instalar k3s en los nodos worker, primero necesitamos obtener el token de conexión del nodo master, para ello consultamos el archivo /var/lib/rancher/k3s/server/node-token del nodo master, ejecutamos el siguiente comando:

root@k3s-master:~# cat /var/lib/rancher/k3s/server/node-token

Ahora en los nodos worker ejecutamos el siguiente comando:

root@k3s-worker1:~# curl -sfL https://get.k3s.io | K3S_URL="https://192.168.50.35:6443" K3S_TOKEN="K100e26cbb9f631b539d417c7c97b7f4ebdbabadf4b760284212ca379fdcb26de51::server:fb1f82eb62c88cddc79459de1b9501fc" sh -
  • K3S_URL: es la dirección del nodo master con el puerto 6443.

  • K3S_TOKEN: es el token de conexión del nodo master.

Comprobación del clúster

Para comprobar que los nodos se han instalado y unido correctamente al clúster, ejecutamos el siguiente comando en el nodo master:

root@k3s-master:~# kubectl get nodes

NAME          STATUS   ROLES                  AGE   VERSION
k3s-master    Ready    control-plane,master   23m   v1.27.7+k3s2
k3s-worker1   Ready    <none>                 12m   v1.27.7+k3s2
k3s-worker2   Ready    <none>                 67s   v1.27.7+k3s2
k3s-worker3   Ready    <none>                 44s   v1.27.7+k3s2

Despliegue de aplicación

Para comprobar que todos los nodos funcionan correctamente, vamos realizar un despliegue de nextcloud y mariadb, para ello utilizaremos los siguientes archivos de configuración:

Nota: Este despliegue es solo para comprobar que los pods se reparten entre los nodos, las réplicas de la aplicación serán diferentes debido a que no estamos montando los volumenes en un almacenamiento compartido y 2 de las 3 réplicas de mariadb fallarán poco después de su creación debido a que no están bien configuradas.

mariadb-configmap1.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: db-datos
data:
  db_user: nextclouduser
  db_dbname: dbnextcloud

mariadb-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc-mariadb
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi

mariadb-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mariadb-deployment
  labels:
    app: nextcloud
    type: database
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nextcloud
      type: database
  template:
    metadata:
      labels:
        app: nextcloud
        type: database
    spec:
      volumes:
        - name: vol-mariadb
          persistentVolumeClaim:
            claimName: pvc-mariadb
      containers:
        - name: contenedor-mariadb
          image: mariadb:10.5
          ports:
            - containerPort: 3306
              name: db-port
          volumeMounts:
            - mountPath: "/var/lib/mysql"
              name: vol-mariadb
          env:
            - name: MYSQL_USER
              valueFrom:
                configMapKeyRef:
                  name: db-datos
                  key: db_user
            - name: MYSQL_DATABASE
              valueFrom:
                configMapKeyRef:
                  name: db-datos
                  key: db_dbname
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-passwords
                  key: db_password
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-passwords
                  key: db_rootpassword

mariadb-srv.yaml

apiVersion: v1
kind: Service
metadata:
  name: nextcloud-service
  labels:
    app: nextcloud
    type: frontend
spec:
  selector:
    app: nextcloud
    type: frontend
  ports:
  - name: http-sv-port
    port: 80
    targetPort: http-port
  - name: https-sv-port
    port: 443
    targetPort: https-port
  type: NodePort

nextcloud-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc-nextcloud
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi

nextcloud-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextcloud-deployment
  labels:
    app: nextcloud
    type: frontend
spec:
  replicas: 6
  selector:
    matchLabels:
      app: nextcloud
      type: frontend
  template:
    metadata:
      labels:
        app: nextcloud
        type: frontend
    spec:
      volumes:
        - name: vol-nextcloud
          persistentVolumeClaim:
            claimName: pvc-nextcloud
      containers:
        - name: contenedor-nextcloud
          image: nextcloud
          ports:
            - containerPort: 80
              name: http-port
            - containerPort: 443
              name: https-port
          volumeMounts:
            - mountPath: "/var/www/html"
              name: vol-nextcloud
          env:
            - name: MYSQL_HOST
              value: mariadb-service
            - name: MYSQL_USER
              valueFrom:
                configMapKeyRef:
                  name: db-datos
                  key: db_user
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-passwords
                  key: db_password
            - name: MYSQL_DATABASE
              valueFrom:
                configMapKeyRef:
                  name: db-datos
                  key: db_dbname

nextcloud-srv.yaml

apiVersion: v1
kind: Service
metadata:
  name: nextcloud-service
  labels:
    app: nextcloud
    type: frontend
spec:
  selector:
    app: nextcloud
    type: frontend
  ports:
  - name: http-sv-port
    port: 80
    targetPort: http-port
  - name: https-sv-port
    port: 443
    targetPort: https-port
  type: NodePort

Para realizar el despliegue de la aplicacion primero creamos los secrets para la base de datos, ejecutamos el siguiente comando

usuario@minikube:~$ kubectl create secret generic db-passwords --from-literal=db_password=nextcloudpass --from-literal=db_rootpassword=rootpass

Realizamos el despliegue de los ficheros con la herramienta kubectl

usuario@minikube:~$ kubectl apply -f .

Comprobamos que los pods se han creado correctamente, ejecutamos el siguiente comando

root@k3s-master:~# kubectl get pod,pv,service -o wide

NAME                                        READY   STATUS    RESTARTS      AGE   IP          NODE          NOMINATED NODE   READINESS GATES
pod/mariadb-deployment-58c84db4ff-mdgq6     1/1     Running   0             68s   10.42.3.8   k3s-worker3   <none>           <none>
pod/nextcloud-deployment-85d9d97959-7qnkd   1/1     Running   0             68s   10.42.2.9   k3s-worker2   <none>           <none>
pod/nextcloud-deployment-85d9d97959-7shvt   1/1     Running   0             68s   10.42.2.5   k3s-worker2   <none>           <none>
pod/nextcloud-deployment-85d9d97959-rlm75   1/1     Running   0             68s   10.42.2.6   k3s-worker2   <none>           <none>
pod/nextcloud-deployment-85d9d97959-v4rbj   1/1     Running   0             68s   10.42.2.7   k3s-worker2   <none>           <none>
pod/nextcloud-deployment-85d9d97959-xc4f6   1/1     Running   0             68s   10.42.2.8   k3s-worker2   <none>           <none>
pod/nextcloud-deployment-85d9d97959-llrqf   1/1     Running   0             68s   10.42.2.4   k3s-worker2   <none>           <none>
pod/mariadb-deployment-58c84db4ff-8vxrs     1/1     Running   2 (32s ago)   68s   10.42.3.7   k3s-worker3   <none>           <none>
pod/mariadb-deployment-58c84db4ff-jvnrh     1/1     Running   2 (32s ago)   68s   10.42.3.9   k3s-worker3   <none>           <none>

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                   STORAGECLASS   REASON   AGE   VOLUMEMODE
persistentvolume/pvc-a7bb2a95-3c34-4bc3-9ef7-a19325d04486   4Gi        RWO            Delete           Bound    default/pvc-mariadb     local-path              66s   Filesystem
persistentvolume/pvc-9a4e3a98-8579-4c8d-a13d-7f59952d256f   4Gi        RWO            Delete           Bound    default/pvc-nextcloud   local-path              62s   Filesystem

NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
service/kubernetes          ClusterIP   10.43.0.1       <none>        443/TCP                      80m   <none>
service/nextcloud-service   NodePort    10.43.232.230   <none>        80:30070/TCP,443:32600/TCP   68s   app=nextcloud,type=frontend

Como podemos ver, los pods se han creado correctamente y se han repartido entre los nodos.

Para eliminar el despliegue completo de la aplicación, podemos ejecutar el siguiente comando:

usuario@minikube:~$ kubectl delete -f .

y para eliminar el secret que hemos creado, utilizamos el siguiente comando:

usuario@minikube:~$ kubectl delete secret db-passwords

Con esto ya tendriamos en funcionamiento nuestro cluster de kubernetes (k3s) en Debian 12.