Oggi voglio parlare di come deployare su un cluster Kubernetes un WordPress+MySQL utilizzando volumi persistenti e soprattutto andando a vedere come è facile scalare una volta che abbiamo effettuato il deploy.
Riguardo Kubernetes c’è poco da dire, è un orchestratore, probabilmente il migliore in circolazione che permette di ridefinire i concetti di applicazione utilizzando il paradigma ormai consolidato dei container (su Kubernetes sono i pods)
Per maggiori dettagli vi rimando alla documentazione ufficiale disponibile a questo link
Vediamo lo scenario che vogliamo raggiungere:
Per fare questo ho “costruito” 3 VM:
- Kube Master
- Kube Slave
- Kube Slave2
Su queste ho costruito un cluster e poi deployato i vari servizi come indicato in figura.
Il sistema operativo usato sulle 3 VM è Ubuntu 20.04 LTS con 2GB di RAM, 2 Processori (necessari per Docker e Kubernetes) e un disco da 25GB giusto per fare un po’ di prove. La scheda di rete di tutte e 3 le VM è in Bridge con la mia eth del pc così da avere i device disponibili il DHCP sulla mia rete interna.
Vediamo adesso i passaggi da seguire (Ci sono diverse scuole di pensiero, io ho preferito usare il deploy classico basato sui pacchetti, altri preferiscono Minikube)
Una volta installato il sistema operativo (con un utente non root) e avviato si procede con l’installazione dei pacchetti fondamentali:
sudo apt-get update && sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add –
sudo bash -c ‘echo “deb http://apt.kubernetes.io/ kubernetes-xenial main” > /etc/apt/sources.list.d/kubernetes.list’
sudo apt-get update && sudo apt-get install -y kubelet kubeadm kubectl
Prima di inizializzare il nodo master dobbiamo aver installato Docker o un altro sistema che permetta la containerizzazione(lo stesso Virtual Box lo permette).
Una volta installato Docker procediamo con l’inizializzazione sul nodo master disattivando prima la Swap (anche se è possibile ignorare il preflight con il comando: –ignore-preflight-errors=Swap)
sudo swapoff -a
sudo kubeadm init
Fatto questo procediamo con la copia dei file di configurazione come indicato:
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
Una volta che il nodo Master è stato inizializzato si può passare a fare la join dei nodi Slave con la stringa fornita in fase di fine inizializzazione del master:
kubeadm join IP_ADDRESS:6443 –token TOKEN_KEY \
–discovery-token-ca-cert-hash sha256:XXXXXXXXXXXXXXXXXX
Quando i due slave avranno terminato la join, dal master dando il comando:
kubectl get nodes
Vedremo un output del genere:
Benissimo, adesso il cluster Kubernetes è pronto per ospitare i Pods, ma prima di procedere dobbiamo installare un CNI (Container Network Interface) per far parlare master e slave.
I più diffusi sono Flannel e Calico. Per il mio esempio ho usato Calico che è facilmente installabile eseguendo questi due deploy:
kubectl create -f https://docs.projectcalico.org/manifests/tigera-operator.yaml
kubectl create -f https://docs.projectcalico.org/manifests/custom-resources.yaml
Una volta installato avremo una situazione del genere:
Adesso si può procedere con il deploy della nostra applicazione.
Per prima cosa andiamo a creare un Persistent Volume che sarà fondamentale per poter caricare su il DB MySQL e i file di WordPress. Anche in questo caso esistono diverse scuole di pensiero e tipologie di volumi installabili, io ho utilizzato il caso più semplice, ovvero con un volume locale sul nodo Master (altre soluzioni usano NFS, GlusterFS etc.)
Procediamo:
kubectl create -f https://github.com/IBM/Scalable-WordPress-deployment-on-Kubernetes/blob/master/local-volumes.yaml
Facendo così creo i volumi necessari che verranno poi “rivendicati” da WordPress e MySQL.
Questa operazione è fondamentale farla prima altrimenti le successive procedure non andranno a buon fine.
Ora creiamo un file dove indichiamo alcune personalizzazioni (es. la pwd di root di MySQL):
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: mysql-pass
literals:
- password=YOUR_PASSWORD
EOF
Fatto questo scarichiamo i seguenti files:
curl -LO https://k8s.io/examples/application/wordpress/mysql-deployment.yaml
curl -LO https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml
Questi li aggiungeremo al file di kustomization:
cat <<EOF >>./kustomization.yaml
resources:
- mysql-deployment.yaml
- wordpress-deployment.yaml
EOF
Adesso abbiamo quasi terminato e possiamo procedere con:
kubectl apply -k ./
Se tutto è andato a buon fine potrete vedere alcune schermate come di seguito:
Ora per poter fare una installazione pulita di WordPress, dato che siamo in una LAN per cui l’EXTERNAL-IP non ce l’ho, possiamo aggirare il problema facendo questa mossa:
kubectl patch svc deployments/wordpress -p '{"spec":{"externalIPs":["192.168.XX.XX"]}}'
Facendo così e aggiungendomi nel mio file hosts la mappatura:
192.168.XX.XX paolodaniele.test
Posso installare il tutto andando dal mio browser al link http://paolodaniele.test
Abbiamo finito! Se vogliamo aumentare e quindi scalare il nostro WordPress ad esempio in caso ti traffico elevato basta fare così:
kubectl scale deployments/wordpress –replicas=8
Ed ecco quello che apparirà dopo poco:
Dietro Kubernetes e la containerizzazione c’è un mondo che piano piano sto cercando di scardinare 🙂
Enjoy!
Ciao, quale dovrebbe essere la procedura per far accedere il nodo all’esterno (su internet), quindi impostare l’external ip corretto fornito dal provider della virtual machine?
saluti
Ciao,
per far accedere il nodo dall’esterno o indichi l’ip come ho fatto io nella guida, oppure per utilizzare il load balancer devi aprire una macchina su google o aws che hanno il supporto nativo.