2567 lines
63 KiB
Markdown
2567 lines
63 KiB
Markdown
# ItaliaDataCenter IDP
|
||
|
||
ItaliaDataCenter IDP è una piattaforma interna progettata per standardizzare e accelerare l'intero ciclo di vita delle applicazioni cloud-native: dalla fase di sviluppo e integrazione continua, fino al rilascio in ambiente Kubernetes, alla gestione operativa e al monitoraggio in produzione.
|
||
|
||
L'obiettivo principale e fornire ai team un ecosistema coerente e governato, in cui strumenti infrastrutturali, componenti applicativi e servizi di supporto collaborano in modo integrato. In questo contesto, la piattaforma abilita processi DevOps end-to-end, gestione sicura delle immagini container, provisioning dei database, orchestrazione dei workload, osservabilita avanzata, quality gate sul codice e supporto a scenari IoT/edge.
|
||
|
||
L'adozione di una IDP consente di ridurre la complessita operativa, migliorare la ripetibilita dei deploy, aumentare la sicurezza e semplificare la collaborazione tra team di sviluppo, operation e piattaforma.
|
||
|
||
Di seguito sono elencati i principali servizi, organizzati per categoria funzionale.
|
||
|
||
|
||
|
||
---
|
||
|
||
## Servizi Core
|
||
|
||
- **Haproxy**
|
||
Load Balancer ad alte prestazioni per la distribuzione del traffico tra i servizi del cluster.
|
||
|
||
- **Rancher**
|
||
Piattaforma di amministrazione centralizzata per la gestione di cluster Kubernetes, utenti, ruoli e policy.
|
||
|
||
- **CephCsi**
|
||
CSI Plugin che consente il provisioning dinamico di storage persistente su cluster Ceph esterni, garantendo scalabilità e affidabilità dei dati.
|
||
|
||
- **Gateway API**
|
||
Implementazione Kubernetes per la gestione avanzata del traffico in ingresso, integrata con NGINX per routing, sicurezza e osservabilità.
|
||
|
||
- **CertManager**
|
||
Gestione automatica del rilascio e rinnovo dei certificati SSL/TLS per i servizi esposti, integrato con ACME/Let's Encrypt.
|
||
|
||
---
|
||
|
||
## Servizi DevOps
|
||
|
||
- **Gitea**
|
||
Server Git self-hosted con gestione repository, issue tracking e pipeline CI/CD integrate.
|
||
|
||
- **Harbor**
|
||
Registry Docker enterprise per la gestione, la scansione e la firma delle immagini container.
|
||
|
||
- **Gitea Act Runner**
|
||
Runner per l'esecuzione automatizzata dei job CI/CD di Gitea, con supporto a workflow containerizzati e integrazione con registry e cluster.
|
||
|
||
- **Pipeline CICD**
|
||
Flussi automatizzati per build, test, security scan e deploy, utili a garantire rilasci rapidi, ripetibili e controllati.
|
||
|
||
- **Template infrastrutturali**
|
||
Modelli riutilizzabili per definire risorse applicative e infrastrutturali in modo standard, versionato e coerente tra ambienti.
|
||
|
||
---
|
||
|
||
## Servizi Database
|
||
|
||
- **CloudNativePG**
|
||
Operator Kubernetes per il deploy e la gestione di cluster PostgreSQL resilienti e scalabili.
|
||
|
||
- **MySql Operator**
|
||
Operator per la gestione automatizzata di cluster MySQL su Kubernetes.
|
||
|
||
- **Redis**
|
||
Database in-memory ad alte prestazioni per caching e gestione di dati temporanei.
|
||
|
||
- **InfluxDB**
|
||
Database ottimizzato per la gestione di serie temporali, ideale per metriche, eventi e dati IoT.
|
||
|
||
- **MongoDB**
|
||
Database NoSQL documentale adatto a workload ad alta flessibilita, applicazioni distribuite e gestione di dati semi-strutturati.
|
||
|
||
- **DbGate**
|
||
Interfaccia grafica web per la gestione e l’esplorazione di database SQL.
|
||
|
||
---
|
||
|
||
## Servizi Applicativi / Utility
|
||
|
||
- **NodeRed**
|
||
Interfaccia grafica per la definizione di flussi IoT, automazione e integrazione di dispositivi.
|
||
|
||
- **Grafana**
|
||
Dashboard avanzate per la visualizzazione di metriche, log e dati di osservabilità.
|
||
|
||
- **Prometheus**
|
||
Sistema di monitoring e alerting open-source per la raccolta di metriche, query time-series e integrazione con dashboard e regole di allarme.
|
||
|
||
- **SonarQube**
|
||
Analisi statica del codice e controllo della qualità per progetti software.
|
||
|
||
- **KubeEdge**
|
||
Estensione Kubernetes per la gestione e l’orchestrazione di device IoT distribuiti.
|
||
|
||
- **Knative**
|
||
Piattaforma serverless su Kubernetes per eseguire workload event-driven, con autoscaling fino a zero e gestione semplificata del traffic routing.
|
||
|
||
- **Locust**
|
||
Strumento di load testing open-source per simulare utenti concorrenti, misurare prestazioni applicative e individuare colli di bottiglia.
|
||
|
||
---
|
||
|
||
## Flusso Tipico
|
||
|
||
1. **Gestione cluster e risorse** tramite Rancher, Gateway API e CephCsi.
|
||
2. **Sviluppo, versionamento e automazione DevOps** con Gitea, Gitea Act Runner, pipeline CI/CD e template infrastrutturali per build, test e deploy standardizzati.
|
||
3. **Gestione immagini container sicura** con Harbor.
|
||
4. **Provisioning e gestione database** tramite operator dedicati (PostgreSQL, MySQL, Redis, InfluxDB, MongoDB) e strumenti di amministrazione come DbGate.
|
||
5. **Deployment serverless e workload event-driven** con Knative, grazie ad autoscaling dinamico e routing del traffico.
|
||
6. **Monitoraggio e visualizzazione dati e metriche** con Prometheus, Grafana e NodeRed.
|
||
7. **Performance e load testing** con Locust, per validare la scalabilita dei servizi e individuare colli di bottiglia.
|
||
8. **Sicurezza** garantita da CertManager e SonarQube.
|
||
9. **Gestione device IoT e edge computing** con KubeEdge.
|
||
|
||
---
|
||
|
||
## Tabella Tool
|
||
|
||
| tool | descrizione | url | user | password |
|
||
| --- | --- | --- | --- | --- |
|
||
| Rancher | Piattaforma di amministrazione centralizzata per cluster Kubernetes. | https://k8s.italiatacenter.com | TBD | TBD |
|
||
| Gitea | Server Git self-hosted con repository e issue tracking. | https://git.italiatacenter.com | admin | **************** |
|
||
| Harbor | Registry Docker enterprise con scansione e firma immagini. | https://harbor.italiatacenter.com | admin | **************** |
|
||
| InfluxDB | Database time-series per metriche, eventi e dati IoT. | https://influxdb.italiatacenter.com | admin | c**************** |
|
||
| DbGate | Interfaccia web per la gestione e l'esplorazione di database SQL. | https://dbgate.italiatacenter.com | n/a | n/a |
|
||
| NodeRed | Interfaccia grafica per flussi IoT e automazione. | https://nodered.italiatacenter.com | admin | **************** |
|
||
| Grafana | Dashboard per visualizzazione di metriche, log e osservabilita. | https://grafana.italiatacenter.com | admin | **************** |
|
||
| SonarQube | Analisi statica del codice e controllo qualita software. | https://sonarqube.italiatacenter.com | sonarqube | **************** |
|
||
| Locust | Strumento di load testing per simulare utenti concorrenti. | n/a| TBD | TBD |
|
||
|
||
Questa piattaforma consente di accelerare il ciclo di vita delle applicazioni, garantendo sicurezza, scalabilità e automazione in ogni fase del processo di sviluppo e gestione.
|
||
|
||
# Installazione Piattaforma – Istruzioni
|
||
|
||
> **Nota**: Documento generato a partire dal file sorgente fornito (`doc.txt`). Le sezioni e i blocchi di codice sono mantenuti fedeli all'originale. Se desideri, posso rifinire l'impaginazione (sottosezioni, sommario, evidenziazione dei comandi per `bash`, `yaml`, ecc.).
|
||
|
||
```yaml
|
||
---
|
||
|
||
Configurazione iniziale:
|
||
|
||
master node
|
||
3 server con queste caratteristiche:
|
||
2 vcpu, 4gb ram 20gb HD Ubuntu 25.10
|
||
|
||
Worker node
|
||
3 server con queste caratteristiche:
|
||
2 vcpu, 4gb ram 50gb HD Ubuntu 25.10
|
||
|
||
Load Balancer (HAproxy)
|
||
1 server con queste caratteristiche:
|
||
1 vcpu, 1gb ram 10gb HD Ubuntu 25.10
|
||
indirizzo pubblico definito sul gatewa ruotato sul Balancer, porte aperte:
|
||
80,443 per servizi applicativi
|
||
10000,10002,10003,10004 per kubeedge
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
Installazione:
|
||
|
||
Su ogni nodo master e worker
|
||
|
||
```bash
|
||
# 1. Aggiorna OS
|
||
sudo apt update && sudo apt -y upgrade # Ubuntu/Debian
|
||
sudo apt install -y iputils-ping
|
||
sudo apt install -y telnetd telnet
|
||
sudo snap install -y kubectl --classic
|
||
sudo apt install -y iptables
|
||
sudo apt install -y iptables-persistent
|
||
|
||
# 2. Disabilita SWAP (necessario)
|
||
sudo swapoff -a
|
||
sudo sed -i.bak '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
|
||
|
||
# 3. Config kernel requisiti Kubernetes (es. bridge netfilter)
|
||
cat <<EOF | sudo tee /etc/sysctl.d/99-k8s.conf
|
||
net.bridge.bridge-nf-call-iptables = 1
|
||
net.ipv4.ip_forward = 1
|
||
net.bridge.bridge-nf-call-ip6tables = 1
|
||
fs.inotify.max_user_watches = 524288
|
||
EOF
|
||
sudo sysctl --system
|
||
|
||
# 4. Sincronizza orologio
|
||
sudo apt install -y chrony
|
||
sudo systemctl enable --now chrony
|
||
|
||
#installa yq
|
||
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
|
||
sudo chmod a+x /usr/local/bin/yq
|
||
# 5. Imposta hostname (es.)
|
||
#sudo hostnamectl set-hostname $1
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
Sul master 1
|
||
```bash
|
||
# 1. Installa RKE2 (script ufficial)
|
||
curl -sfL https://get.rke2.io | sh -
|
||
sudo systemctl enable rke2-server.service
|
||
|
||
# 2. Crea config (personalizza token e tls-san se serve)
|
||
sudo mkdir -p /etc/rancher/rke2
|
||
sudo tee /etc/rancher/rke2/config.yaml > /dev/null <<EOF
|
||
|
||
# RKE2 Server Configuration - First Master Node
|
||
write-kubeconfig-mode: "0644"
|
||
|
||
# CRITICAL: Add all possible API server access points to the certificate
|
||
tls-san:
|
||
- "POC-Kube-Balancer"
|
||
- "10.20.1.100"
|
||
- "POC-Master0"
|
||
- "10.20.1.101"
|
||
- "POC-Master1"
|
||
- "10.20.1.102"
|
||
- "POC-Master2"
|
||
- "10.20.1.103"
|
||
- "POC-Worker0"
|
||
- "10.20.1.104"
|
||
- "POC-Worker1"
|
||
- "10.20.1.105"
|
||
- "POC-Worker2"
|
||
- "10.20.1.106"
|
||
|
||
|
||
# Network configuration
|
||
#cluster-cidr: "10.42.64.0/18"
|
||
#service-cidr: "10.42.0.0/18"
|
||
#cluster-dns: "10.42.0.10"
|
||
|
||
# Security hardening
|
||
#profile: "cis-1.6"
|
||
selinux: true
|
||
secrets-encryption: true
|
||
|
||
# Node configuration
|
||
node-taint:
|
||
- "CriticalAddonsOnly=true:NoExecute"
|
||
|
||
ingress-controller: none
|
||
|
||
EOF
|
||
|
||
# 3. Avvia RKE2 server
|
||
sudo systemctl start rke2-server
|
||
|
||
# Attendi che i pod kube-system siano up (sul master 1)
|
||
|
||
#installa kubectl
|
||
curl -LO https://dl.k8s.io/release/v1.35.0/bin/linux/amd64/kubectl
|
||
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||
|
||
|
||
mkdir /root/.kube
|
||
cp /etc/rancher/rke2/rke2.yaml /root/.kube/config
|
||
echo "MASTER TOKEN TO COPY"
|
||
cat /var/lib/rancher/rke2/server/node-token
|
||
|
||
sui master 2 e 3:
|
||
# 1. Installa RKE2 (script ufficial)
|
||
curl -sfL https://get.rke2.io | sh -
|
||
sudo systemctl enable rke2-server.service
|
||
|
||
# 2. Crea config (personalizza token e tls-san se serve)
|
||
sudo mkdir -p /etc/rancher/rke2
|
||
sudo tee /etc/rancher/rke2/config.yaml > /dev/null <<EOF
|
||
|
||
# RKE2 Server Configuration - Additional Master
|
||
server: https://POC-Master0:9345 # Direct connection for initial join
|
||
token: "K10b8b252de84e5aab8bc1d2a8e4aad3e329ee84d638892b8638de0260b7cb8212a::server:34b189ab7b91fc924500ba0b3608b80b"
|
||
write-kubeconfig-mode: "0644"
|
||
|
||
# Same TLS SANs as master-1 - consistency is crucial!
|
||
tls-san:
|
||
- "POC-Kube-Balancer"
|
||
- "10.20.1.100"
|
||
- "POC-Master0"
|
||
- "10.20.1.101"
|
||
- "POC-Master1"
|
||
- "10.20.1.102"
|
||
- "POC-Master2"
|
||
- "10.20.1.103"
|
||
- "POC-Worker0"
|
||
- "10.20.1.104"
|
||
- "POC-Worker1"
|
||
- "10.20.1.105"
|
||
- "POC-Worker2"
|
||
- "10.20.1.106"
|
||
|
||
# Identical network configuration
|
||
#cluster-cidr: "10.42.64.0/18"
|
||
#service-cidr: "10.42.0.0/18"
|
||
#cluster-dns: "10.42.0.10"
|
||
|
||
# Same backup and security settings
|
||
#profile: "cis-1.6"
|
||
selinux: true
|
||
secrets-encryption: true
|
||
|
||
# Node configuration
|
||
node-taint:
|
||
- "CriticalAddonsOnly=true:NoExecute"
|
||
|
||
ingress-controller: none
|
||
|
||
EOF
|
||
|
||
# 3. Avvia RKE2 server
|
||
sudo systemctl start rke2-server
|
||
|
||
curl -LO https://dl.k8s.io/release/v1.35.0/bin/linux/amd64/kubectl
|
||
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||
|
||
mkdir /root/.kube
|
||
cp /etc/rancher/rke2/rke2.yaml /root/.kube/config
|
||
|
||
|
||
#installa helm
|
||
# scarica helm (esempio Linux AMD64)
|
||
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||
chmod 700 get_helm.sh
|
||
./get_helm.sh
|
||
|
||
# verifica
|
||
helm version
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
su ogni nodo worker:
|
||
```bash
|
||
sudo apt install open-iscsi
|
||
systemctl enable open-iscsi
|
||
systemctl enable iscsid
|
||
systemctl restart iscsid.service
|
||
# Install RKE2 agent
|
||
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sudo sh -
|
||
|
||
# Create configuration
|
||
sudo mkdir -p /etc/rancher/rke2
|
||
|
||
# Worker configuration - connects through the load balancer!
|
||
sudo tee /etc/rancher/rke2/config.yaml > /dev/null << EOF
|
||
# RKE2 Agent Configuration
|
||
server: https://POC-Kube-Balancer:9345 # Using the main load balancer!
|
||
token: "K10b8b252de84e5aab8bc1d2a8e4aad3e329ee84d638892b8638de0260b7cb8212a::server:34b189ab7b91fc924500ba0b3608b80b"
|
||
|
||
# Node labels for workload scheduling
|
||
node-label:
|
||
- "node.kubernetes.io/worker=true"
|
||
- "workload-type=general"
|
||
|
||
# Optional: Reserve resources for system stability
|
||
# kubelet-arg:
|
||
# - "system-reserved=cpu=500m,memory=1Gi"
|
||
# - "kube-reserved=cpu=500m,memory=1Gi"
|
||
EOF
|
||
|
||
# Start the worker
|
||
sudo systemctl enable rke2-agent.service
|
||
sudo systemctl start rke2-agent.service
|
||
|
||
# Check status
|
||
sudo systemctl status rke2-agent.service
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
sul Balancer:
|
||
```bash
|
||
sudo apt update && sudo apt install -y haproxy
|
||
|
||
sudo tee /etc/haproxy/haproxy.cfg > /dev/null <<'EOF'
|
||
global
|
||
log /dev/log local0
|
||
maxconn 20000
|
||
tune.bufsize 16384
|
||
# SSL configuration for future HTTPS endpoints
|
||
ca-base /etc/ssl/certs
|
||
crt-base /etc/ssl/private
|
||
|
||
# Modern SSL configuration - only secure protocols
|
||
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
||
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
|
||
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
|
||
|
||
defaults
|
||
log global
|
||
mode http
|
||
option httplog
|
||
option dontlognull
|
||
timeout connect 5000
|
||
timeout client 50000
|
||
timeout server 50000
|
||
errorfile 400 /etc/haproxy/errors/400.http
|
||
errorfile 403 /etc/haproxy/errors/403.http
|
||
errorfile 408 /etc/haproxy/errors/408.http
|
||
errorfile 500 /etc/haproxy/errors/500.http
|
||
errorfile 502 /etc/haproxy/errors/502.http
|
||
errorfile 503 /etc/haproxy/errors/503.http
|
||
errorfile 504 /etc/haproxy/errors/504.http
|
||
|
||
frontend rke2_registration_frontend
|
||
bind *:9345
|
||
mode tcp
|
||
option tcplog
|
||
default_backend rke2_registration_backend
|
||
|
||
#---------------------------------------------------------------------
|
||
# RKE2 Supervisor/Registration Backend
|
||
# Round-robin between masters for node registration
|
||
#---------------------------------------------------------------------
|
||
backend rke2_registration_backend
|
||
mode tcp
|
||
balance roundrobin
|
||
option tcp-check
|
||
# Health check ensures we only send traffic to healthy masters
|
||
server POC-Master0 POC-Master0:9345 check
|
||
server POC-Master1 POC-Master1:9345 check
|
||
server POC-Master2 POC-Master2:9345 check
|
||
|
||
#---------------------------------------------------------------------
|
||
# Kubernetes API Frontend
|
||
# This is where kubectl commands and apps connect
|
||
#---------------------------------------------------------------------
|
||
frontend k8s_api_frontend
|
||
bind *:6443
|
||
mode tcp
|
||
option tcplog
|
||
default_backend k8s_api_backend
|
||
|
||
#---------------------------------------------------------------------
|
||
# Kubernetes API Backend
|
||
# Distributes API requests across all masters
|
||
#---------------------------------------------------------------------
|
||
backend k8s_api_backend
|
||
mode tcp
|
||
balance roundrobin
|
||
option tcp-check
|
||
# TCP health checks on the API port
|
||
server POC-Master0 POC-Master0:6443 check
|
||
server POC-Master1 POC-Master1:6443 check
|
||
server POC-Master2 POC-Master2:6443 check
|
||
|
||
#---------------------------------------------------------------------
|
||
# Statistics Page (Optional but useful for monitoring)
|
||
#---------------------------------------------------------------------
|
||
listen stats
|
||
bind *:8080
|
||
stats enable
|
||
stats uri /stats
|
||
stats refresh 30s
|
||
stats show-node
|
||
stats auth admin:admin # Change this password!
|
||
|
||
#---------------------------------------------------------------------
|
||
# nginx ingress
|
||
# This is where kubectl commands and apps connect
|
||
#---------------------------------------------------------------------
|
||
frontend nginx_frontend_443
|
||
bind *:443
|
||
mode tcp
|
||
option tcplog
|
||
default_backend nginx_backend
|
||
|
||
frontend nginx_frontend_80
|
||
bind *:80
|
||
mode http
|
||
http-response set-header Access-Control-Allow-Origin %[hdr(origin)]
|
||
default_backend nginx_backend_http
|
||
#---------------------------------------------------------------------
|
||
# Kubernetes API Backend
|
||
# Distributes API requests across all masters
|
||
#---------------------------------------------------------------------
|
||
backend nginx_backend
|
||
mode tcp
|
||
balance roundrobin
|
||
option tcp-check
|
||
# TCP health checks on the API port
|
||
server POC-Master0 POC-Master0:30864 check
|
||
server POC-Master1 POC-Master1:30864 check
|
||
server POC-Master2 POC-Master2:30864 check
|
||
|
||
backend nginx_backend_http
|
||
mode http
|
||
balance roundrobin
|
||
# TCP health checks on the API port
|
||
server POC-Master0 POC-Master0:30864 check ssl verify none
|
||
server POC-Master1 POC-Master1:30864 check ssl verify none
|
||
server POC-Master2 POC-Master2:30864 check ssl verify none
|
||
EOF
|
||
|
||
sudo systemctl enable --now haproxy
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
Installazione componenti k8s
|
||
|
||
|
||
|
||
- **Rancher**
|
||
```bash
|
||
helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
|
||
kubectl create namespace cattle-system
|
||
|
||
helm install rancher rancher-stable/rancher \
|
||
--namespace cattle-system \
|
||
--set hostname=k8s.italiadatacenter.com \
|
||
--set bootstrapPassword=*****
|
||
|
||
|
||
patch gateway add under listener:
|
||
- allowedRoutes:
|
||
namespaces:
|
||
from: cattle-system
|
||
hostname: k8s.italiadatacenter.com
|
||
name: k8s-https
|
||
port: 443
|
||
protocol: HTTPS
|
||
tls:
|
||
certificateRefs:
|
||
- group: ""
|
||
kind: Secret
|
||
name: k8s-secret
|
||
mode: Terminate
|
||
- allowedRoutes:
|
||
namespaces:
|
||
from: cattle-system
|
||
hostname: k8s.italiadatacenter.com
|
||
name: k8s-http
|
||
port: 80
|
||
protocol: HTTP
|
||
|
||
creazione httproute:
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: rancher
|
||
namespace: cattle-system
|
||
spec:
|
||
hostnames:
|
||
- k8s.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: rancher
|
||
port: 80
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **CephCsi**
|
||
```bash
|
||
cat <<EOF > csi-config-map.yaml
|
||
---
|
||
apiVersion: v1
|
||
kind: ConfigMap
|
||
data:
|
||
config.json: |-
|
||
[
|
||
{
|
||
"clusterID": "004ee854-86cc-4ddc-b7d6-75e4fe962296",
|
||
"monitors": [
|
||
"72.20.1.33:6789",
|
||
"72.20.1.34:6789",
|
||
"72.20.1.35:6789"
|
||
]
|
||
}
|
||
]
|
||
metadata:
|
||
name: ceph-csi-config
|
||
EOF
|
||
kubectl apply -f csi-config-map.yaml
|
||
|
||
|
||
cat <<EOF > csi-kms-config-map.yaml
|
||
---
|
||
apiVersion: v1
|
||
kind: ConfigMap
|
||
data:
|
||
config.json: |-
|
||
{}
|
||
metadata:
|
||
name: ceph-csi-encryption-kms-config
|
||
EOF
|
||
kubectl apply -f csi-kms-config-map.yaml
|
||
|
||
|
||
cat <<EOF > ceph-config-map.yaml
|
||
---
|
||
apiVersion: v1
|
||
kind: ConfigMap
|
||
data:
|
||
ceph.conf: |
|
||
[global]
|
||
auth_cluster_required = cephx
|
||
auth_service_required = cephx
|
||
auth_client_required = cephx
|
||
# keyring is a required key and its value should be empty
|
||
keyring: |
|
||
metadata:
|
||
name: ceph-config
|
||
EOF
|
||
kubectl apply -f ceph-config-map.yaml
|
||
|
||
|
||
|
||
cat <<EOF > csi-rbd-secret.yaml
|
||
---
|
||
apiVersion: v1
|
||
kind: Secret
|
||
metadata:
|
||
name: csi-rbd-secret
|
||
namespace: default
|
||
stringData:
|
||
userID: kubernetes
|
||
userKey: AQD2zo5pm8aZIRAAPzWS+dROeX7iJtv5EukfKA==
|
||
EOF
|
||
|
||
|
||
|
||
|
||
|
||
|
||
kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-provisioner-rbac.yaml
|
||
kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-nodeplugin-rbac.yaml
|
||
|
||
wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-rbdplugin-provisioner.yaml
|
||
kubectl apply -f csi-rbdplugin-provisioner.yaml
|
||
wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-rbdplugin.yaml
|
||
kubectl apply -f csi-rbdplugin.yaml
|
||
|
||
------- TEST-----
|
||
|
||
cat <<EOF > csi-rbd-sc.yaml
|
||
---
|
||
apiVersion: storage.k8s.io/v1
|
||
kind: StorageClass
|
||
metadata:
|
||
name: csi-rbd-sc
|
||
provisioner: rbd.csi.ceph.com
|
||
parameters:
|
||
clusterID: 004ee854-86cc-4ddc-b7d6-75e4fe962296
|
||
pool: k8s-rbd
|
||
imageFeatures: layering
|
||
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
|
||
csi.storage.k8s.io/provisioner-secret-namespace: default
|
||
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
|
||
csi.storage.k8s.io/controller-expand-secret-namespace: default
|
||
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
|
||
csi.storage.k8s.io/node-stage-secret-namespace: default
|
||
reclaimPolicy: Delete
|
||
allowVolumeExpansion: true
|
||
mountOptions:
|
||
- discard
|
||
EOF
|
||
kubectl apply -f csi-rbd-sc.yaml
|
||
|
||
|
||
cat <<EOF > raw-block-pvc.yaml
|
||
---
|
||
apiVersion: v1
|
||
kind: PersistentVolumeClaim
|
||
metadata:
|
||
name: raw-block-pvc
|
||
spec:
|
||
accessModes:
|
||
- ReadWriteOnce
|
||
volumeMode: Block
|
||
resources:
|
||
requests:
|
||
storage: 1Gi
|
||
storageClassName: csi-rbd-sc
|
||
EOF
|
||
kubectl apply -f raw-block-pvc.yaml
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **Gateway API**
|
||
```bash
|
||
# Install Gateway API CRDs
|
||
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml
|
||
|
||
kubectl get crd | grep gateway
|
||
|
||
kubectl create namespace nginx-gateway
|
||
|
||
kubectl apply --server-side -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v2.4.1/deploy/crds.yaml
|
||
kubectl apply -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v2.4.1/deploy/nodeport/deploy.yaml
|
||
|
||
---- Gatway configuration ----
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: Gateway
|
||
metadata:
|
||
name: main-gateway
|
||
namespace: nginx-gateway
|
||
annotations:
|
||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||
spec:
|
||
gatewayClassName: nginx
|
||
listeners:
|
||
- allowedRoutes:
|
||
namespaces:
|
||
from: All
|
||
hostname: poc1.italiadatacenter.com
|
||
name: https
|
||
port: 443
|
||
protocol: HTTPS
|
||
tls:
|
||
certificateRefs:
|
||
- group: ""
|
||
kind: Secret
|
||
name: poc1-secret
|
||
mode: Terminate
|
||
- allowedRoutes:
|
||
namespaces:
|
||
from: All
|
||
hostname: poc1.italiadatacenter.com
|
||
name: http
|
||
port: 80
|
||
protocol: HTTP
|
||
|
||
|
||
----- Nodeport service ---
|
||
kubectl apply -f - <<EOF
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
labels:
|
||
app.kubernetes.io/instance: nginx-gateway
|
||
app.kubernetes.io/managed-by: nginx-gateway-nginx
|
||
app.kubernetes.io/name: main-gateway-nginx
|
||
gateway.networking.k8s.io/gateway-name: main-gateway
|
||
name: gateway-nginx-nodeport
|
||
namespace: nginx-gateway
|
||
spec:
|
||
ports:
|
||
- name: port-80
|
||
nodePort: 30864
|
||
port: 80
|
||
protocol: TCP
|
||
targetPort: 80
|
||
- name: port-443
|
||
nodePort: 30874
|
||
port: 443
|
||
protocol: TCP
|
||
targetPort: 443
|
||
selector:
|
||
app.kubernetes.io/instance: nginx-gateway
|
||
app.kubernetes.io/managed-by: nginx-gateway-nginx
|
||
app.kubernetes.io/name: main-gateway-nginx
|
||
gateway.networking.k8s.io/gateway-name: main-gateway
|
||
sessionAffinity: None
|
||
type: NodePort
|
||
EOF
|
||
|
||
----- httproute ---
|
||
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: demo-route
|
||
namespace: demo-apps
|
||
spec:
|
||
hostnames:
|
||
- poc2.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: app-v1
|
||
port: 80
|
||
|
||
--- work area
|
||
|
||
kubectl edit gateway main-gateway -n nginx-gateway
|
||
|
||
add
|
||
|
||
- allowedRoutes:
|
||
namespaces:
|
||
from: cattle-system
|
||
hostname: k8s.italiadatacenter.com
|
||
name: k8s-https
|
||
port: 443
|
||
protocol: HTTPS
|
||
tls:
|
||
certificateRefs:
|
||
- group: ""
|
||
kind: Secret
|
||
name: k8s-secret
|
||
mode: Terminate
|
||
- allowedRoutes:
|
||
namespaces:
|
||
from: cattle-system
|
||
hostname: k8s.italiadatacenter.com
|
||
name: k8s-http
|
||
port: 80
|
||
protocol: HTTP
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **CertManager**
|
||
```bash
|
||
kubectl create namespace cert-manager
|
||
helm repo add jetstack https://charts.jetstack.io
|
||
helm repo update
|
||
|
||
# Install versione consigliata
|
||
helm install cert-manager jetstack/cert-manager \
|
||
--namespace cert-manager \
|
||
--set installCRDs=true \
|
||
--wait
|
||
# Verifica
|
||
kubectl -n cert-manager get pods
|
||
|
||
Crea cluster issuer per let’s Encrypt:
|
||
apiVersion: cert-manager.io/v1
|
||
kind: ClusterIssuer
|
||
metadata:
|
||
name: letsencrypt-prod
|
||
spec:
|
||
acme:
|
||
email: <insert a valid email-address>
|
||
privateKeySecretRef:
|
||
name: letsencrypt-production-key
|
||
server: https://acme-v02.api.letsencrypt.org/directory
|
||
solvers:
|
||
- http01:
|
||
gatewayHTTPRoute:
|
||
parentRefs:
|
||
- group: gateway.networking.k8s.io
|
||
kind: Gateway
|
||
name: main-gateway
|
||
namespace: nginx-gateway
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
```yaml
|
||
---
|
||
```
|
||
|
||
## Servizi DevOps
|
||
|
||
-- **db devops**
|
||
|
||
```yaml
|
||
apiVersion: v1
|
||
kind: Secret
|
||
metadata:
|
||
name: pg-app-user
|
||
namespace: demo-apps
|
||
type: kubernetes.io/basic-auth
|
||
stringData:
|
||
username: devops
|
||
password: ****************
|
||
---
|
||
apiVersion: postgresql.cnpg.io/v1
|
||
kind: Cluster
|
||
metadata:
|
||
name: pg-devops
|
||
namespace: devops
|
||
spec:
|
||
instances: 3
|
||
|
||
storage:
|
||
size: 1Gi
|
||
storageClass: csi-rbdfs-sc
|
||
|
||
walStorage:
|
||
storageClass: csi-rbdfs-sc
|
||
size: 1Gi
|
||
|
||
bootstrap:
|
||
initdb:
|
||
database: devops
|
||
owner: admin
|
||
secret:
|
||
name: pg-app-user
|
||
|
||
postgresql:
|
||
parameters:
|
||
max_connections: "300"
|
||
shared_buffers: "1GB"
|
||
|
||
resources:
|
||
requests:
|
||
cpu: "500m"
|
||
memory: "1Gi"
|
||
limits:
|
||
cpu: "2"
|
||
memory: "2Gi"
|
||
```
|
||
|
||
- **Gitea**
|
||
|
||
```bash
|
||
kubectl cnpg psql pg-devops -n devops
|
||
|
||
CREATE DATABASE giteadb;
|
||
CREATE USER gitea WITH PASSWORD '****************';
|
||
GRANT ALL PRIVILEGES ON DATABASE giteadb TO gitea;
|
||
ALTER DATABASE giteadb OWNER TO gitea;
|
||
|
||
helm repo add gitea https://dl.gitea.io/charts/
|
||
helm repo update
|
||
|
||
|
||
kubectl create namespace gitea
|
||
|
||
cat <<EOF |cat >values.yaml -
|
||
replicaCount: 1
|
||
|
||
image:
|
||
repository: gitea/gitea
|
||
tag: 1.22.0
|
||
pullPolicy: IfNotPresent
|
||
|
||
strategy:
|
||
type: Recreate
|
||
|
||
service:
|
||
http:
|
||
type: ClusterIP
|
||
port: 3000
|
||
ssh:
|
||
type: ClusterIP
|
||
port: 22
|
||
|
||
redis-cluster:
|
||
enabled: false
|
||
|
||
redis:
|
||
enabled: false
|
||
|
||
ingress:
|
||
enabled: false
|
||
|
||
persistence:
|
||
enabled: true
|
||
storageClass: csi-rbdfs-sc
|
||
size: 10Gi
|
||
|
||
postgresql:
|
||
enabled: false
|
||
|
||
postgresql-ha:
|
||
enabled: false
|
||
|
||
gitea:
|
||
admin:
|
||
username: gitadmin
|
||
password: ****************
|
||
email: gitadmin@italiadatacenter.com
|
||
|
||
config:
|
||
database:
|
||
DB_TYPE: postgres
|
||
HOST: pg-devops-rw.devops.svc:5432
|
||
NAME: giteadb
|
||
USER: gitea
|
||
PASSWD: ****************
|
||
SSL_MODE: disable
|
||
|
||
server:
|
||
ROOT_URL: https://git.italiadatacenter.com/
|
||
SSH_DOMAIN: git.italiadatacenter.com
|
||
SSH_PORT: 22
|
||
|
||
security:
|
||
INSTALL_LOCK: true
|
||
|
||
EOF
|
||
|
||
helm upgrade --install gitea gitea-charts/gitea --namespace gitea -f values.yaml
|
||
|
||
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: gitea
|
||
namespace: gitea
|
||
spec:
|
||
hostnames:
|
||
- git.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: gitea-http
|
||
port: 3000
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **Harbor**
|
||
```bash
|
||
#HARBOR
|
||
kubectl create namespace harbor
|
||
|
||
helm repo add harbor https://helm.goharbor.io
|
||
helm repo update
|
||
|
||
cat <<EOF | cat > harbor-cert.yaml -
|
||
apiVersion: cert-manager.io/v1
|
||
kind: Certificate
|
||
metadata:
|
||
name: harbor-tls
|
||
namespace: harbor
|
||
spec:
|
||
secretName: harbor-tls
|
||
issuerRef:
|
||
name: letsencrypt-prod
|
||
kind: ClusterIssuer
|
||
dnsNames:
|
||
- harbor.italiadatacenter.com
|
||
|
||
EOF
|
||
|
||
kubectl apply -f harbor-cert.yaml
|
||
|
||
|
||
|
||
|
||
cat <<EOF | cat > harborvalues.yaml -
|
||
# -----------------------
|
||
# EXPOSURE
|
||
# -----------------------
|
||
expose:
|
||
# Set how to expose the service. Set the type as "ingress", "clusterIP", "nodePort" or "loadBalancer"
|
||
# and fill the information in the corresponding section
|
||
type: clusterIP
|
||
externalURL: https://harbor.italiadatacenter.com
|
||
|
||
# -----------------------
|
||
# ADMIN
|
||
# -----------------------
|
||
harborAdminPassword: "****************"
|
||
|
||
# -----------------------
|
||
# PERSISTENCE
|
||
# -----------------------
|
||
persistence:
|
||
enabled: true
|
||
persistentVolumeClaim:
|
||
registry:
|
||
storageClass: csi-rbdfs-sc
|
||
size: 50Gi
|
||
jobservice:
|
||
storageClass: csi-rbdfs-sc
|
||
size: 2Gi
|
||
trivy:
|
||
storageClass: csi-rbdfs-sc
|
||
size: 2Gi
|
||
|
||
# -----------------------
|
||
# POSTGRESQL (EXTERNAL)
|
||
# -----------------------
|
||
database:
|
||
type: external
|
||
external:
|
||
host: pg-devops-rw.devops.svc
|
||
port: 5432
|
||
username: harbor
|
||
password: "****************"
|
||
database: registry
|
||
sslmode: require
|
||
|
||
# -----------------------
|
||
# REDIS (EXTERNAL)
|
||
# -----------------------
|
||
redis:
|
||
type: external
|
||
external:
|
||
addr: redis.redis.svc.cluster.local:6379
|
||
password: "****************"
|
||
database: 0
|
||
|
||
# -----------------------
|
||
# DISABLE INTERNAL SERVICES
|
||
# -----------------------
|
||
postgresql:
|
||
enabled: false
|
||
|
||
redisInternal:
|
||
enabled: false
|
||
|
||
# -----------------------
|
||
# COMPONENTS
|
||
# -----------------------
|
||
trivy:
|
||
enabled: true
|
||
|
||
metrics:
|
||
enabled: false
|
||
EOF
|
||
|
||
kubectl cnpg psql pg-devops -n devops
|
||
|
||
CREATE DATABASE registry;
|
||
CREATE USER harbor WITH PASSWORD '****************';
|
||
GRANT ALL PRIVILEGES ON DATABASE registry TO harbor;
|
||
ALTER DATABASE registry OWNER TO harbor;
|
||
#test
|
||
kubectl run psql-test --rm -it --image=postgres:16 -- psql -h pg-prod-rw.database.svc -U harbor
|
||
kubectl run redis-test --rm -it --image=redis:7 -- redis-cli -h redis.redis.svc.cluster.local -a Japp0cam
|
||
|
||
|
||
|
||
helm install harbor harbor/harbor -n harbor -f harborvalues.yaml
|
||
|
||
|
||
|
||
--- httproute & body setting nginx ----
|
||
kubectl apply -f - <<EOF
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: harbor
|
||
namespace: harbor
|
||
spec:
|
||
hostnames:
|
||
- harbor.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: harbor
|
||
port: 80
|
||
---
|
||
apiVersion: gateway.nginx.org/v1alpha1
|
||
kind: ClientSettingsPolicy
|
||
metadata:
|
||
name: gateway-client-settings
|
||
spec:
|
||
targetRef:
|
||
group: gateway.networking.k8s.io
|
||
kind: Gateway
|
||
name: main-gateway
|
||
body:
|
||
maxSize: "0"
|
||
EOF
|
||
|
||
|
||
|
||
TEST:
|
||
#push
|
||
docker login harbor.italiadatacenter.com
|
||
docker pull nginx:1.25
|
||
docker tag nginx:1.25 harbor.italiadatacenter.com/library/nginx:1.25
|
||
docker push harbor.italiadatacenter.com/library/nginx:1.25
|
||
|
||
#pull
|
||
docker rmi harbor.italiadatacenter.com/library/nginx:1.25
|
||
docker pull harbor.italiadatacenter.com/library/nginx:1.25
|
||
|
||
#pull da k8s
|
||
|
||
#STEP 1– Creare Robot Account in Harbor
|
||
#Harbor UI → Projects → (es. library o apps) → Robot Accounts
|
||
#Nome: k8s-pull
|
||
#Permessi:
|
||
#✔️ Repository → Pull
|
||
|
||
|
||
kubectl create secret docker-registry harbor-pull \
|
||
-n default \
|
||
--docker-server=harbor.italiadatacenter.com \
|
||
--docker-username=robot$k8s-pull \
|
||
--docker-password=******************************** \
|
||
--docker-email=harbor@italiadatacenter.com
|
||
|
||
#per namespace nuovi
|
||
kubectl patch serviceaccount default -n default -p '{"imagePullSecrets":[{"name":"harbor-pull"}]}'
|
||
|
||
#applicare per i vecchi:
|
||
kubectl patch serviceaccount default -n primo-dev -p '{"imagePullSecrets":[{"name":"harbor-pull"}]}'
|
||
|
||
#test
|
||
kubectl run test-nginx --image=harbor.italiadatacenter.com/library/nginx:1.25 --restart=Never -n poc
|
||
|
||
|
||
|
||
kubectl -n primo-dev create secret docker-registry harbor-pull \
|
||
--docker-server=harbor.italiadatacenter.com \
|
||
--docker-username=robot\$primo+primo \
|
||
--docker-password=******************************** \
|
||
--docker-email=harbor@italiadatacenter.com
|
||
|
||
kubectl patch serviceaccount default -n primo-dev -p '{"imagePullSecrets":[{"name":"harbor-pull"}]}'
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **Gitea Act Runner**
|
||
Download act_runner binary
|
||
```bash
|
||
mv act_runner-0.3.0-linux-amd64 act_runner
|
||
chmod +x ./act_runner
|
||
./act_runner --version
|
||
./act_runner register
|
||
|
||
Git server: https.//git.italiadatacener.com
|
||
token: SiP2B1Wth0FwORkLrIX7WYhho78IVaW3ZppO9vrx
|
||
label: runner1:host
|
||
|
||
start:
|
||
nohup ./act_runner daemon &
|
||
|
||
|
||
Install node
|
||
sudo apt update
|
||
sudo apt upgrade -y
|
||
sudo apt install -y curl ca-certificates gnupg
|
||
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
|
||
sudo apt install -y nodejs
|
||
|
||
verifica
|
||
node -v
|
||
npm -v
|
||
|
||
Installa docker:
|
||
sudo apt update
|
||
sudo apt install ca-certificates curl
|
||
sudo install -m 0755 -d /etc/apt/keyrings
|
||
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||
|
||
# Add the repository to Apt sources:
|
||
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
|
||
Types: deb
|
||
URIs: https://download.docker.com/linux/ubuntu
|
||
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
|
||
Components: stable
|
||
Signed-By: /etc/apt/keyrings/docker.asc
|
||
EOF
|
||
|
||
sudo apt update
|
||
|
||
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **Pipeline CICD**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
customize.sh
|
||
```bash
|
||
#!/bin/bash
|
||
# Usage: ./customize.sh dev|qa|prod
|
||
echo "tetst" $IMAGE_TAG_backend
|
||
ENV=$1
|
||
VALUES_FILE="env/$ENV/values.env"
|
||
PROPERTIES_FILE="properties.env"
|
||
YAML_DIR="kubernetes"
|
||
|
||
# Estrai l'hash completo del commit e crea una variabile temporanea per la sostituzione
|
||
TAG=$(git rev-parse HEAD)
|
||
TMP_TAG_FILE=$(mktemp)
|
||
echo "TAG=$TAG" > "$TMP_TAG_FILE"
|
||
cat ./imglist >> "$TMP_TAG_FILE"
|
||
|
||
|
||
if [ ! -f "$VALUES_FILE" ]; then
|
||
echo "File $VALUES_FILE non trovato."
|
||
exit 1
|
||
fi
|
||
|
||
if [ ! -f "$PROPERTIES_FILE" ]; then
|
||
echo "File $PROPERTIES_FILE non trovato."
|
||
exit 1
|
||
fi
|
||
|
||
# Trova tutti i file .yaml nella directory kubernetes e sottodirectory
|
||
find "$YAML_DIR" -type f -name "*.yaml" | while read YAML_FILE; do
|
||
|
||
while IFS='=' read -r key value; do
|
||
sed -i "s|<$key>|$value|g" "$YAML_FILE"
|
||
done < "$VALUES_FILE"
|
||
|
||
while IFS='=' read -r key value; do
|
||
sed -i "s|<$key>|$value|g" "$YAML_FILE"
|
||
done < "$PROPERTIES_FILE"
|
||
|
||
# Sostituzione dinamica della chiave TAG
|
||
while IFS='=' read -r key value; do
|
||
sed -i "s|<$key>|$value|g" "$YAML_FILE"
|
||
done < "$TMP_TAG_FILE"
|
||
|
||
echo "Sostituzione completata per file $YAML_FILE ambiente $ENV."
|
||
cat $YAML_FILE
|
||
done
|
||
|
||
rm -f "$TMP_TAG_FILE"
|
||
---
|
||
deploy.sh
|
||
#!/bin/bash
|
||
# Esegue kubectl apply per ogni sottodirectory di kubernetes separatamente
|
||
|
||
YAML_DIR="kubernetes"
|
||
# Trova tutte le sottodirectory (inclusa la principale) che contengono file .yaml
|
||
find "$YAML_DIR" -type d | while read DIR; do
|
||
if ls "$DIR"/*.yaml 1> /dev/null 2>&1; then
|
||
echo "Deploy delle risorse nella directory $DIR..."
|
||
kubectl --kubeconfig=./kubeconfig apply -f "$DIR"
|
||
fi
|
||
done
|
||
|
||
echo "Deploy completato di tutte le directory YAML."
|
||
---
|
||
build_container.sh:
|
||
#!/bin/bash
|
||
set -e
|
||
set -o pipefail
|
||
|
||
echo "progetto" $1
|
||
REPO_NAME=$1
|
||
COMMIT_SHA=$(git rev-parse HEAD)
|
||
REGISTRY_URL=$2
|
||
|
||
for dir in containers/*/; do
|
||
CONTAINER_NAME=$(basename "$dir")
|
||
cp -R src/${CONTAINER_NAME}/. containers/${CONTAINER_NAME}/.
|
||
ls -la $dir
|
||
DOCKERFILE="$dir/dockerfile"
|
||
IMAGE_TAG="${REGISTRY_URL}/${REPO_NAME}/${CONTAINER_NAME}:${COMMIT_SHA}"
|
||
echo "IMAGE_TAG_${CONTAINER_NAME}=$IMAGE_TAG" >> ./imglist
|
||
if [ -f "$DOCKERFILE" ]; then
|
||
docker build -t "$IMAGE_TAG" -f "$DOCKERFILE" "$dir"
|
||
docker push "$IMAGE_TAG"
|
||
echo "Build e push completate: $IMAGE_TAG"
|
||
else
|
||
echo "Dockerfile non trovato in $dir"
|
||
fi
|
||
done
|
||
|
||
----
|
||
kube-provisioning.sh
|
||
#!/usr/bin/env bash
|
||
###########################################################
|
||
#./kube-provisioning.sh dev cicd-user kubeconfig-dev.yaml
|
||
#arg1 = namespace
|
||
#arg2 = env (dev|qa|prod)
|
||
###########################################################
|
||
|
||
set -euo pipefail
|
||
|
||
############################################
|
||
# CONFIG
|
||
############################################
|
||
|
||
NAMESPACE=${1:-dev}-$2
|
||
SERVICE_ACCOUNT="deployer"
|
||
KUBECONFIG_FILE=${NAMESPACE}.yaml
|
||
|
||
echo "Namespace: $NAMESPACE"
|
||
echo "ServiceAccount: $SERVICE_ACCOUNT"
|
||
echo "Output kubeconfig: $KUBECONFIG_FILE"
|
||
|
||
############################################
|
||
# CHECK REQUIREMENTS
|
||
############################################
|
||
|
||
if ! command -v kubectl >/dev/null 2>&1; then
|
||
echo "kubectl not found"
|
||
exit 1
|
||
fi
|
||
|
||
############################################
|
||
# CREATE NAMESPACE
|
||
############################################
|
||
|
||
kubectl get ns "$NAMESPACE" >/dev/null 2>&1 || kubectl create namespace "$NAMESPACE"
|
||
|
||
############################################
|
||
# CREATE SERVICE ACCOUNT
|
||
############################################
|
||
|
||
kubectl -n "$NAMESPACE" get sa "$SERVICE_ACCOUNT" >/dev/null 2>&1 || \
|
||
kubectl -n "$NAMESPACE" create serviceaccount "$SERVICE_ACCOUNT"
|
||
|
||
############################################
|
||
# CREATE SECRET FOR SERVICE ACCOUNT TOKEN (legacy, validità illimitata)
|
||
############################################
|
||
|
||
SECRET_NAME="${SERVICE_ACCOUNT}-token"
|
||
if ! kubectl -n "$NAMESPACE" get secret "$SECRET_NAME" >/dev/null 2>&1; then
|
||
kubectl -n "$NAMESPACE" create secret generic "$SECRET_NAME" \
|
||
--type='kubernetes.io/service-account-token' \
|
||
--dry-run=client -o yaml > tmp-secret.yaml
|
||
|
||
# Inserisci correttamente l'annotazione YAML
|
||
yq eval ".metadata.annotations.\"kubernetes.io/service-account.name\" = \"$SERVICE_ACCOUNT\"" -i tmp-secret.yaml
|
||
|
||
kubectl apply -f tmp-secret.yaml
|
||
rm tmp-secret.yaml
|
||
fi
|
||
# Attendi che il token venga popolato nel secret
|
||
for i in {1..10}; do
|
||
TOKEN=$(kubectl -n "$NAMESPACE" get secret "$SECRET_NAME" -o jsonpath='{.data.token}' 2>/dev/null | base64 --decode || true)
|
||
if [[ -n "$TOKEN" ]]; then break; fi
|
||
sleep 1
|
||
done
|
||
|
||
if [[ -z "$TOKEN" ]]; then
|
||
echo "Errore: il token non è stato generato."
|
||
exit 1
|
||
fi
|
||
|
||
############################################
|
||
# CREATE ROLE
|
||
############################################
|
||
|
||
cat <<EOF | kubectl apply -f -
|
||
apiVersion: rbac.authorization.k8s.io/v1
|
||
kind: Role
|
||
metadata:
|
||
name: namespace-deployer
|
||
namespace: $NAMESPACE
|
||
rules:
|
||
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
|
||
resources: ["*"]
|
||
verbs: ["*"]
|
||
EOF
|
||
|
||
############################################
|
||
# CREATE ROLE BINDING
|
||
############################################
|
||
|
||
kubectl -n "$NAMESPACE" get rolebinding namespace-deployer-binding >/dev/null 2>&1 || \
|
||
kubectl create rolebinding namespace-deployer-binding \
|
||
--role=namespace-deployer \
|
||
--serviceaccount=${NAMESPACE}:${SERVICE_ACCOUNT} \
|
||
-n "$NAMESPACE"
|
||
|
||
############################################
|
||
# GET CLUSTER INFO
|
||
############################################
|
||
|
||
CLUSTER_NAME=$(kubectl config view --minify -o jsonpath='{.clusters[0].name}')
|
||
CLUSTER_SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
|
||
CLUSTER_CA=$(kubectl config view --raw --minify -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
|
||
|
||
############################################
|
||
# GENERATE KUBECONFIG
|
||
############################################
|
||
|
||
cat <<EOF > "$KUBECONFIG_FILE"
|
||
apiVersion: v1
|
||
kind: Config
|
||
clusters:
|
||
- cluster:
|
||
certificate-authority-data: ${CLUSTER_CA}
|
||
server: ${CLUSTER_SERVER}
|
||
name: ${CLUSTER_NAME}
|
||
|
||
contexts:
|
||
- context:
|
||
cluster: ${CLUSTER_NAME}
|
||
namespace: ${NAMESPACE}
|
||
user: ${SERVICE_ACCOUNT}
|
||
name: ${SERVICE_ACCOUNT}-${CLUSTER_NAME}
|
||
|
||
current-context: ${SERVICE_ACCOUNT}-${CLUSTER_NAME}
|
||
|
||
users:
|
||
- name: ${SERVICE_ACCOUNT}
|
||
user:
|
||
token: ${TOKEN}
|
||
EOF
|
||
|
||
echo
|
||
echo "Kubeconfig generated:"
|
||
echo "$KUBECONFIG_FILE"
|
||
|
||
echo
|
||
echo "Test command:"
|
||
echo "kubectl --kubeconfig=$KUBECONFIG_FILE get pods"
|
||
|
||
---
|
||
```
|
||
|
||
## Servizi Database
|
||
|
||
- **CloudNativePG**
|
||
```bash
|
||
kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.28/releases/cnpg-1.28.0.yaml--force-conflicts
|
||
curl -sSfL https://github.com/cloudnative-pg/cloudnative-pg/raw/main/hack/install-cnpg-plugin.sh | sudo sh -s -- -b /usr/local/bin
|
||
|
||
|
||
kubectl create namespace database
|
||
|
||
|
||
database.yaml:
|
||
|
||
---
|
||
apiVersion: v1
|
||
kind: Secret
|
||
metadata:
|
||
name: pg-app-user
|
||
namespace: demo-apps
|
||
type: kubernetes.io/basic-auth
|
||
stringData:
|
||
username: admin
|
||
password: *****
|
||
---
|
||
apiVersion: postgresql.cnpg.io/v1
|
||
kind: Cluster
|
||
metadata:
|
||
name: pg-test
|
||
namespace: demo-apps
|
||
spec:
|
||
instances: 3
|
||
|
||
storage:
|
||
size: 1Gi
|
||
storageClass: csi-rbdfs-sc
|
||
|
||
walStorage:
|
||
storageClass: csi-rbdfs-sc
|
||
size: 1Gi
|
||
|
||
bootstrap:
|
||
initdb:
|
||
database: testdb
|
||
owner: admin
|
||
secret:
|
||
name: pg-app-user
|
||
|
||
postgresql:
|
||
parameters:
|
||
max_connections: "300"
|
||
shared_buffers: "1GB"
|
||
|
||
resources:
|
||
requests:
|
||
cpu: "500m"
|
||
memory: "1Gi"
|
||
limits:
|
||
cpu: "2"
|
||
memory: "2Gi"
|
||
|
||
|
||
#test
|
||
kubectl run psql-client -n database --rm -it --image=postgres:16 --env="PGPASSWORD=*****" -- psql -h pg-test-rw.demo-apps.svc -U admin -d appdb
|
||
|
||
kubectl patch pvc pg-test-1-wal -n demo_apps -p '{"spec":{"resources":{"requests":{"storage":"32Gi"}}}}'
|
||
|
||
backup:
|
||
barmanObjectStore:
|
||
destinationPath: s3://pg-backups/prod
|
||
endpointURL: http://minio.minio.svc:9000
|
||
s3Credentials:
|
||
accessKeyId:
|
||
name: s3-creds
|
||
key: ACCESS_KEY
|
||
secretAccessKey:
|
||
name: s3-creds
|
||
key: SECRET_KEY
|
||
|
||
|
||
|
||
|
||
--- pgadmin -------------------
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: pgadmin-deployment
|
||
spec:
|
||
replicas: 1
|
||
selector:
|
||
matchLabels:
|
||
app: pgadmin
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: pgadmin
|
||
spec:
|
||
containers:
|
||
- name: pgadmin
|
||
image: dpage/pgadmin4
|
||
ports:
|
||
- containerPort: 80
|
||
env:
|
||
- name: PGADMIN_DEFAULT_EMAIL
|
||
value: pgadmin@italiadatacenter.com
|
||
- name: PGADMIN_DEFAULT_PASSWORD
|
||
value: ****************
|
||
---
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: pgadmin-service
|
||
spec:
|
||
selector:
|
||
app: pgadmin
|
||
ports:
|
||
- protocol: TCP
|
||
port: 80
|
||
targetPort: 80
|
||
---
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: demo-route
|
||
namespace: demo-apps
|
||
spec:
|
||
hostnames:
|
||
- poc3.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: pgadmin-service
|
||
port: 80
|
||
```
|
||
|
||
--------------------------------------------------------------------------------
|
||
|
||
```bash
|
||
cat <<EOF | kubectl -n database apply -f -
|
||
# This StorageClass is optimized for use with CloudNativePG.
|
||
# It disables storage-level replication and ensures data is local to the pod.
|
||
apiVersion: storage.k8s.io/v1
|
||
kind: StorageClass
|
||
metadata:
|
||
name: longhorn-cnpg-strict-local
|
||
provisioner: driver.longhorn.io
|
||
# allowVolumeExpansion is crucial for scaling database storage without downtime.
|
||
allowVolumeExpansion: true
|
||
# reclaimPolicy: Delete ensures that when a PVC is deleted, the underlying
|
||
# Longhorn volume is also removed, preventing orphaned storage.
|
||
reclaimPolicy: Delete
|
||
parameters:
|
||
# This is the most important setting. We rely on CloudNativePG for replication,
|
||
# so we only need one copy at the storage layer to avoid write amplification.
|
||
numberOfReplicas: "1"
|
||
# dataLocality: strict-local guarantees that the volume data will be stored
|
||
# on the same node as the pod that uses it. This is essential for performance
|
||
# and for aligning with a true shared-nothing architecture.
|
||
dataLocality: "strict-local"
|
||
# A longer timeout for stale replicas is suitable for database workloads.
|
||
staleReplicaTimeout: "2880" # 48 hours in minutes
|
||
# Default filesystem.
|
||
fsType: "ext4"
|
||
EOF
|
||
|
||
|
||
|
||
|
||
|
||
kubectl cnpg psql pg-devops -n devops
|
||
|
||
CREATE DATABASE giteadb;
|
||
CREATE USER gitea WITH PASSWORD '****************';
|
||
GRANT ALL PRIVILEGES ON DATABASE giteadb TO gitea;
|
||
ALTER DATABASE giteadb OWNER TO gitea;
|
||
|
||
|
||
cluster production ready:
|
||
|
||
apiVersion: postgresql.cnpg.io/v1
|
||
kind: Cluster
|
||
metadata:
|
||
name: mycluster
|
||
namespace: database
|
||
spec:
|
||
instances: 3 # → 3 nodi per HA reale
|
||
|
||
primaryUpdateStrategy: unsupervised
|
||
failover: # → Failover automatico
|
||
promoteTimeout: 5m
|
||
targetPromotionRule: "prefer-high-promotion-score"
|
||
|
||
# ---------------------------
|
||
# STORAGE (PRODUCTION)
|
||
# ---------------------------
|
||
storage:
|
||
size: 200Gi
|
||
storageClass: fast-rbd # Ceph, SSD, GP3 ecc.
|
||
resizeInUse: true
|
||
|
||
walStorage: # Consigliato in produzione
|
||
size: 50Gi
|
||
storageClass: fast-rbd
|
||
|
||
# ---------------------------
|
||
# WAL ARCHIVING (S3/MINIO)
|
||
# ---------------------------
|
||
walArchive:
|
||
enabled: true
|
||
destinationPath: "s3://mybucket/wal/"
|
||
s3Credentials:
|
||
accessKeyId:
|
||
name: cnpg-s3-creds
|
||
key: ACCESS_KEY_ID
|
||
secretAccessKey:
|
||
name: cnpg-s3-creds
|
||
key: SECRET_ACCESS_KEY
|
||
endpointURL: "https://s3.myregion.amazonaws.com"
|
||
region: "myregion"
|
||
encryption: AES256
|
||
|
||
# ---------------------------
|
||
# BACKUP AUTOMATICI
|
||
# ---------------------------
|
||
backup:
|
||
barmanObjectStore:
|
||
destinationPath: "s3://mybucket/basebackup/"
|
||
endpointURL: "https://s3.myregion.amazonaws.com"
|
||
s3Credentials:
|
||
accessKeyId:
|
||
name: cnpg-s3-creds
|
||
key: ACCESS_KEY_ID
|
||
secretAccessKey:
|
||
name: cnpg-s3-creds
|
||
key: SECRET_ACCESS_KEY
|
||
wal:
|
||
compression: bzip2
|
||
encryption: AES256
|
||
retentionPolicy: "30d" # → 30 giorni di retention
|
||
monitoring:
|
||
enablePodMonitor: true
|
||
|
||
# ---------------------------
|
||
# TLS INTERNO (RACCOMANDATO)
|
||
# ---------------------------
|
||
certificates:
|
||
serverTLSSecret: cnpg-server-tls
|
||
clientTLSSecret: cnpg-client-tls
|
||
|
||
# ---------------------------
|
||
# RESOURCE MANAGEMENT
|
||
# ---------------------------
|
||
resources:
|
||
requests:
|
||
cpu: "1"
|
||
memory: "2Gi"
|
||
limits:
|
||
cpu: "4"
|
||
memory: "8Gi"
|
||
|
||
# ---------------------------
|
||
# ANTI-AFFINITY & PDB
|
||
# ---------------------------
|
||
affinity:
|
||
enablePodAntiAffinity: true
|
||
topologyKey: "kubernetes.io/hostname"
|
||
|
||
podDisruptionBudget:
|
||
minAvailable: 2
|
||
|
||
# ---------------------------
|
||
# STARTUP & HEALTH
|
||
# ---------------------------
|
||
postgresql:
|
||
shared_preload_libraries:
|
||
- "pg_stat_statements"
|
||
- "auto_explain"
|
||
parameters:
|
||
max_connections: "300"
|
||
shared_buffers: "2GB"
|
||
effective_cache_size: "6GB"
|
||
maintenance_work_mem: "512MB"
|
||
wal_compression: "on"
|
||
wal_level: "replica"
|
||
max_wal_size: "4GB"
|
||
checkpoint_timeout: "15min"
|
||
synchronous_commit: "remote_apply"
|
||
|
||
# ---------------------------
|
||
# SYNCHRONOUS REPLICATION
|
||
# ---------------------------
|
||
replication:
|
||
synchronous:
|
||
mode: " quorum "
|
||
number: 1 # One sync replica; others async
|
||
|
||
# ---------------------------
|
||
# SERVICE & NETWORKING
|
||
# ---------------------------
|
||
service:
|
||
type: ClusterIP
|
||
primary:
|
||
type: ClusterIP
|
||
replicas:
|
||
type: ClusterIP
|
||
|
||
# ---------------------------
|
||
# ENCRYPTION AT REST (OPZIONALE)
|
||
# ---------------------------
|
||
encryption:
|
||
enabled: true
|
||
mode: aes256-gcm
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **MySql Operator**
|
||
```bash
|
||
helm repo add mysql-operator https://mysql.github.io/mysql-operator/
|
||
helm repo update
|
||
|
||
helm install my-mysql-operator mysql-operator/mysql-operator --namespace mysql-operator --create-namespace
|
||
|
||
--db instance
|
||
kubectl create secret generic mypwds \
|
||
--from-literal=rootUser=root \
|
||
--from-literal=rootHost=% \
|
||
--from-literal=rootPassword="******"
|
||
|
||
|
||
apiVersion: mysql.oracle.com/v2
|
||
kind: InnoDBCluster
|
||
metadata:
|
||
name: mycluster
|
||
spec:
|
||
secretName: mypwds
|
||
tlsUseSelfSigned: true
|
||
instances: 3
|
||
router:
|
||
instances: 1
|
||
|
||
|
||
--- test
|
||
$> kubectl run --rm -it myshell --image=container-registry.oracle.com/mysql/community-operator -- mysqlsh root@mycluster --sql
|
||
If you don't see a command prompt, try pressing enter.
|
||
******
|
||
|
||
MySQL mycluster SQL> SELECT @@hostname
|
||
|
||
+-------------+
|
||
| @@hostname |
|
||
+-------------+
|
||
| mycluster-0 |
|
||
+-------------+
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **Redis**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
```bash
|
||
kubectl create namespace redis
|
||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||
helm repo update
|
||
|
||
|
||
cat <<EOF | cat > redisvalues.yaml -
|
||
architecture: replication
|
||
|
||
auth:
|
||
enabled: true
|
||
password: ****************
|
||
|
||
master:
|
||
persistence:
|
||
enabled: true
|
||
storageClass: csi-rbdfs-sc
|
||
size: 5Gi
|
||
resources:
|
||
requests:
|
||
cpu: 100m
|
||
memory: 256Mi
|
||
|
||
replica:
|
||
replicaCount: 2
|
||
persistence:
|
||
enabled: true
|
||
storageClass: csi-rbdfs-sc
|
||
size: 5Gi
|
||
resources:
|
||
requests:
|
||
cpu: 100m
|
||
memory: 256Mi
|
||
|
||
sentinel:
|
||
enabled: true
|
||
replicas: 3
|
||
resources:
|
||
requests:
|
||
cpu: 50m
|
||
memory: 64Mi
|
||
|
||
metrics:
|
||
enabled: false
|
||
EOF
|
||
|
||
helm install redis bitnami/redis -n redis -f redisvalues.yaml
|
||
|
||
#test
|
||
kubectl run redis-client -n redis --rm -it --image=redis:7.2 -- redis-cli -h redis.redis.svc.cluster.local -a ****************
|
||
|
||
|
||
|
||
###########################################################################################################################
|
||
Redis(R) can be accessed via port 6379 on the following DNS name from within your cluster:
|
||
|
||
redis.redis.svc.cluster.local for read only operations
|
||
|
||
For read/write operations, first access the Redis(R) Sentinel cluster, which is available in port 26379 using the same domain name above.
|
||
|
||
To get your password run:
|
||
|
||
export REDIS_PASSWORD=$(kubectl get secret --namespace redis redis -o jsonpath="{.data.redis-password}" | base64 -d)
|
||
|
||
To connect to your Redis(R) server:
|
||
|
||
1. Run a Redis(R) pod that you can use as a client:
|
||
|
||
kubectl run --namespace redis redis-client --restart='Never' --env REDIS_PASSWORD=$REDIS_PASSWORD --image registry-1.docker.io/bitnami/redis:latest --command -- sleep infinity
|
||
|
||
Use the following command to attach to the pod:
|
||
|
||
kubectl exec --tty -i redis-client \
|
||
--namespace redis -- bash
|
||
|
||
2. Connect using the Redis(R) CLI:
|
||
REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h redis -p 6379 # Read only operations
|
||
REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h redis -p 26379 # Sentinel access
|
||
|
||
To connect to your database from outside the cluster execute the following commands:
|
||
|
||
kubectl port-forward --namespace redis svc/redis 6379:6379 &
|
||
REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h 127.0.0.1 -p 6379
|
||
```
|
||
|
||
- **InfluxDB**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
```bash
|
||
helm repo add influxdata https://helm.influxdata.com/
|
||
helm repo update
|
||
----
|
||
kubectl create namespace influxdb
|
||
----
|
||
influxdb-values.yaml:
|
||
image:
|
||
repository: influxdb
|
||
tag: 2.7
|
||
|
||
persistence:
|
||
enabled: true
|
||
size: 20Gi
|
||
|
||
resources:
|
||
requests:
|
||
cpu: 200m
|
||
memory: 256Mi
|
||
limits:
|
||
cpu: 1
|
||
memory: 1Gi
|
||
|
||
service:
|
||
type: ClusterIP
|
||
port: 8086
|
||
|
||
adminUser:
|
||
organization: sts-lab
|
||
bucket: demo-bucket
|
||
user: admin
|
||
password: *****************
|
||
token: my-super-token
|
||
|
||
|
||
----
|
||
helm install influxdb influxdata/influxdb2 --namespace influxdb -f influxdb-values.yaml
|
||
|
||
---
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: influxdb
|
||
spec:
|
||
hostnames:
|
||
- poc2.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: influxdb-influxdb2
|
||
port: 8086
|
||
|
||
|
||
|
||
|
||
****************** TEST ****************************
|
||
|
||
echo $(kubectl get secret influxdb-influxdb2-auth -o "jsonpath={.data['admin-password']}" --namespace influxdb | base64 --decode)
|
||
|
||
logon UI
|
||
http://localhost:8086
|
||
|
||
user: admin
|
||
password: *****************
|
||
|
||
TEST API:
|
||
curl http://localhost:8086/health
|
||
|
||
|
||
link svc:
|
||
influxdb-influxdb2.influxdb.svc.cluster.local
|
||
```
|
||
|
||
- **MongoDB**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **DbGate**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
```yaml
|
||
apiVersion: v1
|
||
kind: Namespace
|
||
metadata:
|
||
name: dbgate
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: dbgate
|
||
namespace: dbgate
|
||
|
||
spec:
|
||
replicas: 1
|
||
|
||
selector:
|
||
matchLabels:
|
||
app: dbgate
|
||
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: dbgate
|
||
|
||
spec:
|
||
containers:
|
||
- name: dbgate
|
||
image: dbgate/dbgate:latest
|
||
|
||
ports:
|
||
- containerPort: 3000
|
||
|
||
env:
|
||
- name: CONNECTIONS
|
||
value: ""
|
||
|
||
resources:
|
||
requests:
|
||
cpu: "100m"
|
||
memory: "128Mi"
|
||
|
||
limits:
|
||
cpu: "500m"
|
||
memory: "512Mi"
|
||
---
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: dbgate
|
||
namespace: dbgate
|
||
|
||
spec:
|
||
selector:
|
||
app: dbgate
|
||
|
||
ports:
|
||
- port: 80
|
||
targetPort: 3000
|
||
|
||
type: ClusterIP
|
||
|
||
httproute:
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: demo-route
|
||
namespace: demo-apps
|
||
spec:
|
||
hostnames:
|
||
- poc3.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: dbgate
|
||
port: 3000
|
||
---
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
## Servizi Applicativi / Utility
|
||
|
||
- **NodeRed**
|
||
```yaml
|
||
apiVersion: v1
|
||
kind: Namespace
|
||
metadata:
|
||
name: nodered
|
||
---
|
||
apiVersion: v1
|
||
kind: PersistentVolumeClaim
|
||
metadata:
|
||
name: node-red-pvc
|
||
namespace: nodered
|
||
labels:
|
||
app: node-red
|
||
spec:
|
||
accessModes:
|
||
- ReadWriteOnce
|
||
resources:
|
||
requests:
|
||
storage: 2Gi
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: node-red
|
||
namespace: nodered
|
||
labels:
|
||
app: node-red
|
||
spec:
|
||
replicas: 1
|
||
selector:
|
||
matchLabels:
|
||
app: node-red
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: node-red
|
||
spec:
|
||
securityContext:
|
||
fsGroup: 1000
|
||
containers:
|
||
- name: nodered
|
||
image: nodered/node-red:4.1
|
||
args: ["--settings", "/config/settings.js"]
|
||
env:
|
||
- name: NODE_OPTIONS
|
||
value: "--trace-warnings"
|
||
ports:
|
||
- containerPort: 1880
|
||
securityContext:
|
||
runAsUser: 1000
|
||
runAsGroup: 1000
|
||
allowPrivilegeEscalation: false
|
||
resources:
|
||
limits:
|
||
memory: "512Mi"
|
||
cpu: "500m"
|
||
requests:
|
||
memory: "256Mi"
|
||
cpu: "250m"
|
||
livenessProbe:
|
||
httpGet:
|
||
path: /
|
||
port: 1880
|
||
initialDelaySeconds: 30
|
||
periodSeconds: 10
|
||
readinessProbe:
|
||
httpGet:
|
||
path: /
|
||
port: 1880
|
||
initialDelaySeconds: 5
|
||
periodSeconds: 5
|
||
volumeMounts:
|
||
- name: node-red-storage
|
||
mountPath: /data
|
||
- name: node-red-settings
|
||
mountPath: /config/settings.js
|
||
subPath: settings.js
|
||
volumes:
|
||
- name: node-red-storage
|
||
persistentVolumeClaim:
|
||
claimName: node-red-pvc
|
||
- name: node-red-settings
|
||
configMap:
|
||
name: node-red-settings
|
||
---
|
||
apiVersion: v1
|
||
kind: ConfigMap
|
||
metadata:
|
||
name: node-red-settings
|
||
namespace: nodered
|
||
data:
|
||
settings.js: |
|
||
module.exports = {
|
||
httpAdminRoot: '/',
|
||
httpNodeRoot: '/',
|
||
userDir: '/data',
|
||
flowFile: 'flows.json',
|
||
credentialSecret: 'yzM0ol6Zn5kd1234',
|
||
adminAuth: {
|
||
type: "credentials",
|
||
users: [{
|
||
username: "admin",
|
||
password: "",
|
||
permissions: "*"
|
||
}]
|
||
},
|
||
uiPort: process.env.PORT || 1880,
|
||
mqttReconnectTime: 15000,
|
||
serialReconnectTime: 15000,
|
||
debugMaxLength: 1000,
|
||
functionGlobalContext: {},
|
||
exportGlobalContextKeys: false,
|
||
logging: {
|
||
console: {
|
||
level: "info",
|
||
metrics: false,
|
||
audit: false
|
||
}
|
||
},
|
||
editorTheme: {
|
||
projects: {
|
||
enabled: false
|
||
}
|
||
}
|
||
};
|
||
---
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: node-red-service
|
||
namespace: nodered
|
||
labels:
|
||
app: node-red
|
||
spec:
|
||
type: ClusterIP
|
||
ports:
|
||
- port: 1880
|
||
targetPort: 1880
|
||
protocol: TCP
|
||
name: http
|
||
selector:
|
||
app: node-red
|
||
---
|
||
apiVersion: autoscaling/v2
|
||
kind: HorizontalPodAutoscaler
|
||
metadata:
|
||
name: node-red-hpa
|
||
namespace: nodered
|
||
labels:
|
||
app: node-red
|
||
spec:
|
||
scaleTargetRef:
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
name: node-red
|
||
minReplicas: 1
|
||
maxReplicas: 3
|
||
metrics:
|
||
- type: Resource
|
||
resource:
|
||
name: cpu
|
||
target:
|
||
type: Utilization
|
||
averageUtilization: 70
|
||
- type: Resource
|
||
resource:
|
||
name: memory
|
||
target:
|
||
type: Utilization
|
||
averageUtilization: 80
|
||
---
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: node-red
|
||
namespace: nodered
|
||
spec:
|
||
hostnames:
|
||
- nodered.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: node-red-service
|
||
port: 1880
|
||
|
||
Istruzioni per set token influxdb
|
||
kubectl get pods -n nodered
|
||
kubectl exec -it node-red-bd88bc7df-knqfw -n nodered -- node-red admin hash-pw
|
||
|
||
kubectl edit configmap node-red-settings -n nodered --->(set campo password password: "<bcrypt-hash-here>", nella sezione adminAuth)
|
||
|
||
kubectl delete pods node-red-bd88bc7df-knqfw -n nodered
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **Grafana**
|
||
Aggiungere repository Helm Grafana
|
||
|
||
```bash
|
||
helm repo add grafana https://grafana.github.io/helm-charts
|
||
helm repo update
|
||
----
|
||
kubectl create namespace grafana
|
||
----
|
||
grafana-values.yaml:
|
||
replicas: 1
|
||
|
||
adminUser: admin
|
||
adminPassword: *****************
|
||
|
||
service:
|
||
type: ClusterIP
|
||
port: 80
|
||
|
||
persistence:
|
||
enabled: true
|
||
size: 10Gi
|
||
|
||
resources:
|
||
requests:
|
||
cpu: 100m
|
||
memory: 128Mi
|
||
limits:
|
||
cpu: 500m
|
||
memory: 512Mi
|
||
---
|
||
helm install grafana grafana/grafana -n grafana -f grafana-values.yaml
|
||
---
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: grafana
|
||
spec:
|
||
hostnames:
|
||
- tekton.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: grafana
|
||
port: 80
|
||
|
||
|
||
|
||
****************** TEST ****************************
|
||
Accesso alla UI Grafana
|
||
|
||
Aprire browser:
|
||
|
||
http://localhost:3000
|
||
|
||
Login:
|
||
|
||
user: admin
|
||
password: *****************
|
||
|
||
|
||
|
||
link svc:
|
||
grafana.grafana.svc.cluster.local
|
||
|
||
|
||
---------------------------------------
|
||
Aggiungere InfluxDB come datasource
|
||
|
||
|
||
In Grafana:
|
||
|
||
Connections
|
||
↓
|
||
Data Sources
|
||
↓
|
||
Add data source
|
||
↓
|
||
InfluxDB
|
||
|
||
Configurazione:
|
||
|
||
URL
|
||
http://influxdb:8086
|
||
|
||
Organization:
|
||
demo-org
|
||
|
||
Token:
|
||
my-super-token
|
||
|
||
Bucket:
|
||
demo-bucket
|
||
|
||
Salva.
|
||
|
||
6️⃣ Test datasource
|
||
|
||
Click:
|
||
|
||
Save & Test
|
||
|
||
Se corretto:
|
||
|
||
Datasource is working
|
||
7️⃣ Creare dashboard
|
||
|
||
In Grafana:
|
||
|
||
Create
|
||
↓
|
||
Dashboard
|
||
↓
|
||
Add panel
|
||
|
||
Query esempio (InfluxDB Flux):
|
||
|
||
from(bucket: "demo-bucket")
|
||
|> range(start: -1h)
|
||
```
|
||
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **Prometheus**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **SonarQube**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
########### repo helm ################
|
||
```bash
|
||
helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube
|
||
helm repo update
|
||
```
|
||
|
||
########### creazione ns e secret db ################
|
||
```bash
|
||
kubectl create namespace sonarqube
|
||
|
||
kubectl create secret generic sonarqube-database-cred \
|
||
--from-literal=username=sonarqube \
|
||
--from-literal=password=**************** \
|
||
-n sonarqube
|
||
```
|
||
|
||
########### creazione database ################
|
||
```bash
|
||
kubectl cnpg psql pg-devops -n devops
|
||
|
||
CREATE DATABASE sonarqube;
|
||
CREATE USER sonarqube WITH PASSWORD '****************';
|
||
GRANT ALL PRIVILEGES ON DATABASE sonarqube TO sonarqube;
|
||
ALTER DATABASE sonarqube OWNER TO sonarqube;
|
||
```
|
||
|
||
########### Values.yaml per installazione helm ################
|
||
|
||
service:
|
||
type: ClusterIP
|
||
|
||
postgresql:
|
||
enabled: false
|
||
|
||
jdbcOverwrite:
|
||
enabled: true
|
||
jdbcUrl: "jdbc:postgresql://pg-devops-rw.devops.svc.cluster.local:5432/sonarqube"
|
||
jdbcUsername: "postgres"
|
||
jdbcSecretName: "sonarqube-database-cred"
|
||
jdbcSecretPasswordKey: "password"
|
||
|
||
readinessProbe:
|
||
initialDelaySeconds: 300 # Increase initial delay to accommodate the database start time
|
||
timeoutSeconds: 60
|
||
periodSeconds: 10
|
||
successThreshold: 1
|
||
failureThreshold: 3
|
||
|
||
livenessProbe:
|
||
initialDelaySeconds: 360 # Ensure the application has enough time to start
|
||
timeoutSeconds: 60
|
||
periodSeconds: 10
|
||
successThreshold: 1
|
||
failureThreshold: 3
|
||
|
||
startupProbe:
|
||
initialDelaySeconds: 300 # Allow for sufficient startup time
|
||
timeoutSeconds: 60
|
||
periodSeconds: 10
|
||
successThreshold: 1
|
||
failureThreshold: 3
|
||
|
||
|
||
########### installazione helm ################
|
||
```bash
|
||
helm upgrade -f sonarvalues.yaml --install -n sonarqube sonarqube sonarqube/sonarqube --set community.enabled=true,monitoringPasscode="****************"
|
||
```
|
||
|
||
########### httproute ################
|
||
```yaml
|
||
apiVersion: gateway.networking.k8s.io/v1
|
||
kind: HTTPRoute
|
||
metadata:
|
||
name: sonarqube
|
||
namespace: sonarqube
|
||
spec:
|
||
hostnames:
|
||
- sonarqube.italiadatacenter.com
|
||
parentRefs:
|
||
- name: main-gateway
|
||
namespace: nginx-gateway
|
||
rules:
|
||
- matches:
|
||
- path:
|
||
type: PathPrefix
|
||
value: /
|
||
backendRefs:
|
||
- name: sonarqube-sonarqube
|
||
port: 9000
|
||
```
|
||
|
||
- **KubeEdge**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **Knative**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
- **Locust**
|
||
------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
|
||
|