Guida per la costruzione di un Cluster Kubernetes con Ubuntu

dic 11, 2019

Creazione di un cluster di kubernetes Ubuntu 18.04

Obiettivo

Con questa guida andremo a costruire un cluster kubernetes con un master e due slave. Potremo successivamente vedere anche come poter far diventare il master una sorta di slave di se stesso, tutto questo con delle VM Ubuntu 18.04-server.

  • Composizione Cluster:
    • Master: 192.168.10.10
    • Slave-01: 192.168.10.50
    • Slave-02: 192.168.10.51

Noi partiremo con tutte e 3 le VM create, inizializzate , aggiornate e senza precedenti installazioni di kubernetes (nel caso fate pure un purge di docker.io e cointenerd).

Cambiate l’host-name alle VM come Kube-Master(192.168.10.10), kube-slave01(192.168.10.50) e kube-slave02(192.168.10.51).

Inizializziamo il cluster

Installazione di docker

Questa parte dovrà essere ripetuta su ogni server:

$ sudo apt install docker.io

Se tutto è andato a buon fine, abilitare l’avvio automatico del docker:

$ sudo systemctl enable docker

 

Installazione di Kubernetes

Anche questi passaggi andranno ripetuti sui tre server, quindi cominciamo col mettere le chiavi di kubernetes:

$ sudo apt install apt-transport-https ca-certificates curl && curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add

Ritornerà “OK” Successivamente aggiungiamo i repository per la versione di Ubuntu in uso, purtroppo per Bionic non hanno ancora rilasciato una distribuzione supportata, come possiamo vedere anche quì https://packages.cloud.google.com/apt/dists dovremo quindi per il momento utilizzare yakkety che è supportato per bionic:

$ cat deb https://apt.kubernetes.io/ kubernetes-xenial main EOF

Aggiorniamo e installiamo kubeadm:

$ sudo apt update $ sudo apt install kubeadm kubectl kubelet

Kubernetes rifiuterà di utilizzare la memoria swap per una esigenza di prestazioni, quindi dovremo disabilitarla (per rendere la disabilitazione fissa, andare a commentare in /etc/fstab la riga riguardante lo swap)

$ sudo swapoff -a

Facciamo partire kubernetes

Preparazione

Questa fase riguarderà solo il master: prima di inizializzarlo dobbiamo fare una modifica per evitare l’errore riportato di seguito

([WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver.)

 

Per evitare questo errore dobbiamo editare un file

$ sudo vim /lib/systemd/system/docker.service 

Quì cerchiamo una stringa che inizia con “ExecStart” e senza cancellarla alla fine di essa aggiungiamo --exec-opt native.cgroupdriver=systemd In questo modo forzeremo l’uso dei driver “systemd”, riavviamo il servizio di docker.

ATTENZIONE: kubernetes non risulta compatibile con i file system formattati in ext4( consigliano lo zfs), durante lo start del master quindi se avete un file system formattato in ext4 potrebbe darvi un allarme di questo genere:

Potete anche ignorarlo per il momento, infatti non vi impedirà di creare pod o deploy sul cluster che stiamo andando a creare

Start del master

Ora possiamo far partire il master, utiliziamo il comando sottostante, la rete 10.244.0.0/16 è una rete fittizia che kubernetes utilizzerà per gestire i propri pod con gli slave

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors all

Una volta lanciato questo comando attendiamo qualche minuto (il tempo di un caffè) e leggiamo bene il risultato finale che sarà simile a questo:

Molto importante da tenersi via è “kubeadm join 192.168.148.61:6443 --token 3k38vh.e7tdsi9cpgjnw6ik \    --discovery-token-ca-cert-hash sha256:f7b7f237cb456768ae9fd5ee481a768db519395f28913051cff79f1c6d3c9617 Questo comando ci servirà sugli slave per fare il join al master (c’è anche un modo per recuperarlo in un secondo momento, lo vedremo alla fine). Congratulazione, il vostro master è partito! ora vedremo come creare un utente dedicato (non obbligatorio ma consigliato).

Configurazione dell’utente non privilegiato 

Creiamo un utente linux, noi lo chiameremo vision, e logghiamo con quell’utente

$ sudo useradd vision -G sudo -m -s /bin/bash $ sudo passwd packet $ sudo su vision

Ora possiamo configurare le variabili d’ambiente sul nuovo utente come suggerivano anche le istruzione alla fine dell’init del master (poco prima del comando kubeadm join che ci siamo salvati)

$ cd $HOME $ sudo cp /etc/kubernetes/admin.conf $HOME/ $ sudo chown $(id -u):$(id -g) $HOME/admin.conf $ export KUBECONFIG=$HOME/admin.conf $ echo "export KUBECONFIG=$HOME/admin.conf" | tee -a ~/.bashrc

Utente kubernetes creato e configurato!

Applicazione del primo POD

Il pod che andremo ad applicare servirà per mettere in comunicazione il master coi vari nodi(gli slave) che andremo a creare, l’intero cluster quindi 

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml $ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml

Attendete qualche secondo/minuto che la configurazione venga scaricata, il pod creato e venga poi abilitato. Per verificare il corretto stato del pod:

$ kubectl get pods --all-namespaces

il pod dovrà tornarci lo stato di “running”come quì sotto:

Siamo quindi pronti a fare il join dei due slave, inoltre come detto in precedenza possiamo anche fare in modo che il master diventi slave di se stesso, infatti senza questo comando non potrebbe caricare i pod che andremo a installare, naturalmente questo passaggio è consigliato o meno in base al cluster che andrete a costruire

$kubectl taint nodes --all node-role.kubernetes.io/master-

Facciamo il Join degli Slave

Una volta loggati in Slave-01 e Slave-02 potremo utilizzare quella stringa che ci eravamo salvati in precedenza, ovvero:

$ sudo kubeadm join 192.168.148.61:6443 --token 3k38vh.e7tdsi9cpgjnw6ik \    --discovery-token-ca-cert-hash sha256:f7b7f237cb456768ae9fd5ee481a768db519395f28913051cff79f1c6d3c9617

Facciamo questo su entrambi gli Slave.

Se per qualche motivo avessimo perso questa stringa, nessun problema, basterà scrivere sul master, con l’utente vision: (ATTENZIONE: questo genererà un nuovo token per il join, non andando a impattare in nessun modo su chi già si trova nel cluster).

$ kubeadm token create --print-join-command

Ritorniamo sul master e dopo qualche minuto dal join, lanciamo questo comando:

$ kubectl get nodes

Ci ritonerà la costruzione del cluster, mostrandoci il master nello stato Ready e in teoria se tutto è andato bene, dopo almeno 3 minuti anche gli slave. Non preoccupatevi se sotto ROLES per gli slave vedremo è normale.

Molto bene! abbiamo creato il Cluster! ora vedremo come gestirlo comodamente tramite una dashboard.

Deploy della dashboard

Deploy della dashboard adatta

Per scegliere la Dashboard adatta controlliamo prima la versione che abbiamo installato di kube, utiliziamo il comando:

$ kubeadm version

Noi stiamo utilizzando al momento la v1.16.3 come da immagine sottostante.

Rechiamoci quindi a questa pagina da quì possiamo vedere le ultime versioni compatibili con la nostra versione di kube, utilizzeremo ora la v2.0.0-beta6.

Andiamo sul Master e come consigliato dalla pagina github, eliminiamo ogni eventuale precedente versione della dashboard prima di fare il deploy (noi andiamo sempre a utilizzare l’utente vision).

$ kubectl delete ns kubernetes-dashboard $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta6/aio/deploy/recommended.yaml

Vi ritornerà qualcosa simile a questo: (notate bene che ha creato un nuovo namespace chiamato kubernetes-dashboard, ci servirà per capire meglio dopo alcune cose)

Deploy effettuato, dashboard caricata, ovviamente come per altre cose possiamo controllare tutto col comando generale:

$ kubectl get all --all-namespaces

Così potremo vedere il nuovo pod sotto al nuovo namespace

Creazione dell’account Admin

Avremo bisogno di un account amministratore di kubernetes per accedere alla dashboard, in modo tale che abbia i permessi per poter monitorare controllare il cluster, altrimenti potrebbe tornare un errore simile a the dashboard response Not enough data to create auth info structure. Andiamo quindi a creare lo yaml che ci servirà per la creazione dell’utente, sempre dal master e sempre con l’utente vision

$ nano webvision-dashboard.yml

incolliamoci dentro questo:

apiVersion: v1 kind: ServiceAccount metadata:ame: web-vision namespace: kube-system

Applichiamo lo yaml

$ kubectl apply -f webvision-dashboard.yml

Ci confermerà che è stato creato (serviceaccount/web-vision created)

Ora dovremo assegnare il ruolo di admin all’utente appena creato per farlo creiamo un nuovo file chiamato ClusterRoleBinding.yml non farà altro che copiare i permessi di un utente che dovrebbe già esistere nel cluster e assegnarli a questo nuovo utente.

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:   name: web-vision roleRef:   apiGroup: rbac.authorization.k8s.io   kind: ClusterRole   name: cluster-admin subjects: - kind: ServiceAccount   name: web-vision   namespace: kube-system

Applichiamo:

$ kubectl apply -f ClusterRoleBinding.yml

Vediamo il token per l’accesso

Prima di provare ad accedere alla dashboard via browser ci serve un ultimo dato, il token segreto per l’accesso con il nuovo utente creato, possiamo risalire al token con questo comando:

$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep web-vision | awk '{print $1}')

Tieniamoci da parte questo token, ora per poter accedere alla dashboard da fuori il cluster dobbiamo creare un tunnelling verso il master, prima però abilitiamo il proxy:

$ kubectl proxy

Ora andiamo sul nostro pc e creiamo questo tunnel verso il master, apriamo una shell in locale e usiamo il comando:

$ ssh -L 8001:127.0.0.1:8001 -N vision@192.168.10.10

perfetto!  ora possiamo accedere alla dashboard tramite l’indirizzo: http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login

Scegliamo come tipo di accesso “by token” e inseriamo quello dell’utente web-vision trovato e salvato in precedenza, accediamo e troveremo una schermata simile a questa:

Complimenti! abbiamo fatto l’accesso alla dashboard, da quì possiamo avere il pieno controllo di ogni pod, servizio o deployment, noi ad esempio ne abbiamo già caricato uno con nginx.