Kubernetes e come toccare le nuvole per meri mortali

Learning Friday del 07/07/2023

Alessandro Accardo

permalink qr code

Chi sono

Ciao, sono Alessandro Accardo, forse vi ricorderete di me per altri Learning Friday come Introduzione a Docker o Introduzione a Kubernetes.

Ecco chi sono.

  • Senior Developer
  • Solution Architect
  • Specializzato in soluzioni Cloud-Native
  • Nerd
  • Appassionato di tecnologia
  • Hacker

Kubectl, Ring of the Elves

Tre Anelli ai Re degli Elfi sotto il cielo che risplende

Kubernetes fornisce uno strumento a riga di comando per comunicare con il control plane di un cluster Kubernetes, utilizzando l'API Kubernetes.

Questo strumento si chiama kubectl.

Kubectl è lo strumento che permette di controllare (operare, dicono quelli bravi) un cluster Kubernetes.

Kubectl permette di leggere informazioni da un cluster o applicare modifiche a un cluster, ma lavora sempre e solo su un singolo cluster, pur avendo il concetto di contesto e potendo quindi cambiare contesto (cambiare cluster) a necessità.

Per la configurazione, kubectl cerca un file chiamato config nella directory $HOME/.kube. È possibile specificare altri file kubeconfig impostando la variabile d'ambiente KUBECONFIG o il flag --kubeconfig.

Esempi di utilizzo

source <(kubectl completion bash)
kubectl config get-contexts                # display list of contexts
kubectl config current-context             # display the current-context
kubectl config use-context my-cluster-name # set the default context to my-cluster-name
kubectl apply -f ./my-manifest.yaml        # create resource(s)
kubectl apply -f ./my1.yaml -f ./my2.yaml  # create from multiple files
kubectl apply -f ./dir                     # create resource(s) in all manifest files in dir
kubectl apply -f https://git.io/vPieo      # create resource(s) from url
# Create multiple YAML objects from stdin
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: busybox-sleep
spec:
  containers:
  - name: busybox
    image: busybox:1.28
    args:
    - sleep
    - "1000000"
EOF
# Get commands with basic output
kubectl get services                          # List all services in the namespace
kubectl get pods --all-namespaces             # List all pods in all namespaces
kubectl get pods -o wide                      # List all pods in the current namespace, with more details
kubectl get deployment my-dep                 # List a particular deployment
kubectl get pods                              # List all pods in the namespace
kubectl get pod my-pod -o yaml                # Get a pod's YAML
kubectl set image deployment/frontend www=image:v2
       # Rolling update "www" containers of "frontend" deployment, updating the image
kubectl rollout history deployment/frontend              # Check the history of deployments including the revision
kubectl rollout undo deployment/frontend                 # Rollback to the previous deployment
kubectl rollout undo deployment/frontend --to-revision=2 # Rollback to a specific revision
kubectl rollout status -w deployment/frontend
            # Watch rolling update status of "frontend" deployment until completion
kubectl rollout restart deployment/frontend              # Rolling restart of the "frontend" deployment
kubectl scale --replicas=3 rs/foo                                 # Scale a replicaset named 'foo' to 3
kubectl scale --replicas=3 -f foo.yaml                            # Scale a resource specified in "foo.yaml" to 3
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql
  # If the deployment named mysql's current size is 2, scale mysql to 3
kubectl scale --replicas=5 rc/foo rc/bar rc/baz                   # Scale multiple replication controllers
kubectl logs my-pod                    # dump pod logs (stdout)
kubectl logs -l name=myLabel           # dump pod logs, with label name=myLabel (stdout)
kubectl logs my-pod --previous         # dump pod logs (stdout) for a previous instantiation of a container
kubectl logs my-pod -c my-container    # dump pod container logs (stdout, multi-container case)
kubectl logs -l name=myLabel -c my-container # dump pod logs, with label name=myLabel (stdout)
kubectl logs my-pod -c my-container --previous
         # dump pod container logs (stdout, multi-container case) for a previous instantiation of a container
kubectl logs -f my-pod                 # stream pod logs (stdout)
kubectl logs -f my-pod -c my-container  # stream pod container logs (stdout, multi-container case)
kubectl logs -f -l name=myLabel --all-containers # stream all pods logs with label name=myLabel (stdout)
kubectl run -i --tty busybox --image=busybox:1.28 -- sh # Run pod as interactive shell
kubectl run nginx --image=nginx -n mynamespace
         # Start a single instance of nginx pod in the namespace of mynamespace
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
         # Generate spec for running pod nginx and write it into a file called pod.yaml
kubectl attach my-pod -i                   # Attach to Running Container
kubectl port-forward my-pod 5000:6000
         # Listen on port 5000 on the local machine and forward to port 6000 on my-pod
kubectl exec my-pod -- ls /                # Run command in existing pod (1 container case)
kubectl exec --stdin --tty my-pod -- /bin/sh # Interactive shell access to a running pod (1 container case)
kubectl exec my-pod -c my-container -- ls / # Run command in existing pod (multi-container case)
kubectl top pod POD_NAME --containers      # Show metrics for a given pod and its containers
kubectl top pod POD_NAME --sort-by=cpu     # Show metrics for a given pod and sort it by 'cpu' or 'memory'

Helm, Ring of the Dwarves

Sette ai Principi dei Nani nelle lor rocche di pietra

Se Kubernetes fosse un sistema operativo, Helm sarebbe il gestore dei pacchetti. Ubuntu usa apt, CentOS usa yum e Kubernetes usa helm.

Helm distribuisce le applicazioni pacchettizzate su Kubernetes e le struttura in chart. Questi chart contengono tutte le risorse applicative preconfigurate e tutte le versioni in un unico pacchetto facilmente gestibile.

Helm semplifica l'installazione, l'aggiornamento, il recupero delle dipendenze e la configurazione delle distribuzioni su Kubernetes con semplici comandi CLI. I pacchetti software si trovano nei repository o vengono creati.

Gli oggetti Kubernetes sono difficili da gestire. Con strumenti utili, la curva di apprendimento di Kubernetes diventa fluida e gestibile. Helm automatizza la manutenzione dei manifesti YAML per gli oggetti Kubernetes, impacchettando le informazioni nelle chart e pubblicandole in un cluster Kubernetes.

Helm tiene traccia della cronologia delle versioni di ogni installazione e modifica della chart. Il rollback a una versione precedente o l'aggiornamento a una versione più recente sono completati con comandi comprensibili.

Dashboard, Ring of the Men

Nove agli Uomini Mortali che la triste morte attende

Kubernetes Dashboard è un utile componente aggiuntivo che ti consente di monitorare l'attività del tuo cluster dal tuo browser.

Puoi utilizzare Dashboard per distribuire applicazioni containerizzate in un cluster Kubernetes, risolvere i problemi dell'applicazione containerizzata e gestire le risorse del cluster.

Puoi utilizzare Dashboard per ottenere una panoramica delle applicazioni in esecuzione sul tuo cluster, nonché per creare o modificare singole risorse Kubernetes (come deployments, jobs, DaemonSets e così via). Ad esempio, puoi ridimensionare un deployment, avviare un aggiornamento in sequenza, riavviare un pod o distribuire nuove applicazioni utilizzando una procedura guidata di distribuzione.

La dashboard fornisce anche informazioni sullo stato delle risorse Kubernetes nel tuo cluster e su eventuali errori che potrebbero essersi verificati.

Può anche soddisfare i requisiti di base di modifica delle risorse, ma dovrai comunque lavorare con i manifest per la maggior parte del tempo. Il modulo di creazione delle risorse è adatto solo per i casi d'uso più elementari e non funziona affatto con gli elementi esistenti.

L'abilitazione della dashboard è facoltativa e non sarà necessariamente utile in tutti gli scenari. Se ti senti a tuo agio con il terminale, sei preoccupato per la sicurezza o cerchi di ridurre al minimo il consumo di risorse in background, non perderai nulla rimanendo fedele agli strumenti CLI più familiari.

Bonus point: Qui abbiamo parlato della dashboard ufficiale del progetto Kubernetes. Prevalentemente perché è, per l'appunto, ufficiale.

Esistono però varie e variegate altre dashboard di terze parti che possono essere migliori o più semplici da installare, o focalizzate sulla Ops Experience (OX) oppure focalizzate sulla sicurezza.

Tra quelle che è doveroso citare, direi che ci sono Skooner, Headlamp e Weaveworks Scope. Non li tratteremo, ma dobbiamo citarli.

Manifests, The One Ring

Uno per l'Oscuro Sire chiuso nella reggia tetra, Nella Terra di Mordor, dove l'Ombra nera scende.

Un file manifest di Kubernetes è la vostra guida personale attraverso un cluster Kubernetes: Un file di configurazione scritto in formato YAML o JSON, che descrive le risorse che volete nel vostro cluster. Queste risorse possono essere una miriade di cose: pod (che eseguono le applicazioni), servizi (che aiutano le applicazioni a comunicare) e deployment (che gestiscono le applicazioni).

Si può anche pensare a un file manifest come a una lista dei desideri di Kubernetes: comunica quali risorse volete e come volete che siano configurate.

Bonus: Charts, The Minor Rings

Helm utilizza un formato di packaging chiamato chart. Un chart è un insieme di file che descrivono un insieme correlato di risorse Kubernetes. Un singolo chart può essere utilizzato per distribuire qualcosa di semplice, come un pod memcached, o qualcosa di complesso, come un intero stack di app web con server HTTP, database, cache e così via.

I chart sono creati come file disposti in un particolare albero di directory. Possono essere impacchettati in archivi di versione per essere distribuiti.

Se si desidera scaricare e consultare i file di un chart pubblicato, senza installarlo, è possibile farlo con helm pull chartrepo/chartname.

Charts come template per diversi applicativi simili tra loro

Ora, visto che le chart di fatto non sono altro che template di manifest, possiamo pensare che, dato un set di configurazioni comuni (quindi ad alta similarità di manifest) quello che differenzia una chart dall'altra è solo il descrittore values.yaml che viene passato ad helm per configurare le opzioni della chart.

Chiaramente, è più facile vederlo che usare 1000 parole per spiegarlo.

Charts come installer per sistemi complessi

Il motivo per cui helm è nato, e quindi per cui esistono le charts, è proprio perché si è iniziato a parlare di stack applicativi, cioè un insieme di software che compongono un sistema completo che implementa una funzionalità o un ristretto insieme di queste.

Proprio per l'astrazione ulteriore che questi strumenti hanno fornito, si è presa la strada di alzare il livello di astrazione durante la progettazione di sistemi distribuiti complessi trattando gli stack come applicativi singoli. Questo ha permesso di progettare sistemi sempre più complessi e con un alto grado di interoperabilità, e ha permesso la nascita di molti standard di settore e l'affermazione di stack applicativi come best practice e standard de facto.

Prerequisiti

Un Anello per domarli, un Anello per trovarli, Un Anello per ghermirli e nel buio incatenarli. Nella Terra di Mordor, dove l'Ombra cupa scende.

  1. Una distribuzione Linux (io uso OpenSuSE, ma va bene anche Ubuntu, Debian, Fedora, Arch). Non garantisco supporto o funzionamento delle procedure per Windows + WSL2, MacOS, *BSD o altri sistemi minori.
  2. Go 1.18 o superiore (https://golang.org)
  3. Kubectl 1.24 o superiore (https://kubernetes.io/docs/tasks/tools/#kubectl)
  4. Helm 3.12.0 o superiore (https://helm.sh)

Per far funzionare la baracca, avremo anche bisogno di inserire queste righe nel nostro file hosts (/etc/hosts).

127.0.0.1       kind.local
127.0.0.1       dashboard.kind.local
127.0.0.1       monitoring.kind.local
127.0.0.1       prometheus.kind.local
127.0.0.1       petclinic.kind.local

Altro requisito è clonare il mio repository, che contiene già tutti i file necessari per questo Hands-On.

Tutti i comandi verranno eseguiti nel contesto di questa directory.

git clone https://github.com/kLeZ/20230707-LF-k8s-hands-on.git

Installare un cluster di test con KinD

KinD è uno strumento per l'esecuzione di cluster Kubernetes locali utilizzando i container Docker come "nodi".

KinD è stato progettato principalmente per testare Kubernetes stesso, ma può essere utilizzato per lo sviluppo locale o per il CI.

Andiamo ora sul sito ufficiale di KinD, https://kind.sigs.k8s.io.

Così come specificato nella guida quickstart, eseguiamo l'installazione della CLI.

go install sigs.k8s.io/kind@v0.20.0

Creiamo il cluster KinD.

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
- role: worker
kind create cluster --config=cluster.yaml --name local

Installiamo un Ingress Controller, che servirà tra poco.

kubectl apply \
    -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

E aspettiamo che venga su.

kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=90s

E per provarlo, installiamo il seguente Echo Service.

kubectl apply \
    -f https://kind.sigs.k8s.io/examples/ingress/usage.yaml

Che possiamo testare in questo modo:

# should output "foo-app"
curl localhost/foo/hostname
echo -e '\n'
# should output "bar-app"
curl localhost/bar/hostname

Installare il Debug Pod tramite kubectl

Esiste una bellissima immagine con molti tool preinstallati per fare un po' di debugging all'interno del cluster.

A imperitura memoria, il repository dove si trova il Dockerfile è disponibile su GitHub.

Il comando per il suo utilizzo è il seguente:

kubectl run -it --rm --image=brix4dayz/swiss-army-knife --restart=Never debug

Installare la dashboard tramite manifest

Di Dashboard ne abbiamo già parlato nella slide di teoria, ora è il momento di mettere in pratica quello che sappiamo.

kubectl apply \
    -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

Ingress

kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  rules:
  - host: dashboard.kind.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 443
kubectl apply -f dashboard-ingress.yaml

The Admin: A Service Account's tale

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: admin-user-token
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/service-account.name: admin-user
kubectl apply -f dashboard-user.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
kubectl apply -f dashboard-user-crb.yaml

A questo punto copiamo il token generato che ci servirà per fare il login.

kubectl -n kubernetes-dashboard describe secret admin-user-token | grep 'token:' | awk '{print $2}'

Installare l'infrastruttura di monitoring tramite charts

Abbiamo già parlato di cosa sono le charts, di cosa è Helm e di come questi strumenti ci consentono di astrarre ancora di più il nostro sistema, abilitandoci alla progettazione di sistemi molto molto più complessi di come siamo sempre stati abituati progettare.

Come infrastruttura per il monitoraggio scegliamo una soluzione considerata ormai uno standard de facto nella community Kubernetes. Parlo dello stack Prometheus, Grafana. Come bonus installeremo anche lo stack PLG (Promtail, Loki, Grafana) per l'aggregazione e il monitoraggio dei log.

Esplorando gli stack PLG e PG

Prima di immergerci nell'installazione degli stack, rivisitiamo rapidamente ciascuno dei principali componenti. Una volta acquisita una comprensione fondamentale della responsabilità principale di ogni componente, possiamo immergerci nell'installazione sul nostro cluster Kubernetes.

Prometheus

Prometheus è un toolkit di monitoraggio e avviso di sistemi. Prometheus raccoglie e archivia le sue metriche in serie temporali, cioè le informazioni sulle metriche vengono archiviate con il timestamp in cui sono state registrate, insieme a coppie chiave-valore opzionali denominate etichette.

Promtail

Promtail è responsabile dell'inserimento dei dati in Loki. È implementato come DaemonSet, il che significa che un'istanza di Promtail viene eseguita su ogni nodo del tuo cluster Kubernetes. Legge periodicamente i log da tutti i container (stdout e stderr) in esecuzione su quel particolare nodo Kubernetes. Oltre a localizzare e leggere i flussi di log, Promtail può allegare etichette ai log prima di inviarli a Loki.

Loki

Loki è il cuore dello stack PLG. È un archivio dati ottimizzato per i log. A differenza di altri sistemi di aggregazione dei log, Loki non indicizza i messaggi di log. Al contrario, indicizza le etichette assegnate a ogni log. Possiamo interrogare i log archiviati in Loki utilizzando LogQL, un linguaggio di query ispirato a PromQL. Con LogQL, possiamo non solo semplicemente esaminare milioni di log in pochi secondi ma possiamo anche estrarre facilmente le metriche dai log.

Grafana

Grafana viene utilizzato per visualizzare metriche (provvenienti da Prometheus) e log (memorizzati in Loki). Loki e Prometheus si integrano perfettamente con Grafana. Possiamo creare dashboard individuali in Grafana in base ai log dell'applicazione e alle metriche calcolate.

Installazione

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
kubectl create ns monitoring
helm install prom prometheus-community/kube-prometheus-stack -n monitoring --values prometheus-values.yaml
kubectl wait --namespace monitoring \
  --for=condition=ready pod \
  --selector=release=prom \
  --timeout=90s
kubectl --namespace monitoring get pods -l "release=prom"
prometheus:
  prometheusSpec:
    serviceMonitorSelectorNilUsesHelmValues: false
    serviceMonitorSelector: {}
    serviceMonitorNamespaceSelector: {}

grafana:
  sidecar:
    dashboards:
      enabled: true
      defaultFolderName: "General"
      label: grafana_dashboard
      labelValue: "1"
      folderAnnotation: grafana_folder
      searchNamespace: ALL
      provider:
        foldersFromFilesStructure: true
    datasources:
      defaultDatasourceEnabled: true
  additionalDataSources:
    - name: Loki
      type: loki
      url: http://loki-loki-distributed-query-frontend.monitoring:3100

An entrance to the Monitoring appliance

kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: grafana-ingress
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: monitoring.kind.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prom-grafana
            port:
              number: 80
kubectl apply -f grafana-ingress.yaml

Accessing the holy secrets of the monitoring infrastructure

kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: prometheus.kind.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prom-kube-prometheus-stack-prometheus
            port:
              number: 9090
kubectl apply -f prometheus-ingress.yaml

The Bastard Son of Odin

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm upgrade --install promtail grafana/promtail -f promtail-values.yaml -n monitoring
helm upgrade --install loki grafana/loki-distributed -n monitoring
config:
  lokiAddress: "http://loki-loki-distributed-gateway/loki/api/v1/push"

Some dashboards (courtesy of @dotdc)

David Calvert è un SRE abbastanza attivo nella community che partecipa al progetto Prometheus come Open Source Contrinutor.

Prendiamo spunto dal suo ottimo gusto estetico (del resto è francese!) e dalle sue fantastiche dashboard per avere un sistema pronto all'uso.

git clone https://github.com/dotdc/grafana-dashboards-kubernetes.git
kubectl kustomize grafana-dashboards-kubernetes > grafana-dashboards.yaml
rm -rf grafana-dashboards-kubernetes
kubectl -n monitoring apply -f grafana-dashboards.yaml
rm grafana-dashboards.yaml

Qualche servizio di esempio e un po' lurking sul cluster

Come applicazione di esempio da installare ho scelto Spring PetClinic, un classico per chi, come me, viene dal mondo Java e ha un rapporto sano e sincero con Spring.

Di base è semplicemente un'applicazione distribuita, ci serve solo a scopo illustrativo di come poi il cluster possa essere utilizzato per finalità di sviluppo applicativo.

Spring PetClinic

Installiamo la PetClinic, facendo però attenzione a disabilitare WaveFront, una soluzione di monitoring in cloud offerta da VMware (che per ora non ci interessa).

Oltre a questo, dovremo anche modificare il Service di API Gateway perché piuttosto che pubblicare la porta su un LoadBalancer (che non abbiamo) espondendo quindi direttamente il servizio, lo proteggeremo facendolo passare da Ingress Controller.

Per ovviare alle problematiche esposte senza dover fare modifiche manualmente, dovendo entrare quindi nel merito del codice, applichiamo la patch che vi ho fornito.

git clone https://github.com/spring-petclinic/spring-petclinic-cloud.git
cd spring-petclinic-cloud
git apply ../Disabled_WaveFront_integration_Changed_API_Gateway_Service_Type_from_LoadBalancer_to_C.patch
cd spring-petclinic-cloud
kubectl apply -f k8s/init-namespace
kubectl apply -f k8s/init-services

La patch (per chi volesse vederla)

Subject: [PATCH] Disabled WaveFront integration; Changed API Gateway Service Type from LoadBalancer to ClusterIP
---
Index: k8s/init-services/04-wavefront.yaml
===================================================================
diff --git a/k8s/init-services/04-wavefront.yaml b/k8s/init-services/04-wavefront.yaml
deleted file mode 100644
--- a/k8s/init-services/04-wavefront.yaml       (revision ab8476cbc1e23f8f2a415e31fa69d26ca23e4704)
+++ /dev/null   (revision ab8476cbc1e23f8f2a415e31fa69d26ca23e4704)
@@ -1,66 +0,0 @@
-# Need to change YOUR_CLUSTER and YOUR_API_TOKEN accordingly
-
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  labels:
-    app: wavefront-proxy
-    name: wavefront-proxy
-  name: wavefront-proxy
-  namespace: spring-petclinic
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: wavefront-proxy
-  template:
-    metadata:
-      labels:
-        app: wavefront-proxy
-    spec:
-      containers:
-      - name: wavefront-proxy
-        image: wavefronthq/proxy:latest
-        imagePullPolicy: Always
-        env:
-        - name: WAVEFRONT_URL
-          valueFrom:
-             secretKeyRef:
-               name: wavefront
-               key: wavefront-url
-        - name: WAVEFRONT_TOKEN
-          valueFrom:
-             secretKeyRef:
-               name: wavefront
-               key: wavefront-api-token
-        # Uncomment the below lines to consume Zipkin/Istio traces
-        - name: WAVEFRONT_PROXY_ARGS
-          value: --traceZipkinListenerPorts 9411 --traceZipkinApplicationName spring-petclinic-k8s
-        ports:
-        - containerPort: 2878
-          protocol: TCP
-        # Uncomment the below lines to consume Zipkin/Istio traces
-        - containerPort: 9411
-          protocol: TCP
-        securityContext:
-          privileged: false
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: wavefront-proxy
-  labels:
-    app: wavefront-proxy
-  namespace: spring-petclinic
-spec:
-  ports:
-  - name: wavefront
-    port: 2878
-    protocol: TCP
-  # Uncomment the below lines to consume Zipkin/Istio traces
-  - name: http
-    port: 9411
-    targetPort: 9411
-    protocol: TCP
-  selector:
-    app: wavefront-proxy
Index: k8s/api-gateway-deployment.yaml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/k8s/api-gateway-deployment.yaml b/k8s/api-gateway-deployment.yaml
--- a/k8s/api-gateway-deployment.yaml   (revision ab8476cbc1e23f8f2a415e31fa69d26ca23e4704)
+++ b/k8s/api-gateway-deployment.yaml   (date 1687512570696)
@@ -45,8 +45,6 @@
         env:
         - name: SPRING_PROFILES_ACTIVE
           value: kubernetes
-        - name: MANAGEMENT_METRICS_EXPORT_WAVEFRONT_URI
-          value: proxy://wavefront-proxy.spring-petclinic.svc.cluster.local:2878
         ports:
         - containerPort: 8080
       restartPolicy: Always
Index: k8s/customers-service-deployment.yaml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/k8s/customers-service-deployment.yaml b/k8s/customers-service-deployment.yaml
--- a/k8s/customers-service-deployment.yaml     (revision ab8476cbc1e23f8f2a415e31fa69d26ca23e4704)
+++ b/k8s/customers-service-deployment.yaml     (date 1687512749759)
@@ -55,10 +55,7 @@
              secretKeyRef:
                name: customers-db-mysql
                key: mysql-root-password
-        - name: MANAGEMENT_METRICS_EXPORT_WAVEFRONT_URI
-          value: proxy://wavefront-proxy.spring-petclinic.svc.cluster.local:2878
         ports:
         - containerPort: 8080
-        resources: {}
       restartPolicy: Always
 status: {}
Index: k8s/vets-service-deployment.yaml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/k8s/vets-service-deployment.yaml b/k8s/vets-service-deployment.yaml
--- a/k8s/vets-service-deployment.yaml  (revision ab8476cbc1e23f8f2a415e31fa69d26ca23e4704)
+++ b/k8s/vets-service-deployment.yaml  (date 1687512585440)
@@ -54,10 +54,7 @@
              secretKeyRef:
                name: vets-db-mysql
                key: mysql-root-password
-        - name: MANAGEMENT_METRICS_EXPORT_WAVEFRONT_URI
-          value: proxy://wavefront-proxy.spring-petclinic.svc.cluster.local:2878
         ports:
         - containerPort: 8080
-        resources: {}
       restartPolicy: Always
 status: {}
Index: k8s/visits-service-deployment.yaml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/k8s/visits-service-deployment.yaml b/k8s/visits-service-deployment.yaml
--- a/k8s/visits-service-deployment.yaml        (revision ab8476cbc1e23f8f2a415e31fa69d26ca23e4704)
+++ b/k8s/visits-service-deployment.yaml        (date 1687512597292)
@@ -54,10 +54,7 @@
              secretKeyRef:
                name: visits-db-mysql
                key: mysql-root-password
-        - name: MANAGEMENT_METRICS_EXPORT_WAVEFRONT_URI
-          value: proxy://wavefront-proxy.spring-petclinic.svc.cluster.local:2878
         ports:
         - containerPort: 8080
-        resources: {}
       restartPolicy: Always
 status: {}
Index: k8s/init-services/05-api-gateway-service.yaml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/k8s/init-services/05-api-gateway-service.yaml b/k8s/init-services/05-api-gateway-service.yaml
--- a/k8s/init-services/05-api-gateway-service.yaml     (revision ab8476cbc1e23f8f2a415e31fa69d26ca23e4704)
+++ b/k8s/init-services/05-api-gateway-service.yaml     (date 1687512416412)
@@ -13,6 +13,5 @@
     targetPort: 8080
   selector:
     app: api-gateway
-  type: LoadBalancer
 status:
   loadBalancer: {}
Index: k8s/init-services/02-config-map.yaml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/k8s/init-services/02-config-map.yaml b/k8s/init-services/02-config-map.yaml
--- a/k8s/init-services/02-config-map.yaml      (revision ab8476cbc1e23f8f2a415e31fa69d26ca23e4704)
+++ b/k8s/init-services/02-config-map.yaml      (date 1687511667914)
@@ -16,11 +16,6 @@
         mime-types: application/json,text/css,application/javascript
         min-response-size: 2048
 
-    wavefront:
-      application:
-        name: spring-petclinic-k8s
-      freemium-account: true
-
     # Logging
     logging.level.org.springframework: INFO
 
@@ -50,7 +45,7 @@
           prometheus:
             enabled: true
           wavefront:
-            enabled: true
+            enabled: false
 
     customers-service-id: http://customers-service.spring-petclinic.svc.cluster.local:8080
     visits-service-id: http://vists-service.spring-petclinic.svc.cluster.local:8080

L'ingress di API Gateway

kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: petclinic-ingress
  namespace: spring-petclinic
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: petclinic.kind.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-gateway
            port:
              number: 80
kubectl apply -f petclinic-ingress.yaml

I database (MySQL)

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install vets-db-mysql bitnami/mysql --namespace spring-petclinic \
     --version 9.10.4 --set auth.database=service_instance_db
helm install visits-db-mysql bitnami/mysql --namespace spring-petclinic \
     --version 9.10.4 --set auth.database=service_instance_db
helm install customers-db-mysql bitnami/mysql --namespace spring-petclinic \
     --version 9.10.4 --set auth.database=service_instance_db

E finalmente arriva mamm… errrr, no. E finalmente arrivano i deployment

cd spring-petclinic-cloud
export REPOSITORY_PREFIX=springcommunity
./scripts/deployToKubernetes.sh
rm -rf spring-petclinic-cloud

Attiviamo il Grande Fratello

Due parole sui service monitor.

prometheus-custom-metrics-elements-1024x555.png

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: api-gateway
  namespace: spring-petclinic
spec:
  endpoints:
  - port: http
    path: '/actuator/prometheus'
  namespaceSelector:
    any: true
  selector:
    matchLabels:
      app: api-gateway
kubectl apply -f api-gateway-servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: customers-service
  namespace: spring-petclinic
spec:
  endpoints:
  - port: http
    path: '/actuator/prometheus'
  namespaceSelector:
    any: true
  selector:
    matchLabels:
      app: customers-service
kubectl apply -f customers-service-servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: vets-service
  namespace: spring-petclinic
spec:
  endpoints:
  - port: http
    path: '/actuator/prometheus'
  namespaceSelector:
    any: true
  selector:
    matchLabels:
      app: vets-service
kubectl apply -f vets-service-servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: visits-service
  namespace: spring-petclinic
spec:
  endpoints:
  - port: http
    path: '/actuator/prometheus'
  namespaceSelector:
    any: true
  selector:
    matchLabels:
      app: visits-service
kubectl apply -f visits-service-servicemonitor.yaml

Saluti

Grazie a tutti per essere arrivati fin qui!

thanks_for_watching.jpeg