{"id":24047685,"url":"https://github.com/clhore/basickubernetescluster-wordpress","last_synced_at":"2026-04-09T08:02:29.539Z","repository":{"id":271580203,"uuid":"913906342","full_name":"clhore/BasicKubernetesCluster-Wordpress","owner":"clhore","description":"Creation of a Kubernetes cluster in an on-premise environment. Implementation of MetalLB as a load balancer and deployment of a WordPress application.","archived":false,"fork":false,"pushed_at":"2025-01-08T15:35:01.000Z","size":802,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-08T16:53:41.107Z","etag":null,"topics":["kubernetes","kubernetes-cluster","kubernetes-setup","metallb","mysql","ndb-cluster","nfs","nfs-server","wordpress","wordpress-kubernetes","wordpress-mysql"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clhore.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-08T15:23:43.000Z","updated_at":"2025-01-08T15:46:49.000Z","dependencies_parsed_at":"2025-01-08T17:05:52.465Z","dependency_job_id":null,"html_url":"https://github.com/clhore/BasicKubernetesCluster-Wordpress","commit_stats":null,"previous_names":["clhore/basickubernetescluster-wordpress"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clhore%2FBasicKubernetesCluster-Wordpress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clhore%2FBasicKubernetesCluster-Wordpress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clhore%2FBasicKubernetesCluster-Wordpress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clhore%2FBasicKubernetesCluster-Wordpress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clhore","download_url":"https://codeload.github.com/clhore/BasicKubernetesCluster-Wordpress/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240831076,"owners_count":19864709,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kubernetes","kubernetes-cluster","kubernetes-setup","metallb","mysql","ndb-cluster","nfs","nfs-server","wordpress","wordpress-kubernetes","wordpress-mysql"],"created_at":"2025-01-09T00:50:03.075Z","updated_at":"2025-10-17T16:06:53.135Z","avatar_url":"https://github.com/clhore.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"**Kubernetes Cluster - Kubernetes + MySQL + Wordpress**\n\nClúster Kubernetes en entorno on-premise y despliegue del aplicativo\nWordPress en alta disponibilidad. Servicios adicionales, MySQL NDB\nClúster, hipervisor Proxmox y servidor NFS.\n\n# Introduccion\n\nEn este documento se muestra el despliegue del aplicativo WordPress y\nlas implementaciones necesarias para desplegarlo en un clúster de\nKubernetes on-premise.\n\nA lo largo del documento se mostrarán la implementación de un clúster de\nKubernetes en un entorno on-premise, utilizando Proxmox hipervisor de\ntipo 1. A partir de este entorno, se han creado y configurado todos los\nnodos necesarios para conformar el clúster de Kubernetes, asegurando la\nescalabilidad y su óptimo funcionamiento. Implementando redundancia,\ntanto en los nodos master como en los worker.\n\nPara garantizar la alta disponibilidad de los datos, se ha implementado\nun clúster de base de datos MySQL NDB Cluster, permitiendo una\nreplicación distribuida y tolerancia a fallos. Además, se configuró un\nservidor NFS como solución de almacenamiento persistente, destinado a\nsoportar los recursos necesarios para los aplicativos desplegados en el\nclúster de Kubernetes.\n\nUso de VIPs (Virtual IPs and Service Proxies) implementación de MetalLB,\nofreciendo así una gestión eficiente del tráfico hacia las aplicaciones\nalojadas en el clúster de Kubernetes.\n\nFinalmente, se porcede al despliege del aplicativo WordPress en\nconfiguración de alta disponibilidad, utilizando todos los componentes\nantes mencionados para garantizar un servicio robusto y resiliente.\nAdicionalmente, se implementó la tecnología de Cloudflare Tunnel para\nexponer la aplicación de una forma segura y sencilla, ofreciendo una\ncapa adicional de protección y simplificando el acceso desde redes\nexternas.\n\n# Infraestructura\n\n## Hypervisor\n\nLa creación de los nodos que compondrán este proyecto, en mi caso serán\ncreados en el hypervisor Proxmox. En este caso yo cuento con un servidor\ndedicado donde se encuentra instalado Proxmox, se podría utilizar un\nhypervisor de tipo 2 como VirtualBox y crear todo el entorno en local.\n\n## Clúster Kubernetes\n\nSe crea un clúster con redundancia en los nodos master y worker\ngarantizando que si algún nodo falla los demás nodos puedan suplirlo. Se\ncontará con 2 nodos master y 3 worker.\n\nCon el fin de balancear la carga entre los distintos nodos y no requerir\nun Load Balancer externo al clúster de Kubernetes, haremos uso de\nMetalLB Load Balancer y VIPs (Virtual IPs and Service Proxies).\n\n![image](images/schema/scheme_cluster_kubernetes.png)\n![image](images/schema/schema_metallb_load_balancer.png)\n\n## MySQL NDB Cluster\n\nSe implementa un clúster de MySQL para alta disponibilidad. Esto nos\npermite externalizar la base de datos del clúster de Kubernetes y\nevitando que la caída del clúster afecte a la base de datos, además de\nevitarle esa carga al clúster.\n\nEn este caso contamos con una configuración básica de 4 nodos. Contando\ncon 1 nodo manager, 2 nodos de datos y 1 nodo SQL.\n\n-   **Nodo Manager**\\[srvdbm-mgm01\\] - Encargado de administrar el\n    clúster, tiene conectividad con todos los nodos del clúster.\n\n-   **Nodo Data**\\[srvdbm01-2\\] - Almacenan los datos creando réplicas\n    de los mismos para mantener la alta disponibilidad.\n\n-   **Nodo SQL**\\[srvdbm-sql01\\] - Nodo sobre el que se realizan las\n    querys SQL a la base de datos. Tiene conectividad con los nodos de\n    base de datos y con los nodos cliente como en este caso la red del\n    clúster de Kubernetes.\n\n![image](images/schema/schema_mysql_ndb_cluster.png)\n\n## Servidor NFS\n\nSe implementa un servidor NFS para almacenar los recursos persistentes\nde las implementaciones realizadas sobre el clúster de Kubernetes.\nEvitando perdida de información, facilitando el escalado del clúster a\nfuturo y centralizando el almacenamiento lo que nos facilitara la\nadministración de los recursos.\n\nEn caso de ser necesario una aplicación de memoria, está solo tendrá que\nllevarse a cabo sobre el servidor NFS.\n\n## Esquema\n\nEsquema general de la infraestructura a implementar, donde observamos la\nconectividad entre nodos.\n\n![image](images/schema/infraestructura_schema.png)\n\n# Implantación infraestructura\n\n## Clúster Kubernetes\n\nPara la creación del clúster, debemos empezar creando las VMs. Yo\nrealizaré la instalación sobre el sistema operativo Debian 12, con 4\nnúcleos y 4 GB de RAM, aunque sería recomendable ampliar hasta 8 GB esto\ndependerá de los aplicativos a desplegar.\n\nSe crearán 2 máquinas máster y 3 workers. Usaremos una red exclusiva\npara el clúster de Kubernetes, a fin de aislar el clúster del resto de\nnodos del sistema. Además se le otorgara IPs de dicha red al nodo SQL de\nla base de datos y al servidor NFS, ya que requieren ser accesibles por\nKubernetes.\n\nEmpezamos configurando la IP y el HostName de los nodos.\n\n![image](images/schema/network_172.31.0.0.png)\n\n                # hostnamectl set-hostname srvk8s-master01\n                # vi /etc/network/interfaces\n                # ifdown ens18; ifup ens18\n\n![image](images/install/set_network.png)\n\nEmpezamos con la instalación de Kubernetes, debemos instalar Kubernetes\nen los nodos master y worker. Posteriormente, se iniciará el clúster\ndesde el nodo master y se irán agregando al clúster.\n\nDeshabilitamos swap, ya que si no Kubernetes no nos dejara levantar el\nclúster.\n\n        root@srvk8s-master01:~# systemctl --type swap\n\n        UNIT                    LOAD   ACTIVE SUB    DESCRIPTION                            \n        *\\x2dvg\\x2dswap_1.swap loaded active active /dev/mapper/srvk8s--master01--vg-swap_1\n            \n        root@srvk8s-master01:~# systemctl mask dev-mapper-srvk8s\\x2d\\x2dmaster01\\x2d\\x2dvg\n        \\x2dswap_1.swap\n        root@srvk8s-master01:~# sed -i '/ swap / s/^\\(.*\\)$/#\\1/g' /etc/fstab\n        root@srvk8s-master01:~# reboot\n\nConfiguración he instalación de containerd.\n\n        root@srvk8s-master01:~# cat \u003c\u003cEOF | tee /etc/modules-load.d/containerd.conf \n        overlay \n        br_netfilter\n        EOF\n        \n        root@srvk8s-master01:~# modprobe overlay \u0026\u0026 modprobe br_netfilter\n        \n        root@srvk8s-master01:~# cat \u003c\u003cEOF | tee /etc/sysctl.d/99-kubernetes-k8s.conf\n        net.bridge.bridge-nf-call-iptables = 1\n        net.ipv4.ip_forward = 1 \n        net.bridge.bridge-nf-call-ip6tables = 1 \n        EOF\n\n        root@srvk8s-master01:~# apt-get update \u0026\u0026 apt-get install containerd -y\n        root@srvk8s-master01:~# containerd config default | tee /etc/containerd/config.tom\n        l \u003e/dev/null 2\u003e\u00261\n\nRevisamos que el SystemdCgroup tenga como valor true, si no lo\nmodificamos y reiniciamos containerd.\n\n        root@srvk8s-master01:~# grep SystemdCgroup /etc/containerd/config.toml\n            SystemdCgroup = true\n        root@srvk8s-master01:~# systemctl restart containerd \u0026\u0026 systemctl enable containerd\n\nInstalación de dependencias, la dependencia nfs-common es para que los\npods se puedan comunicar con el servidor NFS.\n\n        root@srvk8s-master01:~# apt-get install curl pgp -y\n\n        root@srvk8s-master01:~# echo \"deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg]\n        https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /\" | tee /etc/apt/sources.list.d/kubernetes.list\n\n        root@srvk8s-master01:~# curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | \n        gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg\n\n        root@srvk8s-master01:~# apt-get update \u0026\u0026 apt-get install kubelet kubeadm kubectl nfs-common -y \n        root@srvk8s-master01:~# apt-mark hold kubelet kubeadm kubectl\n\nCreamos el fichero de configuración del clúster par iniciarlo, este será\ncreado en el master 1, que será quien levante el clúster de Kubernetes.\n\n        root@srvk8s-master01:~# cat kubelet.yaml \n        apiVersion: kubeadm.k8s.io/v1beta3\n        kind: InitConfiguration\n        ---\n        apiVersion: kubeadm.k8s.io/v1beta3\n        kind: ClusterConfiguration\n        kubernetesVersion: \"1.30.0\"\n        controlPlaneEndpoint: \"srvk8s-master01\"\n        ---\n        apiVersion: kubelet.config.k8s.io/v1beta1\n        kind: KubeletConfiguration\n\nIniciamos el clúster, una vez iniciado podemos ir agregando los nodos al\nclúster.\n\n        root@srvk8s-master01:~# kubeadm init --config kubelet.yaml --upload-certs\n\nAgregar otro nodo master.\n\n        root@srvk8s-master02:~# kubeadm join srvk8s-master01:6443 --token \u003ctoken\u003e \\\n        --discovery-token-ca-cert-hash sha256:\u003ctoken\u003e \\\n        --control-plane --certificate-key \u003ctoken\u003e\n\nAgregar nodo worker.\n\n        root@srvk8s-worker01:~# kubeadm join srvk8s-master01:6443 --token \u003ctoken\u003e \\\n        --discovery-token-ca-cert-hash sha256:\u003ctoken\u003e \n\nRevisamos que los nodos se han agregado correctamente.\n\n![image](images/install/kubernetes_cluster_nodes.png)\n\nA modo aclaratibo indicaremos el rol de los nodos worker.\n\n        root@srvk8s-master01:~# kubectl \\\n        label node srvk8s-worker01 node-role.kubernetes.io/worker=\"\"\n        root@srvk8s-master01:~# kubectl \\\n        label node srvk8s-worker02 node-role.kubernetes.io/worker=\"\"\n        root@srvk8s-master01:~# kubectl \\\n        label node srvk8s-worker03 node-role.kubernetes.io/worker=\"\"\n        \n        root@srvk8s-master01:~# kubectl get nodes\n        NAME              STATUS   ROLES           AGE     VERSION\n        srvk8s-master01   Ready    control-plane   3d14h   v1.30.7\n        srvk8s-master02   Ready    control-plane   3d13h   v1.30.7\n        srvk8s-worker01   Ready    worker          3d13h   v1.30.7\n        srvk8s-worker02   Ready    worker          3d12h   v1.30.7\n        srvk8s-worker03   Ready    worker          39h     v1.30.7\n\n## MetalLB Load Balancer\n\nInstalamos MetalLB, una solución robusta para implementar un balanceador\nde carga dentro de nuestro clúster de Kubernetes. MetalLB nos permite\ngestionar el tráfico externo y enrutar las solicitudes hacia los Pods\nque ejecutan nuestras aplicaciones dentro del clúster.\n\nA través de MetalLB, los servicios expuestos en Kubernetes pueden\nutilizar una IP única para ser accesibles desde el exterior. Esto\nsimplifica el acceso a los servicios desplegados, garantizando una\ndistribución eficiente del tráfico hacia los Pods correspondientes y\nmejorando la experiencia del usuario.\n\nMetalLB se configura como un complemento de red para Kubernetes y es\nespecialmente útil en entornos on-premise o privados, donde no se\ndispone de balanceadores de carga nativos de proveedores de nube como\nAWS o GCP. Con MetalLB, combinamos flexibilidad, rendimiento y facilidad\nde configuración para gestionar el tráfico.\n\nHabilitar el modo ARP estricto.\n\n        root@srvk8s-worker01:~# kubectl edit configmap -n kube-system kube-proxy\n\n![image](images/install/strictARP_true.png)\n\nInstalamos MetalLB.\n\n        root@srvk8s-worker01:~# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml\n\nConfiguración, creamos el pool indicándole el rango de IPs.\n\n        root@srvk8s-master01:~$ cat metallb-ipadd-pool.yaml \n        apiVersion: metallb.io/v1beta1\n        kind: IPAddressPool\n        metadata:\n            name: first-pool\n            namespace: metallb-system\n        spec:\n            addresses:\n            - 172.31.0.100-172.31.0.110\n\n        root@srvk8s-master01:~$ cat metallb-pool-advertise.yaml \n        apiVersion: metallb.io/v1beta1\n        kind: L2Advertisement\n        metadata:\n            name: metallb-pool-advertise\n            namespace: metallb-system\n        spec:\n            ipAddressPools:\n            - first-pool\n\n        root@srvk8s-master01:~$ kubectl apply -f metallb-ipadd-pool.yaml\n        root@srvk8s-master01:~$ kubectl apply -f mmetallb-pool-advertise.yaml\n\n        # Observar que están activos los pods de MetalLB.\n        root@srvk8s-master01:~$ kubectl get pod -n metallb-system\n        NAME                          READY   STATUS    RESTARTS      AGE\n        controller-547c7bdf5c-5xntg   1/1     Running   2 (26h ago)   29h\n        speaker-6cv4q                 1/1     Running   2 (26h ago)   29h\n        speaker-gbnhx                 1/1     Running   4 (26h ago)   29h\n        speaker-lx6z8                 1/1     Running   2 (26h ago)   29h\n        speaker-st8mr                 1/1     Running   1 (26h ago)   29h\n        speaker-zb6rf                 1/1     Running   4 (26h ago)   29h\n\n## MySQL NDB Cluster\n\nSe instala y configura el clúster según la documentación oficial. Donde\ntenemos múltiples opciones, desde paquetes para Debian y RedHat, hasta\nla instalación manual de los binarios.\n\n::: center\n![image](images/install/network_10.0.0.0.png)\n:::\n\nComo se puede observar en la imagen el clúster se encuentra\ncorrectamente configurado.\n\n::: center\n![image](images/install/mysql_ndb_cluster_ndb_mgm.png)\n:::\n\nPara realizar querys sobre el clúster usaremos la dirección del nodo\nSQL/API 10.20.20.220 o desde el clúster de Kubernetes la dirección\n172.31.0.120.\n\n## Servidor NFS\n\nInstalamos un servidor NFS sobre un nodo. Posterior a la instalación\notorgamos permisos sobre un shared a los equipos de la red\n172.31.0.0/24, que es donde se encuentra en clúster de Kubernetes.\n\nInstallacion del servidor NFS sobre nodo Debian.\n\n        pv1@srv-nfs01:~$ sudo apt install nfs-kernel-server -y\n        pv1@srv-nfs01:~$ sudo systemctl start nfs-kernel-server\n        pv1@srv-nfs01:~$ sudo systemctl enable nfs-kernel-server\n\nCreamos el shared compartido y otorgamos permisos sobre él a los equipos\nde la red 172.31.0.0/24\n\n        pv1@srv-nfs01:~$ sudo mkdir -m 755 /mnt/shared/wordpress/\n        pv1@srv-nfs01:~$ sudo chown nobody:nogroup /mnt/shared/wordpress/\n        pv1@srv-nfs01:~$ cat /etc/exports\n        /mnt/shared/wordpress 172.31.0.0/24(rw,sync,no_subtree_check)\n        pv1@srv-nfs01:~$ sudo exportfs -a\n\nProbamos que tenemos acceso a él desde el clúster de Kubernetes.\n\n        root@srvk8s-master01:~# showmount -e 172.31.0.240\n        Export list for 172.31.0.240:\n        /mnt/shared/wordpress 172.31.0.0/24\n\n        root@srvk8s-master01:~# mkdir /mnt/shared\n        root@srvk8s-master01:~# sudo mount \\\n        -t nfs 172.31.0.240:/mnt/shared/wordpress /mnt/shared\n        root@srvk8s-master01:~# df -h /mnt/shared\n        S.ficheros                         Tamaño Usados  Disp Uso% Montado en\n        172.31.0.240:/mnt/shared/wordpress    48G   1,3G   44G   3% /mnt/shared\n\n## Wordpress\n\nAhora que contamos con todos los elementos necesarios para la\ninfraestructura, procedemos a desplegar el aplicativo WordPress en el\nclúster de Kubernetes.\n\n**Infraestructura Configurada:**\n\n-   Clúster de Kubernetes: Ya operativo y listo para manejar el\n    despliegue de aplicaciones.\n\n-   Base de Datos Externa: Un MySQL NDB Cluster configurado para\n    garantizar la alta disponibilidad y accesibilidad de los datos de\n    WordPress.\n\n-   Servidor NFS: Configurado en 172.31.0.240 para almacenar de manera\n    persistente los datos y archivos generados por WordPress.\n\n**Despliegue de WordPress**\n\nVamos a desplegar el aplicativo WordPress sobre el clúster de Kubernetes\nutilizando una configuración de 3 réplicas, asegurando así la alta\ndisponibilidad del servicio.\n\nCon esta configuración, cualquier interrupción en un nodo del clúster no\nafectará la disponibilidad del sitio web, ya que otras réplicas estarán\nlistas para asumir la carga.\n\nAdemás, los volúmenes persistentes almacenarán los datos en el servidor\nNFS, garantizando la consistencia de los archivos, independientemente de\nqué réplica esté sirviendo las solicitudes.\n\nDescargar e instalar Helm.\n\n        root@srvk8s-master01:~# curl https://raw.githubusercontent.com/helm/\n        helm/main/scripts/get-helm-3 | bash\n\nEl repositorio de Helm Charts oficial que contiene la imagen de\nWordPress se encuentra en Bitnami.\n\n        root@srvk8s-master01:~# helm repo add bitnami \\\n        https://charts.bitnami.com/bitnami\n        root@srvk8s-master01:~# helm repo update\n\nCreamos el usuario y la base de datos para el aplicativo WordPress.\n\n        [root@srvdbm-sql01 ~]# mysql -u root -p\n        \n        \u003e CREATE DATABASE wordpress;\n        \u003e CREATE USER 'wordpress'@'172.31.0.%' IDENTIFIED BY 'PASSWORD';\n        \u003e GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'172.31.0.%';\n        \u003e FLUSH PRIVILEGES;\n        \u003e SHOW GRANTS FOR 'wordpress'@'172.31.0.%';\n\nCreamos el deployment indicándole el aplicativo a implementar, el uso de\nLoadBalancer, la conexión con la base de datos y la creación del volumen\npersistente de WordPress que será almacenado en el shared.\n\n        root@srvk8s-master01:~# cat wordpress-nfs-deployment.yaml \n        # WordPress Service\n        ---\n        apiVersion: v1\n        kind: Service\n        metadata:\n          name: wordpress\n          labels:\n            app: wordpress\n        spec:\n          type: LoadBalancer\n          ports:\n            - port: 80\n              targetPort: 80\n          selector:\n            app: wordpress\n            tier: frontend\n        \n        # PersistentVolume for WordPress\n        ---\n        apiVersion: v1\n        kind: PersistentVolume\n        metadata:\n          name: wp-pv\n        spec:\n          storageClassName: manual\n          capacity:\n            storage: 1Gi\n          accessModes:\n            - ReadWriteMany\n          nfs:\n            path: /mnt/shared/wordpress\n            server: 172.31.0.240\n            readOnly: false\n        \n        # PersistentVolumeClaim for WordPress\n        ---\n        apiVersion: v1\n        kind: PersistentVolumeClaim\n        metadata:\n          name: wp-pvc\n        spec:\n          storageClassName: manual\n          accessModes:\n            - ReadWriteMany\n          resources:\n            requests:\n              storage: 1Gi\n        \n        # WordPress Deployment\n        ---\n        apiVersion: apps/v1\n        kind: Deployment\n        metadata:\n          name: wordpress\n          labels:\n            app: wordpress\n        spec:\n          replicas: 3\n          selector:\n            matchLabels:\n              app: wordpress\n              tier: frontend\n          template:\n            metadata:\n              labels:\n                app: wordpress\n                tier: frontend\n            spec:\n              containers:\n                - name: wordpress\n                  image: wordpress:latest\n                  env:\n                    - name: WORDPRESS_DB_HOST\n                      value: \"172.31.0.120:3306\"\n                    - name: WORDPRESS_DB_NAME\n                      value: \"wordpress\"\n                    - name: WORDPRESS_DB_USER\n                      value: \"wordpress\"\n                    - name: WORDPRESS_DB_PASSWORD\n                      value: \"\u003cPASSWORD_DB\u003e\"\n                  ports:\n                    - containerPort: 80\n                  volumeMounts:\n                    - name: wordpress-persistent-storage\n                      mountPath: /var/www/html\n              volumes:\n                - name: wordpress-persistent-storage\n                  persistentVolumeClaim:\n                    claimName: wp-pvc\n\nUna vez configurado el deployment wordpress-nfs-deployment.yaml con\ntodos los detalles de la implementación (como la configuración del\nservidor NFS, la conexión a la base de datos externa y las réplicas),\nprocedemos al despliege sobre el cluster.\n\n        root@srvk8s-master01:~# kubectl apply -f wordpress-nfs-deployment.yaml \n        service/wordpress created\n        persistentvolume/wp-pv created\n        persistentvolumeclaim/wp-pvc created\n        deployment.apps/wordpress created\n\nRevisamos que los pods del aplicativo se han ejecutado correctamente, en\ncaso de observar algún fallo podemos usar 'kubectl describe pod -l\napp=wordpress', para revisar.\n\n        root@srvk8s-master01:~# kubectl get pods -l app=wordpress\n        NAME                         READY   STATUS    RESTARTS   AGE\n        wordpress-84d9678558-2lg4g   1/1     Running   0          21s\n        wordpress-84d9678558-gxvpc   1/1     Running   0          21s\n        wordpress-84d9678558-ldj54   1/1     Running   0          21s\n        \n        root@srvk8s-master01:~# kubectl get svc\n        NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE\n        kubernetes   ClusterIP      10.96.0.1      \u003cnone\u003e         443/TCP        3d14h\n        wordpress    LoadBalancer   10.100.77.41   172.31.0.100   80:31481/TCP   36s\n\nCon estos pasos, tendremos WordPress desplegado en el clúster de\nKubernetes con:\n\n-   Alta disponibilidad gracias a las réplicas.\n\n-   Datos persistentes almacenados en el servidor NFS.\n\n-   Un servicio accesible mediante una IP gestionada por MetalLB.\n\n## Cloudflare Tunnel\n\nVamos a hacer uso del tunnel de cloudflare para exponer el aplicativo.\nEsto nos permite hacer accesible el aplicativo, sin exponer la IP de\nnuestra máquina. Además de permitirnos aplicar políticas como la\nrestricción de acceso, esto es muy interesante porque podemos restringir\nel acceso al panel de administración de WordPress.\n\n**Creación Cloudflare Tunnel** Una vez creamos el tunnel, desde el panel\nhttps://one.dash.cloudflare.com/ de cloudflare, nos indicará los pasos a\nseguir para instalarlo en los distintos sistemas. En mi caso lo instaló\nsobre un nodo que tiene conectividad con la red 172.31.0.0/24 para poder\nacceder al aplicativo.\n\n![image](images/install/create_cloudflare_tunnels.png)\n![image](images/install/service_cloudflare_tunnels.png)\n\nDebemos crear un host público, indicando la IP externa de WordPress.\n\n![image](images/install/create_host_publico.png)\n\nUna vez realizado este proceso el aplicativo ya sería accesible de forma\npública.\n\n-   **URL:** https://transparent-edge.tertiaoptio.es\n\n![image](images/install/web_test1.png)\n\n**Agregamos seguridad, restricción acceso panel wp-admin** En el\napartado access, creamos una aplicación de tipo *SELF-HOSTED*.\n\n![image](images/install/access_restrict.png)\n\nAgregamos las rutas a las que restringiremos el acceso.\n\n![image](images/install/application_domain.png)\n\nEn este caso nos ofrecen dos opciones, la primera nos permite autorizar\nun correo haciendo uso del Auth de Google, la segunda nos permite\nautorizar correos también, pero los correos autorizados cuando quieran\nacceder solicitarán un PIN con el que podrán acceder, dicho PIN es\nenviado a su buzón de correo.\n\n![image](images/install/authentication_method.png)\n\nAgregamos una política que nos permitirá controlar los buzones de correo\nque posen acceso.\n\n![image](images/install/policies.png)\n\nEn este caso seleccionamos la opción de agregar buzones de correo\nconcretos, pero también hay opción de permitir acceso a todos los\nbuzones de un dominio concreto, esto para una organización es sumamente\nútil.\n\n![image](images/install/email_access.png)\n\n# Comprobaciones\n\nRealizamos comprobaciones.\n\n![image](images/install/check_policies01.png)\n![image](images/install/web_test1.png)\n![image](images/install/check_policies.png)\n\nTras iniciar sesión con el buzón de correo autorizado, se puede acceder\nal login de forma correcta.\n\n![image](images/install/access_email.png)\n\n# Mejoras\n\nPara aumentar el rendimiento, la tolerancia a fallos y optimizar la\ngestión de recursos, se pueden implementar las siguientes mejoras:\n\n## Hipervisor Proxmox y alta disponibilidad (HA)\n\nUtilizar Proxmox como hipervisor principal incrementa la capacidad de\ncómputo y previene caídas. Al crear un clúster de Proxmox, las máquinas\nvirtuales pueden trasladarse automáticamente a otro servidor en caso de\nque uno falle, garantizando accesibilidad y continuidad operativa.\n\n## NAS para almacenamiento centralizado\n\nImplementar un servidor NAS dedicado para almacenar los discos de las\nmáquinas virtuales elimina la dependencia del almacenamiento local de\nProxmox. Esto permite una mayor flexibilidad, facilita la creacion de\nbackups y habilita características críticas como la alta disponibilidad.\n\n## Copias de seguridad periódicas\n\nEstablecer un sistema de copias de seguridad periódicas (semanales,\nmensuales o según la criticidad de los datos) es esencial para la\nrecuperación ante desastres. Estas copias pueden realizarse en sistemas\nexternos para garantizar la integridad de la información y la\nrecuperación eficiente en caso de fallos.\n\n## Segmentación de sistemas de archivos\n\nConfigurar los servidores con diferentes filesystem segmentados para\ndirectorios críticos como /var, /var/log, y directorios específicos de\nbases de datos como los de MySQL. Esta segmentación ofrece varias\nventajas:\n\n-   Facilita el control del uso de almacenamiento por parte de los\n    diferentes aplicativos.\n\n-   Permite ser más selectivo al ampliar el almacenamiento, evitando la\n    necesidad de grandes cambios en el sistema completo.\n\n-   Mejora el rendimiento del sistema al distribuir las cargas de\n    trabajo.\n\nPor último una visión general del entorno on-premise implementado.\n\n![image](images/proxmox.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclhore%2Fbasickubernetescluster-wordpress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclhore%2Fbasickubernetescluster-wordpress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclhore%2Fbasickubernetescluster-wordpress/lists"}