--- tags: anarky, k8s, kubernetes --- # K8s ep1 ## Concepts Kubernetes is a portable, extensible and open-source platform for managing containerized workloads and services. ##### Containers Each container that you run is repeatable; the standardization from having dependencies included means that you get the same behavior wherever you run it. Containers decouple applications from underlying host infrastructure. This makes deployment easier in different cloud or OS environments. ##### Containers images A container image represents binary data that encapsulates an application and all its software dependencies. Container images are executable software bundles that can run standalone and that make very well defined assumptions about their runtime environment. ##### Pods A Pod is a wrapper around one or more containers. Most often, a Pod contains only a single container — however, for advanced use cases, a Pod may contain multiple containers. If a Pod contains multiple containers, they are treated by Kubernetes as a unit — for example, they are started and stopped together and executed on the same node. *A Pod is the smallest unit of deployment in Kubernetes — you never work with containers directly, but with Pods that wrap containers.* --- ## Hands on Lo scopo finale è di avere un cluster k8s, con due pods: *matches* e *people*. Questi due pods saranno raggiungibili dall'esterno del network k8s. ### Steps - [ ] 1. Project scaffolding - [ ] 2. Creazione microservizi *matches* e *people* - [ ] 3. Creazione immagine docker con push su Dockerhub - [ ] 3. Deploy servizi su minikube con *Deployment* e *Service*. #### 1. Project scaffolding ![](https://i.imgur.com/x4IE7kU.png) #### 2. Creazione microservizi matches e people All'interno delle sue cartelle servizi inizializzare npm con `npm init` e sucessivamente installare il necessario con `npm i express` Inserire all'interno di *index.js* il seguente script ``` const express = require('express') const app = express() const os = require('os'); const port = process.env.PORT || 3000 app.get('/', (req, res) => { res.send({ i: `Welcome in people.`, hn: `${os.hostname()}` }) }) app.listen(port, () => { console.log(`People app listening in ${port}`) }) ``` > Riportare in entrambi i servizi ricordandosi di cambiare il nome del servizio. Testare quanto fatto eseguendo il servizio con `nodemon index.js` #### 3. Creazione immagine docker con push su Dockerhub Il primo passo per contenerizzare un servizio è creare la dockerimage. Copiare il seguente contenuto dentro il file *Dockerfile* ``` FROM node:12.0-slim COPY . . RUN npm install CMD [ "node", "index.js" ] ``` Dopo aver specificato l'immagine lanciamo la build tramite il comando `docker build -t matches:0.0.0 .` e `docker build -t people:0.0.0 .` dove -t sta per tag, ovvero il nome che vogliamo dare all'immagine A questo punto lanciando `docker images` in cima appariranno le nostre due immagini pronte ad essere utilizzate. ![](https://i.imgur.com/NgxcXjV.png) Per testare le nostre immagini lanciamo ``` docker run --name=matches -p 3000:3000 -e PORT=3000 "matches:0.0.0" ``` Dove -p specifica il port forwarding `<macport>:<containerport>` -e specifica la variabile d'ambiente PORT A questo punto su localhost:3000 dovrebbe girare la nostra app. E possibile visualizzare i container runnati digitando `docker ps` Siccome però le nostre immagini devono andare all'interno di un cluster k8s bisogna pubblicarle. Il repo ufficiale per le immagini Docker è Dockerhub. Dopo esserci registrati online lanciare `docker login` e loggarsi in locale Taggiamo la nostra immagine con `docker tag matches:0.0.0 <dockerhubusername>/matches:0.0.0` e `docker tag people:0.0.0 <dockerhubusername>/people:0.0.0` Una volta taggata l'immagine è necessario pusharla con il comando `docker push <dockerhubusername>/matches:0.0.0` #### 3. Deploy servizi su minikube con Deployment e Service. La fondazione k8s ha creato minikube, una versione minimale di Kubernetes creata appositamente per lo sviluppo locale. Installiammola con `brew install minikube` Una volta installata creiamo il cluster con `minikube start` Verifichiamo il corretto funzionamento del cluster con `kubectl cluster-info`. *Kubectl* è la CLI di kubernetes, e in questo momento è già connessa a minikube. Kubernetes ha un interfaccia dichiarativa. In altre parole possiamo descrivere una qualsiasi risorsa tramite un file YAML. Ci sono diverse risorse k8s (che possono essere rappresentate in uno YAML). * [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) rappresenta le istruzioni per la creazione o per la modifica di Pod. * Service rappresenta lo strato network che è possibile abbinare ad un Deployment, ovvero a un gruppo ben identificato di [Pods](https://kubernetes.io/docs/concepts/workloads/pods/). Nella cartella *kube* nei due servizi aggiungere file *kube.yaml* ``` apiVersion: apps/v1 kind: Deployment metadata: name: matches spec: replicas: 1 selector: matchLabels: app: matches template: metadata: labels: app: matches spec: containers: - name: app image: <dockerhubusername>/matches:0.0.0 ports: - containerPort: 3000 env: - name: PORT value: "3000" imagePullPolicy: Always ``` Creiamo ora il servizio, ovvero il layer network del deployment sopra specificato. ![](https://i.imgur.com/aTnewEq.png) Aggiungiamo il codice al di sopra del file precedentemente creato dividendo il contenuto con `---` ``` apiVersion: v1 kind: Service metadata: name: matches spec: selector: app: matches ports: - port: 80 targetPort: 3000 type: LoadBalancer --- <codice deployment inserito prima> ``` Deployamo le risorse appena definite con il comando `kubectl apply -f kube ` * Con il comando `kubectl get pods --watch` possiamo visulizzare i pods attivi nel cluster in live. * Con il comando `minikube service matches` possiamo creare un tunnel tra la il network del cluster e la rete locale, necessario solo su mac (dove la rete docker risulta necessariamente divisa) * Con il comando `kubectl scale --replicas=2 deployment/matches` è possibile scalare l'app da 1 a due replice. Questo creerà due pods, assegnati ad un nodo del cluster a caso. Fine ep 1 🧅