Javier Ramírez-Urea, arquitecto de soluciones en Hopla! Software
Hoy, os traemos este post sobre Portworx Essentials.
En él, vamos a hablar de cómo utilizar esta herramienta para ofrecer almacenamiento persistente y distribuido a las aplicaciones desplegadas en Kubernetes.
El caso que os traemos es desplegar un simple WordPress.
Veremos cómo el almacenamiento persistente nos permite mover la base de datos, o el propio frontal de WordPress, a cualquier nodo.
Al tratarse de una versión gratuita, no tendremos acceso a algunas de las características de la versión empresarial, a parte de las diferencias de volumen. Por ello, os recomendamos consultar más información sobre este despliegue aquí.
Desplegar WordPress usando Portworx Essentials
#Paso 1
El primer paso es parte de un cluster muy sencillo de Kubernetes. Para esta prueba desplegamos cuatro máquinas virtuales con Terraform y posteriormente lo realizamos con Kubernetes con nuestros playbooks Ansible.
En unos minutos tenemos un cluster con un master y tres nodos worker.
Nuestro despliegue Terraform prepara 25GB de disco en cada nodo worker. Estos discos son los que usaremos como dispositivo de bloques para que Portworx gestione como almacenamiento persistente en nuestro cluster.
Utilizaremos un balanceador externo que redirija las peticiones al FQDN “wordpress.hoplalabs.local” a nuestro Ingress Controller desplegado en el cluster.
Para la instalación de WordPress usaremos un Chart de Bitnami, por lo que nuestro entorno cuenta con Helm ya instalado.
Partiendo de este entorno, revisamos la versión de Kubernetes. IMPORTANTE: será necesario para desplegar Portworx de forma apropiada.
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube-node1 Ready master 10m v1.18.2
kube-node2 Ready <none> 7m45s v1.18.2
kube-node3 Ready <none> 5m21s v1.18.2
Entramos en el portal de Portworx para generar un fichero de despliegue de la plataforma.
Es un proceso muy sencillo que nos guía con sencillas preguntas sobre nuestra infraestructura subyacente. Con nuestras respuestas, el portal genera un fichero que podremos usar directamente.
Registro en Portworx Essentials para crear una cuenta en la plataforma Portworx Central y obtener un usuario de acceso:
Una vez dentro, nos dirigimos a “Install and Run”.
Nos abrirá un entorno ”wizard” que nos guiará por las distintas opciones de plataforma, recopilando la información necesaria para desplegar Portworx en nuestra infraestructura.
Esta herramienta es Spec Generator y nos permite generar los ficheros de despliegue completos, con todos los componentes y características necesarias.
La primera opción que debemos elegir es qué tipo de plataforma vamos a desplegar.
Podemos elegir entre Portworx Essentials y Portworx Enterprise.
Para un entorno de demo, preproducción o desarrollo, recomendamos usar Portworx Essentials. Esta plataforma nos ayudará a entender y ver las características más importantes de Portworx.
Porworx Essentials nos permite gestionar un máximo de 500 volúmenes y 5TB de información. Además, acepta un máximo de 5 nodos, lo que supone un máximo de 1TB por nodo. Portworx Essentials se puede gestionar con un único cluster de Portwox, por lo que será recomendable usar Portworx Enterprise en entorno multi-tenant, por ejemplo.
Una vez seleccionamos Portworx Essentials, comienza la recogida de información de nuestro despliegue. Lo primero que necesitamos saber es la versión de Kubernetes sobre la que se ejecutará la plataforma y la versión de Portworx que desplegaremos.
#Paso 2
En este paso se configura si el despliegue se realizará en alguna nube o en nuestro centro de datos.
Seleccionaremos cómo queremos que Portworx gestione los discos.
En este ejemplo, dejaremos que Portworx busque el almacenamiento disponible y lo adquiera para persistencia.
Nos preguntará, además, por la generación de un disco de journal para gestionar las sincronizaciones y evitar cuellos de botella. Dejamos que Portworx lo genere por nosotros.
El último punto de esta fase se refiere a la disposición de un entorno de KeyValue.
NOTA: Portworx puede usar un entorno externo (recomendable) o bien generar el suyo propio. En el caso de permitir la generación de su propia base de datos, es recomendable usar un disco específico. Dado que se trata de una demo rápida, desplegaremos el entorno sin este recurso específico.
#Paso 3
En este paso podremos especificar los interfaces que usaremos para la red de datos, separando la gestión de la sincronización de los bloques. En este entorno de demo que estamos usando sólo tenemos una interfaz, por lo que podemos dejar estas opciones en “auto”.
#Paso 4
En el último paso debemos especificar sobre qué infraestructura estamos trabajando. De esta forma, Portwrox puede integrarse con la plataforma existente y creará el fichero de despliegue, teniendo en cuenta cualquier particularidad que pudiera ser relevante en el proceso.
Si nuestras imágenes se encuentran en un registro interno o necesitamos configurar variables u opciones adicionales, este será el momento de hacerlo.
Cuando pulsemos “Next”, nos aparecerá un acuerdo de licencia para poder usar la plataforma que vamos a desplegar. El proceso estará completo.
Una vez finalicemos esta guía, el portal generará un fichero de despliegue.
Este fichero puede guardarse para posteriores usos, pudiendo identificarlo por nombre y añadirle etiquetas.
Copiaremos la línea de despliegue. Esta línea variará de unas instalaciones a otras porque identifica unívocamente cada despliegue.
Aplicaremos entonces el despliegue en nuestro cluster *las capturas de pantalla en la demo corresponden a un despliegue anterior:
$ kubectl apply -f
service/portworx-service created
customresourcedefinition.apiextensions.k8s.io/volumeplacementstrategies.portworx.io created
serviceaccount/px-account created
clusterrole.rbac.authorization.k8s.io/node-get-put-list-role created
clusterrolebinding.rbac.authorization.k8s.io/node-role-binding created
namespace/portworx created
role.rbac.authorization.k8s.io/px-role created
rolebinding.rbac.authorization.k8s.io/px-role-binding created
secret/px-essential created
daemonset.apps/portworx created
service/portworx-api created
daemonset.apps/portworx-api created
serviceaccount/stork-account created
clusterrole.rbac.authorization.k8s.io/stork-role created
clusterrolebinding.rbac.authorization.k8s.io/stork-role-binding created
deployment.apps/stork created
storageclass.storage.k8s.io/stork-snapshot-sc created
service/stork-service created
configmap/stork-config created
serviceaccount/stork-scheduler-account created
clusterrole.rbac.authorization.k8s.io/stork-scheduler-role created
clusterrolebinding.rbac.authorization.k8s.io/stork-scheduler-role-binding created
deployment.apps/stork-scheduler created
serviceaccount/px-lh-account created
clusterrole.rbac.authorization.k8s.io/px-lh-role created
clusterrolebinding.rbac.authorization.k8s.io/px-lh-role-binding created
service/px-lighthouse created
deployment.apps/px-lighthouse created
configmap/autopilot-config created
serviceaccount/autopilot-account created
clusterrole.rbac.authorization.k8s.io/autopilot-role created
clusterrolebinding.rbac.authorization.k8s.io/autopilot-role-binding created
deployment.apps/autopilot created
service/autopilot created
Como vemos, el despliegue genera un número importante de recursos en el cluster. Se ejecutarán varios procesos en cada nodo para gestionar la sincronización y uso de los dispositivos de bloques.
Nuestra idea es usar el almacenamiento de Portworx como StorageClass para poder gestionar los volúmenes de forma dinámica.
Creamos entonces un recurso de tipo “StoraceClass”. Usamos “portwrx-sc” en este ejemplo:
$ cat<<EOF|kubectl create -f –
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: portworx-sc
provisioner: kubernetes.io/portworx-volume
parameters:
repl: «1»
EOF
storageclass.storage.k8s.io/portworx-sc created
Una vez tenemos nuestro StorageClass creado, podemos proceder a desplegar WordPress. En este caso, usaremos Helm para realizar el despliegue de forma automatizada.
Para ello, añadimos el repositorio de Charts de Bitnami para la instalación:
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm repo update
Ahora configuramos la instalación de WordPress. Para ello, revisamos las variables que tenemos a nuestro alcance en el Chart para modificar el comportamiento de WordPress (https://hub.helm.sh/charts/bitnami/wordpress). Ponemos atención fundamentalmente en las variables referentes al espacio de almacenamiento persistente de WordPress y MariaDB. Recordemos que tenemos tan sólo 25GB de disco por nodo en nuestro entorno.
$ helm install wordpress \
–set global.storageClass=portworx-sc \
–set persistence.size=1Gi \
–set mariadb.master.persistence.size=2Gi \
–set ingress.enabled=true \
–set ingress.hostname=wordpress.hoplalabs.local \
–set wordpressUsername=admin \
–set wordpressPassword=password \
bitnami/wordpress
NAME: wordpress
LAST DEPLOYED: Thu Aug 27 14:58:43 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
** Please be patient while the chart is being deployed **
Your WordPress site can be accessed through the following DNS name from within your cluster:
wordpress.default.svc.cluster.local (port 80)
To access your WordPress site from outside the cluster follow the steps below:
1. Get the WordPress URL and associate WordPress hostname to your cluster external IP:
export CLUSTER_IP=$(minikube ip) # On Minikube. Use: `kubectl cluster-info` on others K8s clusters
echo «WordPress URL: http://wordpress.hoplalabs.local/»
echo «$CLUSTER_IP wordpress.hoplalabs.local» | sudo tee -a /etc/hosts
2. Open a browser and access WordPress using the obtained URL.
3. Login with the following credentials below to see your blog:
echo Username: admin
echo Password: $(kubectl get secret –namespace default wordpress -o jsonpath=»{.data.wordpress-password}» | base64 –decode)
Accedemos al FQDN de publicación (en DNS y balanceado a las IP de los nodos de publicación de nuestro cluster con el puerto de nuestro Ingress-Controller) y observamos que WordPress está funcionando correctamente.
Si nos fijamos en los PerstentVolumeClaims creados en el proceso de instalación de WordPress, observamos lo siguiente:
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-wordpress-mariadb-0 Bound pvc-34bb23a6-57d3-4ab7-943d-92f00d5dad39 2Gi RWO portworx-sc 1h
wordpress Bound pvc-f6b492c8-7791-42d0-8d85-b393ad598d15 1Gi RWO portworx-sc 1h
Los PVCs están asociados al recurso StorageClass que hemos creado usando Portworx.
Creamos una entrada en el blog accediendo como “admin” para poder comprobar la persistencia en caso de conmutación del servicio.
Vamos a ver qué ocurre ahora si conmutamos los datos. Observamos en qué nodos están los pods desplegados:
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-controller-nginx-ingress-controller-b645f985d-7kg6c 1/1 Running 0 92m 10.10.13.8 worker3 <none> <none>
nginx-controller-nginx-ingress-controller-default-backend-65ngs 1/1 Running 0 4h29m 10.10.13.2 worker3 <none> <none>
wordpress-bfd5f4c68-z7cnt 1/1 Running 0 10m 10.10.9.198 worker2 <none> <none>
wordpress-mariadb-0 1/1 Running 0 4h5m 10.10.13.7 worker3 <none> <none>
Lo más sencillo en esta situación para asegurar que MariaDB se irá a otro nodo, será hacer un “drain” en el nodo worker3, por ejemplo. Veamos qué sucede:
$ kubectl drain worker3 –ignore-daemonsets
node/worker3 cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-ps5f8, kube-system/kube-proxy-tnjqw, kube-system/portworx-api-wfhs4, kube-system/portworx-sk2xz
evicting pod default/nginx-controller-nginx-ingress-controller-default-backend-65ngs
evicting pod default/nginx-controller-nginx-ingress-controller-b645f985d-7kg6c
evicting pod kube-system/autopilot-58db5f4dbb-2kd9x
evicting pod default/wordpress-mariadb-0
evicting pod kube-system/stork-f4799f469-m6k6h
evicting pod kube-system/stork-scheduler-8d85c5b46-gsnc4
pod/stork-f4799f469-m6k6h evicted
pod/nginx-controller-nginx-ingress-controller-default-backend-65ngs evicted
pod/stork-scheduler-8d85c5b46-gsnc4 evicted
pod/autopilot-58db5f4dbb-2kd9x evicted
pod/nginx-controller-nginx-ingress-controller-b645f985d-7kg6c evicted
pod/wordpress-mariadb-0 evicted
node/worker3 evicted
Como es de esperar, el Pod de MariaDB se mueve a otro nodo. En este caso, worker1 recibe la carga.
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-controller-nginx-ingress-controller-b645f985d-l5qnn 1/1 Running 0 95s 10.10.11.138 worker1 <none> <none>
nginx-controller-nginx-ingress-controller-default-backend-46qc4 1/1 Running 0 96s 10.10.11.137 worker1 <none> <none>
wordpress-bfd5f4c68-z7cnt 0/1 Running 5 23h 10.10.9.198 worker2 <none> <none>
wordpress-mariadb-0 0/1 ContainerCreating 0 37s <none> worker1 <none> <none>
Tras unos segundos, el proceso está de nuevo en ejecución. Esta vez la base de datos se encuentra en el nodo worker1.
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-controller-nginx-ingress-controller-b645f985d-l5qnn 1/1 Running 0 3m31s 10.10.11.138 worker1 <none> <none>
nginx-controller-nginx-ingress-controller-default-backend-46qc4 1/1 Running 0 3m32s 10.10.11.137 worker1 <none> <none>
wordpress-bfd5f4c68-z7cnt 1/1 Running 6 23h 10.10.9.198 worker2 <none> <none>
wordpress-mariadb-0 1/1 Running 0 2m33s 10.10.11.140 worker1 <none> <none>
provision@kube1:~$
Este es un ejemplo muy sencillo, con el que podemos ver cómo de sencillo resulta usar Portworx Essentials para gestionar nuestro almacenamiento persistente en Kubernetes.
Portworx nos permite garantizar los datos en un cluster e incluso entre varios distintos; siendo además una herramienta fundamental cuando estos clusters se encuentran en diferentes localizaciones o entornos cloud.
La gestión de la disponibilidad, número de réplicas de bloque, sincronización, snapshots, etc, en Portworx queda fuera del alcance de este sencillo post pero esperamos que os haya sido de utilidad y os anime a usar esta potente herramienta.
Puedes descargarte el resultado final en este link