commit 20d506407abec8d19fc2eaecd7bc20095e364438 Author: alessandro Date: Fri Jul 17 09:42:52 2026 +0200 primo diff --git a/GatewayAPI.txt b/GatewayAPI.txt new file mode 100644 index 0000000..d7de8e9 --- /dev/null +++ b/GatewayAPI.txt @@ -0,0 +1,126 @@ +# 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 - < **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 < /dev/null < /dev/null < /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 < 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 < 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 < 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 < 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 < 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 < 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 - < + 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 <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 < 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 < 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 - < "$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 </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 < "$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 < 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 < 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: "", 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** + ------------------------------------------------------------------------------------------------------------------------------ + + + diff --git a/Runbook Infrastruttura RKE2 e.docx b/Runbook Infrastruttura RKE2 e.docx new file mode 100644 index 0000000..02cccaf Binary files /dev/null and b/Runbook Infrastruttura RKE2 e.docx differ diff --git a/ServiceModel.xlsx b/ServiceModel.xlsx new file mode 100644 index 0000000..af255c4 Binary files /dev/null and b/ServiceModel.xlsx differ diff --git a/add-listener.js b/add-listener.js new file mode 100644 index 0000000..a67e2e8 --- /dev/null +++ b/add-listener.js @@ -0,0 +1,69 @@ +#!/usr/bin/env node +/** + * Aggiunge un listener HTTPS alla sezione `listeners` del gateway.yaml. + * + * Uso: + * node add-listener.js [gateway-file] + * + * Esempio: + * node add-listener.js sonarqube.italiadatacenter.com https-sonarqube sonarqube-secret + * node add-listener.js grafana.italiadatacenter.com https-grafana grafana-secret gateway.yaml + */ + +const fs = require('fs'); +const path = require('path'); + +const [,, hostname, name, secretName, gatewayFile = 'gateway.yaml'] = process.argv; + +if (!hostname || !name || !secretName) { + console.error('Uso: node add-listener.js [gateway-file]'); + console.error('Es.: node add-listener.js sonarqube.italiadatacenter.com https-sonarqube sonarqube-secret'); + process.exit(1); +} + +const filepath = path.resolve(__dirname, gatewayFile); + +if (!fs.existsSync(filepath)) { + console.error(`File non trovato: ${filepath}`); + process.exit(1); +} + +const content = fs.readFileSync(filepath, 'utf8'); + +// Controlla se il listener esiste già (per nome o hostname) +if (content.includes(`name: ${name}`) || content.includes(`hostname: ${hostname}`)) { + console.warn(`Attenzione: un listener con name "${name}" o hostname "${hostname}" esiste già. Nessuna modifica applicata.`); + process.exit(0); +} + +const newBlock = ` - allowedRoutes: + namespaces: + from: All + hostname: ${hostname} + name: ${name} + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: ${secretName} + mode: Terminate`; + +// Inserisce il nuovo block prima della riga "kind: List" o in fondo alla lista listeners +// Trova l'ultima occorrenza di "mode: Terminate" e appende subito dopo +const lastTerminateIdx = content.lastIndexOf(' mode: Terminate'); +if (lastTerminateIdx === -1) { + console.error('Impossibile trovare il punto di inserimento (mode: Terminate). File non modificato.'); + process.exit(1); +} + +const insertAfter = lastTerminateIdx + ' mode: Terminate'.length; +const updated = content.slice(0, insertAfter) + '\n' + newBlock + content.slice(insertAfter); + +fs.writeFileSync(filepath, updated, 'utf8'); +console.log(`Listener aggiunto:`); +console.log(` hostname : ${hostname}`); +console.log(` name : ${name}`); +console.log(` secret : ${secretName}`); +console.log(`File aggiornato: ${filepath}`); diff --git a/add-listener.sh b/add-listener.sh new file mode 100644 index 0000000..d989537 --- /dev/null +++ b/add-listener.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# Aggiunge un listener HTTPS direttamente sulla risorsa K8s Gateway +# main-gateway nel namespace nginx-gateway, tramite kubectl patch. +# +# Uso: +# ./add-listener.sh +# +# Esempio: +# ./add-listener.sh sonarqube.italiadatacenter.com https-sonarqube sonarqube-secret + +set -euo pipefail + +GATEWAY_NAME="main-gateway" +GATEWAY_NS="nginx-gateway" + +HOSTNAME_VAL="${1:-}" +NAME_VAL="${2:-}" +SECRET_NAME="${3:-}" + +if [[ -z "$HOSTNAME_VAL" || -z "$NAME_VAL" || -z "$SECRET_NAME" ]]; then + echo "Uso: $0 " + echo "Es.: $0 sonarqube.italiadatacenter.com https-sonarqube sonarqube-secret" + exit 1 +fi + +# Controlla idempotenza: verifica se il listener esiste già per nome o hostname +EXISTING=$(kubectl get gateway "$GATEWAY_NAME" -n "$GATEWAY_NS" \ + -o jsonpath='{.spec.listeners[*].name}') + +if echo "$EXISTING" | grep -qw "$NAME_VAL"; then + echo "Attenzione: listener con name '${NAME_VAL}' già presente. Nessuna modifica." + exit 0 +fi + +EXISTING_HOSTS=$(kubectl get gateway "$GATEWAY_NAME" -n "$GATEWAY_NS" \ + -o jsonpath='{.spec.listeners[*].hostname}') + +if echo "$EXISTING_HOSTS" | grep -qw "$HOSTNAME_VAL"; then + echo "Attenzione: listener con hostname '${HOSTNAME_VAL}' già presente. Nessuna modifica." + exit 0 +fi + +# JSON Patch: aggiunge il nuovo listener in append alla lista +PATCH=$(cat < ceph-csi-rbd-values.yaml +csiConfig: + - clusterID: "004ee854-86cc-4ddc-b7d6-75e4fe962296" + monitors: + - "172.20.1.33:6789" + - "172.20.1.34:6789" + - "172.20.1.35:6789" + +provisioner: + name: provisioner + replicaCount: 2 +EOF + + +helm install --namespace ceph-csi ceph-csi --values ceph-csi-rbd-values.yaml ./ + +Examples on how to configure a storage class and start using the driver are here: +https://github.com/ceph/ceph-csi/tree/devel/examples/rbd + + +echo "kubernetes" | tr -d '\n' | base64 +a3ViZXJuZXRlcw== + +cat > ceph-admin-secret.yaml << EOF +apiVersion: v1 +kind: Secret +metadata: + name: csi-rbd-secret + namespace: default +stringData: + userID: kubernetes + userKey: AQD2zo5pm8aZIRAAPzWS+dROeX7iJtv5EukfKA== +EOF + +# create a secret for admin user. +kubectl apply -f ceph-admin-secret.yaml + + + +----- Create StorageClass ------ + +cat > ceph-rbd-sc.yaml < create-ceph-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 + +# create pvc +kubectl apply -f create-ceph-pvc.yaml + +cat < create-pod-with-pvc.yaml +apiVersion: v1 +kind: Pod +metadata: + name: ceph-pod-pvc +spec: + containers: + - name: ceph-pod-pvc + image: busybox + command: ["sleep", "infinity"] + volumeMounts: + - mountPath: /mnt/ceph_rbd + name: volume + volumes: + - name: volume + persistentVolumeClaim: + claimName: raw-block-pvc +EOF + +# create pod +kubectl apply -f create-pod-with-pvc.yaml \ No newline at end of file diff --git a/add-on/CephCsi_install.txt b/add-on/CephCsi_install.txt new file mode 100644 index 0000000..38ee348 --- /dev/null +++ b/add-on/CephCsi_install.txt @@ -0,0 +1,122 @@ +cat < 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 < 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 < 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 < 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 < 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 < 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 \ No newline at end of file diff --git a/add-on/Istruzioni_kubeedge.txt b/add-on/Istruzioni_kubeedge.txt new file mode 100644 index 0000000..db9ca36 --- /dev/null +++ b/add-on/Istruzioni_kubeedge.txt @@ -0,0 +1,276 @@ +Cloudside: + +wget https://github.com/kubeedge/kubeedge/releases/download/v1.17.0/keadm-v1.17.0-linux-amd64.tar.gz +tar -zxvf keadm-v1.17.0-linux-amd64.tar.gz +cp keadm-v1.17.0-linux-amd64/keadm/keadm /usr/local/bin/keadm + +keadm init --advertise-address="89.105.78.161" --kubeedge-version=v1.22.0 --kube-config=/root/.kube/config + +keadm manifest generate --advertise-address="89.105.78.161" --kube-config=/root/.kube/config > kubeedge-cloudcore.yaml + +patch: + + cloudcore.yaml: | + apiVersion: cloudcore.config.kubeedge.io/v1alpha2 + commonConfig: + monitorServer: + bindAddress: 127.0.0.1:9091 + tunnelPort: 10354 + featureGates: + requireAuthorization: false + kind: CloudCore + +kubectl apply -f kubeedge-cloudcore.yaml -n kubeedge +kubectl apply -f edgenodeport.yaml -n kubeedge + + + +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Edge Side: +export KUBEEDGE_VERSION=v1.22.0 +export CLOUD_MASTER_IP=34.132.113.155 +export EDGE_NODE_NAME=edge-node-02 + + +Step 1 : Download & unpack containerd package +Containerd versions can be found in this location : https://github.com/containerd/containerd/releases + +Download : + wget https://github.com/containerd/containerd/releases/download/v1.6.14/containerd-1.6.14-linux-amd64.tar.gz +Unpack : + sudo tar Cxzvf /usr/local containerd-1.6.14-linux-amd64.tar.gz + +Step 2 : Install runc +Runc is a standardized runtime for spawning and running containers on Linux according to the OCI specification + + wget https://github.com/opencontainers/runc/releases/download/v1.1.3/runc.amd64 + sudo install -m 755 runc.amd64 /usr/local/sbin/runc + +Step 3: Download and install CNI plugins : + wget https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz + sudo mkdir -p /opt/cni/bin + sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.1.1.tgz + +Step 4: Configure containerd + +Create a containerd directory for the configuration file +config.toml is the default configuration file for containerd +Enable systemd group . Use sed command to change the parameter in config.toml instead of using vi editor +Convert containerd into service + + sudo mkdir /etc/containerd + containerd config default | sudo tee /etc/containerd/config.toml + sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml + sudo curl -L https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -o /etc/systemd/system/containerd.service + +Step 4.1 +remove SystemdCgroup = true line from /etc/containerd/config.toml. + +Step 4.2 +mkdir -p /etc/cni/net.d/ + +$ cat >/etc/cni/net.d/10-containerd-net.conflist </dev/null || true + fi +done + +# ------------------------------- +# 2. Cleanup containerd (safe) +# ------------------------------- +echo "[2] Cleaning containerd..." + +if command -v crictl &> /dev/null; then + echo "Using crictl..." + + # rimuove solo container stopped + crictl ps -a --state Exited -q | xargs -r crictl rm || true + + # rimuove pod sandbox non più validi + crictl pods --state NotReady -q | xargs -r crictl rmp || true + + # pulizia immagini dangling (SAFE) + crictl rmi --prune || true +else + echo "crictl not found, skipping..." +fi + +# ------------------------------- +# 3. Restart containerd +# ------------------------------- +echo "[3] Restarting containerd..." +systemctl restart containerd + +# ------------------------------- +# 4. Cleanup kubelet (soft) +# ------------------------------- +echo "[4] Cleaning kubelet state (soft)..." + +# Rimuove solo pod non più esistenti +find /var/lib/kubelet/pods -mindepth 1 -maxdepth 1 -type d -mtime +1 -exec rm -rf {} + || true + +# ------------------------------- +# 5. Restart kube services +# ------------------------------- +echo "[5] Restarting kubelet + edgecore..." + +systemctl restart kubelet || true +systemctl restart edgecore || true + +# ------------------------------- +# 6. Verifica connessione CloudCore +# ------------------------------- +echo "[6] Checking connectivity to CloudCore..." + +CLOUD_IP="89.105.78.161" +PORT="10002" + +if timeout 5 bash -c "(set campo password password: "", nella sezione adminAuth) + +kubectl delete pods node-red-bd88bc7df-knqfw -n nodered + + +user: admin +password:KAYQE1QA7uwUZ8uI \ No newline at end of file diff --git a/add-on/RabbitMQ.txt b/add-on/RabbitMQ.txt new file mode 100644 index 0000000..91f35a5 --- /dev/null +++ b/add-on/RabbitMQ.txt @@ -0,0 +1,59 @@ +Install Operator + +kubectl apply -f "https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml" +# namespace/rabbitmq-system created +# customresourcedefinition.apiextensions.k8s.io/rabbitmqclusters.rabbitmq.com created +# serviceaccount/rabbitmq-cluster-operator created +# role.rbac.authorization.k8s.io/rabbitmq-cluster-leader-election-role created +# clusterrole.rbac.authorization.k8s.io/rabbitmq-cluster-operator-role created +# rolebinding.rbac.authorization.k8s.io/rabbitmq-cluster-leader-election-rolebinding created +# clusterrolebinding.rbac.authorization.k8s.io/rabbitmq-cluster-operator-rolebinding created +# deployment.apps/rabbitmq-cluster-operator created + +Define an instance +Mqinstance.yaml: + +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + name: production-ready +spec: + replicas: 1 + resources: + requests: + cpu: 1 + memory: 1Gi + limits: + cpu: 1 + memory: 1Gi + rabbitmq: + additionalConfig: | + cluster_partition_handling = pause_minority + disk_free_limit.relative = 1.0 + collect_statistics_interval = 10000 + persistence: + storageClassName: csi-rbdfs-sc + storage: "5Gi" + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - production-ready + topologyKey: kubernetes.io/hostname + override: + statefulSet: + spec: + template: + spec: + containers: [] + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: "topology.kubernetes.io/zone" + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app.kubernetes.io/name: production-ready \ No newline at end of file diff --git a/add-on/act-runner-host.txt b/add-on/act-runner-host.txt new file mode 100644 index 0000000..4b8b41f --- /dev/null +++ b/add-on/act-runner-host.txt @@ -0,0 +1,44 @@ +Download act_runner binary + 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 < con il relativo valore letto dal file values.env della directory corrispondente all'input fornito +1) build_container.sh : script che effettua la docker build di tutti i container presenti nella directory containers usando il nome della directory sotto containers come nome del container,nome della root directory come nome del repository e sha del commit come tag. lo script deve eseguire anche la push su un registry con precedente login con credenziali lette dal file properties.env +2) deploy.sh: script che effettua il deploy in kubernetes del file infrastructure.yaml contenuto nella directory kubernetes + +struttura directory di progetto: + progetto-A + properties.env + build_src.sh + .gitea/ + workflows + pipeline.yaml + containers + frontend + dockerfile + backend + dockerfile + env + dev + values.env + qa + values.env + prod + values.env + kubernetes + infrastructure.yaml + src + + + Provisioning: + env: + $organization= nome della società + $project=nome del progetto + + + 1) Gitea: creazione Organization--> $organization(if not alreay exist) + 2) Gitea: creazione progetto nome--> $project + 3) Harbor: creazione project $project + 4) X3 k8s creazione NAMSPACE,SA, ROLE, ROLEBINDING,KUBECONFIG per deploy su namespace (kube-provisioning.sh) per dev qa e prod + 5) X3 Gitea: creazione secret KUBECONFIG_DEV, KUBECONFIG_QA e KUBECONFIG_PROD con kubeconfig generato da kube-provisioning.sh + 6) harbor: creazione robot-user "git" con permessi full su repo del progetto ---> $registry_user, $registry_pass + 7) harbor: creazione robot-user "k8spull" con permessi full su repo del progetto ---> $registry_user, $registry_pass + 8) creazione secret e patch SA default + kubectl -n <$project> create secret docker-registry harbor-pull \ + --docker-server=harbor.italiadatacenter.com \ + --docker-username=robot\$<$project>+k8spull \ + --docker-password= \ + --docker-email=harbor@italiadatacenter.com + + kubectl patch serviceaccount default -n athleteos-dev -p '{"imagePullSecrets":[{"name":"harbor-pull"}]}' + kubectl patch serviceaccount default -n <$project-qa> -p '{"imagePullSecrets":[{"name":"harbor-pull"}]}' + kubectl patch serviceaccount default -n <$project-prod> -p '{"imagePullSecrets":[{"name":"harbor-pull"}]}' + 9) Gitea: creazione secret REGISTRY_USER -->$registry_user, REGISTRY_PASS -->$registry_pass + 10)Gitea: poplazione repo con skeleton template + + + gitea-api-token + 65fc5f07365bd3f89c5b9ddca3d2d2e7b3777a88 + + https://git.italiadatacenter.com/api/swagger + + + List Template + curl -X 'GET' \ + 'https://git.italiadatacenter.com/api/v1/repos/search?q=tmpl&topic=false&includeDesc=true&token=65fc5f07365bd3f89c5b9ddca3d2d2e7b3777a88' \ + -H 'accept: application/json' + + + List repository: + curl -X 'GET' \ + 'https://git.italiadatacenter.com/api/v1/repos/search?token=65fc5f07365bd3f89c5b9ddca3d2d2e7b3777a88' \ + -H 'accept: application/json' + + + Create repo from template: + curl -X 'POST' \ + 'https://git.italiadatacenter.com/api/v1/repos/STS_Lab/tmpl_nginx_node/generate?token=65fc5f07365bd3f89c5b9ddca3d2d2e7b3777a88' \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "avatar": true, + "default_branch": "string", + "description": "string", + "git_content": true, + "git_hooks": true, + "labels": true, + "name": "secondo", + "owner": "STS_Lab", + "private": true, + "protected_branch": true, + "topics": true, + "webhooks": true +}' + + +creazione din una applicazione backstage che permetta la creazione di un repo da template con questa api: + curl -X 'POST' \ + 'https://git.italiadatacenter.com/api/v1/repos/STS_Lab/tmpl_nginx_node/generate?token=65fc5f07365bd3f89c5b9ddca3d2d2e7b3777a88' \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "avatar": true, + "default_branch": "string", + "description": "string", + "git_content": true, + "git_hooks": true, + "labels": true, + "name": "secondo", + "owner": "STS_Lab", + "private": true, + "protected_branch": true, + "topics": true, + "webhooks": true +}' + +la lista dei template disponbili è fornita dall'api: + curl -X 'GET' \ + 'https://git.italiadatacenter.com/api/v1/repos/search?q=tmpl&topic=false&includeDesc=true&token=65fc5f07365bd3f89c5b9ddca3d2d2e7b3777a88' \ + -H 'accept: application/json' + + l'utente deve poter creare un nuovo repo fornendo nome e template scelto dalla lista + + --------------------------------- + Harbor api: + https://harbor.italiadatacenter.com/devcenter-api-2.0 + + admin/KAYQE1QA7uwUZ8uI + + + + Create project + curl -X 'POST' \ + -u admin:KAYQE1QA7uwUZ8uI \ + 'https://harbor.italiadatacenter.com/api/v2.0/projects' \ + -H 'accept: application/json' \ + -H 'X-Resource-Name-In-Location: false' \ + -H 'Content-Type: application/json' \ + -d '{ + "project_name": "secondo", + "public": false, + "metadata": { + "public": "false", + "enable_content_trust": "string", + "enable_content_trust_cosign": "string", + "prevent_vul": "string", + "severity": "string", + "auto_scan": "string", + "auto_sbom_generation": "string", + "reuse_sys_cve_allowlist": "string", + + "proxy_speed_kb": "string", + "max_upstream_conn": "string" + }, + "cve_allowlist": { + "id": 0, + "project_id": 0, + "expires_at": 0, + "items": [ + { + "cve_id": "string" + } + ], + "creation_time": "2026-03-21T17:12:18.108Z", + "update_time": "2026-03-21T17:12:18.108Z" + }, + "storage_limit": 0 + +}' + + +creazionnr robot user + +curl -X 'POST' \ + -u admin:KAYQE1QA7uwUZ8uI \ + 'https://harbor.italiadatacenter.com/api/v2.0/robots' \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "name": "secondobot", + "description": "scondo bot", + "secret": "string", + "level": "system", + "disable": true, + "duration": -1, + "permissions": [ + { + "kind": "project", + "namespace": "secondo", + "access": [ + { + "action": "delete", + "resource": "repository" + }, + { + "action": "list", + "resource": "repository" + }, + { + "action": "push", + "resource": "repository" + }, + { + "action": "read", + "resource": "repository" + }, + { + "action": "update", + "resource": "repository" + }, + { + "action": "pull", + "resource": "repository" + } + ] + } + ] +}' + + + +{ + "creation_time": "2026-03-21T18:24:57.665Z", + "expires_at": -1, + "id": 44, + "name": "robot$secondobot", + "secret": "YxlIfu6o73zsQnKkgaWMdSc6MEwftVzk" +} + + + + + +####### template modulari######################################################### + + +# 🧠 🎯 Cos’è `git subtree` (in pratica) + +👉 `subtree` ti permette di: + +```text +includere un altro repository dentro una sottocartella +MANTENENDO la possibilità di aggiornarlo +``` + +👉 differenza chiave: + +* il codice viene **copiato nel repo** +* ma mantiene un **legame logico con l’origine** + +--- + +# 🔥 Perché è perfetto per template modulari + +Scenario IDP: + +```text +template-node +template-k8s +template-ci +``` + +👉 li vuoi combinare in: + +```text +my-service/ + app/ + k8s/ + ci/ +``` + +👉 `subtree` fa ESATTAMENTE questo, in modo pulito + +--- + +# 🏗️ Setup iniziale (step-by-step) + +## 1️⃣ Aggiungi il repo template + +```bash +git remote add template-node https://gitea/template-node.git +git fetch template-node +``` + +--- + +## 2️⃣ Importa il template + +```bash +git subtree add \ + --prefix=app \ + template-node main \ + --squash +``` + +--- + +### 🔍 Cosa succede + +* copia contenuto in `app/` +* crea 1 commit (grazie a `--squash`) +* mantiene riferimento al repo remoto + +--- + +# 🔄 Aggiornare il template + +👉 quando il template evolve: + +```bash +git subtree pull \ + --prefix=app \ + template-node main \ + --squash +``` + +--- + +👉 risultato: + +* aggiorna solo quella cartella +* merge automatico + +--- + +# 🚀 Multi-template (use case IDP) + +```bash +git subtree add --prefix=app template-node main --squash +git subtree add --prefix=k8s template-k8s main --squash +git subtree add --prefix=ci template-ci main --squash +``` + +--- + +👉 ottieni: + +```text +repo finale: + app/ + k8s/ + ci/ +``` + diff --git a/add-on/clusterussuer.yaml b/add-on/clusterussuer.yaml new file mode 100644 index 0000000..23eeecc --- /dev/null +++ b/add-on/clusterussuer.yaml @@ -0,0 +1,17 @@ +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod +spec: + acme: + email: alessandro.barucci66@gmail.com + server: https://acme-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: letsencrypt-production-key + solvers: + - http01: + gatewayHTTPRoute: + parentRefs: + - name: gateway + namespace: default + kind: Gateway \ No newline at end of file diff --git a/add-on/confmap.png b/add-on/confmap.png new file mode 100644 index 0000000..7996ad1 Binary files /dev/null and b/add-on/confmap.png differ diff --git a/add-on/create_ns.sh b/add-on/create_ns.sh new file mode 100644 index 0000000..6eaec53 --- /dev/null +++ b/add-on/create_ns.sh @@ -0,0 +1,118 @@ +#!/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 ROLE +############################################ + +cat </dev/null 2>&1 || \ +kubectl create rolebinding namespace-deployer-binding \ + --role=namespace-deployer \ + --serviceaccount=${NAMESPACE}:${SERVICE_ACCOUNT} \ + -n "$NAMESPACE" + +############################################ +# GENERATE TOKEN +############################################ + +TOKEN=$(kubectl create token "$SERVICE_ACCOUNT" -n "$NAMESPACE") + +############################################ +# 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 < "$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" diff --git a/add-on/dbgate.yaml b/add-on/dbgate.yaml new file mode 100644 index 0000000..cf79c63 --- /dev/null +++ b/add-on/dbgate.yaml @@ -0,0 +1,59 @@ +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 \ No newline at end of file diff --git a/add-on/devops.txt b/add-on/devops.txt new file mode 100644 index 0000000..e334296 --- /dev/null +++ b/add-on/devops.txt @@ -0,0 +1,113 @@ +kubectl create namespace devops + + +dbdevops.yaml: + +--- +apiVersion: v1 +kind: Secret +metadata: + name: pg-app-user + namespace: demo-apps +type: kubernetes.io/basic-auth +stringData: + username: devops + password: KAYQE1QA7uwUZ8uI +--- +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" + + + +--- 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: KAYQE1QA7uwUZ8uI + - name: PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION + value: "false" +--- +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 diff --git a/add-on/edgenodeport.yaml b/add-on/edgenodeport.yaml new file mode 100644 index 0000000..388cf33 --- /dev/null +++ b/add-on/edgenodeport.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + meta.helm.sh/release-name: cloudcore + meta.helm.sh/release-namespace: kubeedge + labels: + k8s-app: kubeedge + kubeedge: cloudcore + name: kubeedge-nodeport + namespace: kubeedge +spec: + ports: + - appProtocol: tcp + name: cloudhub + nodePort: 30868 + port: 10000 + protocol: TCP + targetPort: 10000 + - appProtocol: tcp2 + name: cloudhub2 + nodePort: 30869 + port: 10002 + protocol: TCP + targetPort: 10002 + selector: + k8s-app: kubeedge + kubeedge: cloudcore + sessionAffinity: None + type: NodePort \ No newline at end of file diff --git a/add-on/get_helm.sh b/add-on/get_helm.sh new file mode 100644 index 0000000..5f265a5 --- /dev/null +++ b/add-on/get_helm.sh @@ -0,0 +1,347 @@ +#!/usr/bin/env bash + +# Copyright The Helm Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# The install script is based off of the MIT-licensed script from glide, +# the package manager for Go: https://github.com/Masterminds/glide.sh/blob/master/get + +: ${BINARY_NAME:="helm"} +: ${USE_SUDO:="true"} +: ${DEBUG:="false"} +: ${VERIFY_CHECKSUM:="true"} +: ${VERIFY_SIGNATURES:="false"} +: ${HELM_INSTALL_DIR:="/usr/local/bin"} +: ${GPG_PUBRING:="pubring.kbx"} + +HAS_CURL="$(type "curl" &> /dev/null && echo true || echo false)" +HAS_WGET="$(type "wget" &> /dev/null && echo true || echo false)" +HAS_OPENSSL="$(type "openssl" &> /dev/null && echo true || echo false)" +HAS_GPG="$(type "gpg" &> /dev/null && echo true || echo false)" +HAS_GIT="$(type "git" &> /dev/null && echo true || echo false)" +HAS_TAR="$(type "tar" &> /dev/null && echo true || echo false)" + +# initArch discovers the architecture for this system. +initArch() { + ARCH=$(uname -m) + case $ARCH in + armv5*) ARCH="armv5";; + armv6*) ARCH="armv6";; + armv7*) ARCH="arm";; + aarch64) ARCH="arm64";; + x86) ARCH="386";; + x86_64) ARCH="amd64";; + i686) ARCH="386";; + i386) ARCH="386";; + esac +} + +# initOS discovers the operating system for this system. +initOS() { + OS=$(echo `uname`|tr '[:upper:]' '[:lower:]') + + case "$OS" in + # Minimalist GNU for Windows + mingw*|cygwin*) OS='windows';; + esac +} + +# runs the given command as root (detects if we are root already) +runAsRoot() { + if [ $EUID -ne 0 -a "$USE_SUDO" = "true" ]; then + sudo "${@}" + else + "${@}" + fi +} + +# verifySupported checks that the os/arch combination is supported for +# binary builds, as well whether or not necessary tools are present. +verifySupported() { + local supported="darwin-amd64\ndarwin-arm64\nlinux-386\nlinux-amd64\nlinux-arm\nlinux-arm64\nlinux-loong64\nlinux-ppc64le\nlinux-s390x\nlinux-riscv64\nwindows-amd64\nwindows-arm64" + if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then + echo "No prebuilt binary for ${OS}-${ARCH}." + echo "To build from source, go to https://github.com/helm/helm" + exit 1 + fi + + if [ "${HAS_CURL}" != "true" ] && [ "${HAS_WGET}" != "true" ]; then + echo "Either curl or wget is required" + exit 1 + fi + + if [ "${VERIFY_CHECKSUM}" == "true" ] && [ "${HAS_OPENSSL}" != "true" ]; then + echo "In order to verify checksum, openssl must first be installed." + echo "Please install openssl or set VERIFY_CHECKSUM=false in your environment." + exit 1 + fi + + if [ "${VERIFY_SIGNATURES}" == "true" ]; then + if [ "${HAS_GPG}" != "true" ]; then + echo "In order to verify signatures, gpg must first be installed." + echo "Please install gpg or set VERIFY_SIGNATURES=false in your environment." + exit 1 + fi + if [ "${OS}" != "linux" ]; then + echo "Signature verification is currently only supported on Linux." + echo "Please set VERIFY_SIGNATURES=false or verify the signatures manually." + exit 1 + fi + fi + + if [ "${HAS_GIT}" != "true" ]; then + echo "[WARNING] Could not find git. It is required for plugin installation." + fi + + if [ "${HAS_TAR}" != "true" ]; then + echo "[ERROR] Could not find tar. It is required to extract the helm binary archive." + exit 1 + fi +} + +# checkDesiredVersion checks if the desired version is available. +checkDesiredVersion() { + if [ "x$DESIRED_VERSION" == "x" ]; then + # Get tag from release URL + local latest_release_url="https://get.helm.sh/helm3-latest-version" + local latest_release_response="" + if [ "${HAS_CURL}" == "true" ]; then + latest_release_response=$( curl -L --silent --show-error --fail "$latest_release_url" 2>&1 || true ) + elif [ "${HAS_WGET}" == "true" ]; then + latest_release_response=$( wget "$latest_release_url" -q -O - 2>&1 || true ) + fi + TAG=$( echo "$latest_release_response" | grep '^v[0-9]' ) + if [ "x$TAG" == "x" ]; then + printf "Could not retrieve the latest release tag information from %s: %s\n" "${latest_release_url}" "${latest_release_response}" + exit 1 + fi + else + TAG=$DESIRED_VERSION + fi +} + +# checkHelmInstalledVersion checks which version of helm is installed and +# if it needs to be changed. +checkHelmInstalledVersion() { + if [[ -f "${HELM_INSTALL_DIR}/${BINARY_NAME}" ]]; then + local version=$("${HELM_INSTALL_DIR}/${BINARY_NAME}" version --template="{{ .Version }}") + if [[ "$version" == "$TAG" ]]; then + echo "Helm ${version} is already ${DESIRED_VERSION:-latest}" + return 0 + else + echo "Helm ${TAG} is available. Changing from version ${version}." + return 1 + fi + else + return 1 + fi +} + +# downloadFile downloads the latest binary package and also the checksum +# for that binary. +downloadFile() { + HELM_DIST="helm-$TAG-$OS-$ARCH.tar.gz" + DOWNLOAD_URL="https://get.helm.sh/$HELM_DIST" + CHECKSUM_URL="$DOWNLOAD_URL.sha256" + HELM_TMP_ROOT="$(mktemp -dt helm-installer-XXXXXX)" + HELM_TMP_FILE="$HELM_TMP_ROOT/$HELM_DIST" + HELM_SUM_FILE="$HELM_TMP_ROOT/$HELM_DIST.sha256" + echo "Downloading $DOWNLOAD_URL" + if [ "${HAS_CURL}" == "true" ]; then + curl -SsL "$CHECKSUM_URL" -o "$HELM_SUM_FILE" + curl -SsL "$DOWNLOAD_URL" -o "$HELM_TMP_FILE" + elif [ "${HAS_WGET}" == "true" ]; then + wget -q -O "$HELM_SUM_FILE" "$CHECKSUM_URL" + wget -q -O "$HELM_TMP_FILE" "$DOWNLOAD_URL" + fi +} + +# verifyFile verifies the SHA256 checksum of the binary package +# and the GPG signatures for both the package and checksum file +# (depending on settings in environment). +verifyFile() { + if [ "${VERIFY_CHECKSUM}" == "true" ]; then + verifyChecksum + fi + if [ "${VERIFY_SIGNATURES}" == "true" ]; then + verifySignatures + fi +} + +# installFile installs the Helm binary. +installFile() { + HELM_TMP="$HELM_TMP_ROOT/$BINARY_NAME" + mkdir -p "$HELM_TMP" + tar xf "$HELM_TMP_FILE" -C "$HELM_TMP" + HELM_TMP_BIN="$HELM_TMP/$OS-$ARCH/helm" + echo "Preparing to install $BINARY_NAME into ${HELM_INSTALL_DIR}" + runAsRoot cp "$HELM_TMP_BIN" "$HELM_INSTALL_DIR/$BINARY_NAME" + echo "$BINARY_NAME installed into $HELM_INSTALL_DIR/$BINARY_NAME" +} + +# verifyChecksum verifies the SHA256 checksum of the binary package. +verifyChecksum() { + printf "Verifying checksum... " + local sum=$(openssl sha1 -sha256 ${HELM_TMP_FILE} | awk '{print $2}') + local expected_sum=$(cat ${HELM_SUM_FILE}) + if [ "$sum" != "$expected_sum" ]; then + echo "SHA sum of ${HELM_TMP_FILE} does not match. Aborting." + exit 1 + fi + echo "Done." +} + +# verifySignatures obtains the latest KEYS file from GitHub main branch +# as well as the signature .asc files from the specific GitHub release, +# then verifies that the release artifacts were signed by a maintainer's key. +verifySignatures() { + printf "Verifying signatures... " + local keys_filename="KEYS" + local github_keys_url="https://raw.githubusercontent.com/helm/helm/main/${keys_filename}" + if [ "${HAS_CURL}" == "true" ]; then + curl -SsL "${github_keys_url}" -o "${HELM_TMP_ROOT}/${keys_filename}" + elif [ "${HAS_WGET}" == "true" ]; then + wget -q -O "${HELM_TMP_ROOT}/${keys_filename}" "${github_keys_url}" + fi + local gpg_keyring="${HELM_TMP_ROOT}/keyring.gpg" + local gpg_homedir="${HELM_TMP_ROOT}/gnupg" + mkdir -p -m 0700 "${gpg_homedir}" + local gpg_stderr_device="/dev/null" + if [ "${DEBUG}" == "true" ]; then + gpg_stderr_device="/dev/stderr" + fi + gpg --batch --quiet --homedir="${gpg_homedir}" --import "${HELM_TMP_ROOT}/${keys_filename}" 2> "${gpg_stderr_device}" + gpg --batch --no-default-keyring --keyring "${gpg_homedir}/${GPG_PUBRING}" --export > "${gpg_keyring}" + local github_release_url="https://github.com/helm/helm/releases/download/${TAG}" + if [ "${HAS_CURL}" == "true" ]; then + curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" + curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" + elif [ "${HAS_WGET}" == "true" ]; then + wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" + wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" + fi + local error_text="If you think this might be a potential security issue," + error_text="${error_text}\nplease see here: https://github.com/helm/community/blob/master/SECURITY.md" + local num_goodlines_sha=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" 2> "${gpg_stderr_device}" | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)') + if [[ ${num_goodlines_sha} -lt 2 ]]; then + echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256!" + echo -e "${error_text}" + exit 1 + fi + local num_goodlines_tar=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" 2> "${gpg_stderr_device}" | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)') + if [[ ${num_goodlines_tar} -lt 2 ]]; then + echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz!" + echo -e "${error_text}" + exit 1 + fi + echo "Done." +} + +# fail_trap is executed if an error occurs. +fail_trap() { + result=$? + if [ "$result" != "0" ]; then + if [[ -n "$INPUT_ARGUMENTS" ]]; then + echo "Failed to install $BINARY_NAME with the arguments provided: $INPUT_ARGUMENTS" + help + else + echo "Failed to install $BINARY_NAME" + fi + echo -e "\tFor support, go to https://github.com/helm/helm." + fi + cleanup + exit $result +} + +# testVersion tests the installed client to make sure it is working. +testVersion() { + set +e + HELM="$(command -v $BINARY_NAME)" + if [ "$?" = "1" ]; then + echo "$BINARY_NAME not found. Is $HELM_INSTALL_DIR on your "'$PATH?' + exit 1 + fi + set -e +} + +# help provides possible cli installation arguments +help () { + echo "Accepted cli arguments are:" + echo -e "\t[--help|-h ] ->> prints this help" + echo -e "\t[--version|-v ] . When not defined it fetches the latest release tag from the Helm CDN" + echo -e "\te.g. --version v3.0.0 or -v canary" + echo -e "\t[--no-sudo] ->> install without sudo" +} + +# cleanup temporary files to avoid https://github.com/helm/helm/issues/2977 +cleanup() { + if [[ -d "${HELM_TMP_ROOT:-}" ]]; then + rm -rf "$HELM_TMP_ROOT" + fi +} + +# Execution + +#Stop execution on any error +trap "fail_trap" EXIT +set -e + +# Set debug if desired +if [ "${DEBUG}" == "true" ]; then + set -x +fi + +# Parsing input arguments (if any) +export INPUT_ARGUMENTS="${@}" +set -u +while [[ $# -gt 0 ]]; do + case $1 in + '--version'|-v) + shift + if [[ $# -ne 0 ]]; then + export DESIRED_VERSION="${1}" + if [[ "$1" != "v"* ]]; then + echo "Expected version arg ('${DESIRED_VERSION}') to begin with 'v', fixing..." + export DESIRED_VERSION="v${1}" + fi + else + echo -e "Please provide the desired version. e.g. --version v3.0.0 or -v canary" + exit 0 + fi + ;; + '--no-sudo') + USE_SUDO="false" + ;; + '--help'|-h) + help + exit 0 + ;; + *) exit 1 + ;; + esac + shift +done +set +u + +initArch +initOS +verifySupported +checkDesiredVersion +if ! checkHelmInstalledVersion; then + downloadFile + verifyFile + installFile +fi +testVersion +cleanup diff --git a/add-on/gitea-action.txt b/add-on/gitea-action.txt new file mode 100644 index 0000000..668b333 --- /dev/null +++ b/add-on/gitea-action.txt @@ -0,0 +1,88 @@ +apiVersion: v1 +kind: Secret +metadata: + name: gitea-runner-secret +type: Opaque +stringData: + token: G3uEVBJ1TrlFhlwiWfE7seymUPnN1OgyeQHy7T7e +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: act-runner-vol +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: csi-rbdfs-sc +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: act-runner + name: act-runner +spec: + replicas: 1 + selector: + matchLabels: + app: act-runner + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + app: act-runner + spec: + hostAliases: + - ip: "140.82.121.3" + hostnames: + - "github.com" + restartPolicy: Always + volumes: + - name: docker-certs + emptyDir: {} + - name: runner-data + persistentVolumeClaim: + claimName: act-runner-vol + - name: dockersock + hostPath: + path: /var/run/docker.sock + containers: + - name: runner + image: gitea/act_runner:nightly-dind-rootless + command: ["sh", "-c", "while ! nc -z localhost 2376 /tmp/app.ini; test -e /act-runner-data/.runner || gitea actions generate-runner-token > /act-runner-data/token + env: + - name: GITEA_APP_INI + value: /tmp/app.ini + - name: GITEA_CUSTOM + value: /data/gitea + - name: GITEA_WORK_DIR + value: /data + + volumeMounts: + - name: gitea-shared-storage + mountPath: /data + readOnly: true + - name: gitea-act-runner-data + mountPath: /act-runner-data + containers: + - name: runner + image: gitea/act_runner:nightly + + # Container only for gitea, so we can choose the dind variant (rootless or not) + image: gitea/act_runner:0.2.10 + + env: + - name: DOCKER_HOST + value: tcp://127.0.0.1:2376 + - name: DOCKER_CERT_PATH + value: /certs/client + - name: DOCKER_TLS_VERIFY + value: "1" + - name: GITEA_RUNNER_REGISTRATION_TOKEN_FILE + value: /data/token + - name: CONFIG_FILE + value: /config.yaml + - name: GITEA_INSTANCE_URL + value: https://git.italiadatacenter.com + - name: CONFIG_FILE + value: /actrunner/config.yaml + + volumeMounts: + - name: gitea-act-runner-data + mountPath: /data + - name: docker-certs + mountPath: /certs/client + - name: runner-config + mountPath: /actrunner + ## Avoid subPath because it cannot be updated + ## https://github.com/kubernetes/kubernetes/issues/50345 + #mountPath: /actrunner/config.yaml + #subPath: config.yaml + + + - name: daemon + ## Rootless works for simple cases, but not for docker buildx + #image = "docker:27.1.2-dind-rootless" + image = "docker:27.1.2-dind" + env: + - name: DOCKER_TLS_CERTDIR + value: /certs + - name: DOCKER_HOST + value: tcp://127.0.0.1:2376 + - name: DOCKER_TLS_VERIFY + value: 1 + securityContext: + privileged: true + volumeMounts: + - name: docker-certs + mountPath: /certs/client + - name: gitea-docker-daemon-config + ## This one for rootless variant + #mountPath: /home/rootless/.config/docker + ## This other for regular variant + mountPath: /etc/docker + ## Avoid subPath because it cannot be updated + ## https://github.com/kubernetes/kubernetes/issues/50345 + #mountPath: /home/rootless/.config/docker/daemon.json + #mountPath: /etc/docker/daemon.json + #subPath: daemon.json + + + volumes: + - name: docker-certs + emptyDir: {} + - name: gitea-act-runner-config + configMap: + name: gitea-act-runner-config + - name: gitea-act-runner-data + persistentVolumeClaim: + claimName: gitea-act-runner + - name: gitea-shared-storage + persistentVolumeClaim: + claimName: gitea-shared-storage + readOnly: true + - name: gitea-docker-daemon-config + configMap: + name: gitea-docker-daemon-config + + volumeClaimTemplates: + - metadata: + name: gitea-act-runner-data + namespace: gitea + spec: + accessModes: + - ReadWriteOnce + storageClassName: standard + resources: + requests: + storage: 1Gi \ No newline at end of file diff --git a/add-on/gitea-workflow.txt b/add-on/gitea-workflow.txt new file mode 100644 index 0000000..1576bac --- /dev/null +++ b/add-on/gitea-workflow.txt @@ -0,0 +1,87 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + +jobs: + docker: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Harbor + uses: docker/login-action@v3 + with: + registry: harbor.italiadatacenter.com + username: ${{ secrets.HARBOR_USERNAME }} + password: ${{ secrets.HARBOR_PASSWORD }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: harbor.italiadatacenter.com/test/nginxtest:${{ github.sha }} + + #run: /root/work/pipeline/build_container.sh ${{ github.event.repository.name }} + +--------------------------------------------------------------------- +name: Build and Push Docker Images from Containers + +on: + push: + branches: [ main ] + workflow_dispatch: # Permette esecuzione manuale + +jobs: + # Job per elencare le directory con Dockerfile e creare una matrice + list-containers: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set matrix for containers + id: set-matrix + run: | + # Trova tutte le directory contenenti Dockerfile in containers/ + dirs=$(find containers -name Dockerfile -exec dirname {} \; | sort) + # Converte in JSON per la matrice (es. [{"dir": "containers/app1"}, {"dir": "containers/app2"}]) + matrix=$(echo "$dirs" | jq -R -s -c 'split("\n")[:-1] | map({dir: .})') + echo "matrix=$matrix" >> $GITHUB_OUTPUT + + - name: Log in to Docker registry + uses: docker/login-action@v3 + with: + registry: ghcr.io # Esempio: GitHub Container Registry; cambia se usi Docker Hub + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Job per buildare e pushare ogni immagine usando la matrice + build: + needs: list-containers + runs-on: ubuntu-latest + strategy: + matrix: + container: ${{ fromJson(needs.list-containers.outputs.matrix) }} + + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: ${{ matrix.container.dir }} # Contesto del build (la directory del Dockerfile) + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/add-on/gitea.sh b/add-on/gitea.sh new file mode 100644 index 0000000..4ee8b10 --- /dev/null +++ b/add-on/gitea.sh @@ -0,0 +1,100 @@ + +kubectl cnpg psql pg-devops -n devops + +CREATE DATABASE giteadb; +CREATE USER gitea WITH PASSWORD 'KAYQE1QA7uwUZ8uI'; +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 <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: KAYQE1QA7uwUZ8uI + email: gitadmin@italiadatacenter.com + + config: + database: + DB_TYPE: postgres + HOST: pg-devops-rw.devops.svc:5432 + NAME: giteadb + USER: gitea + PASSWD: KAYQE1QA7uwUZ8uI + 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 diff --git a/add-on/grafana.txt b/add-on/grafana.txt new file mode 100644 index 0000000..4e6da51 --- /dev/null +++ b/add-on/grafana.txt @@ -0,0 +1,123 @@ +Aggiungere repository Helm Grafana + +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: KAYQE1QA7uwUZ8uI5 + +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: KAYQE1QA7uwUZ8uI5 + + + +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) \ No newline at end of file diff --git a/add-on/harbor.sh b/add-on/harbor.sh new file mode 100644 index 0000000..eb9d1e6 --- /dev/null +++ b/add-on/harbor.sh @@ -0,0 +1,201 @@ +#HARBOR +kubectl create namespace harbor + +helm repo add harbor https://helm.goharbor.io +helm repo update + +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 < 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: "KAYQE1QA7uwUZ8uI" + +# ----------------------- +# 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: "KAYQE1QA7uwUZ8uI" + database: registry + sslmode: require + +# ----------------------- +# REDIS (EXTERNAL) +# ----------------------- +redis: + type: external + external: + addr: redis.redis.svc.cluster.local:6379 + password: "KAYQE1QA7uwUZ8uI" + 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 'KAYQE1QA7uwUZ8uI'; +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 - </dev/null 2>&1; then + echo "Errore: sudo non trovato" + exit 1 +fi + +TMP_DIR="$(mktemp -d)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +echo "[1/8] Download e installazione containerd ${CONTAINERD_VERSION}" +cd "${TMP_DIR}" +wget -q "https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz" +sudo tar Cxzvf /usr/local "containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz" + +echo "[2/8] Download e installazione runc ${RUNC_VERSION}" +wget -q "https://github.com/opencontainers/runc/releases/download/v${RUNC_VERSION}/runc.amd64" +sudo install -m 755 runc.amd64 /usr/local/sbin/runc + +echo "[3/8] Download e installazione CNI plugins ${CNI_VERSION}" +wget -q "https://github.com/containernetworking/plugins/releases/download/v${CNI_VERSION}/cni-plugins-linux-amd64-v${CNI_VERSION}.tgz" +sudo mkdir -p /opt/cni/bin +sudo tar Cxzvf /opt/cni/bin "cni-plugins-linux-amd64-v${CNI_VERSION}.tgz" + +echo "[4/8] Configurazione containerd" +sudo mkdir -p /etc/containerd +containerd config default | sudo tee /etc/containerd/config.toml >/dev/null +sudo sed -i '/SystemdCgroup = true/d' /etc/containerd/config.toml +sudo curl -fsSL https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -o /etc/systemd/system/containerd.service + +echo "[5/8] Configurazione rete CNI" +sudo mkdir -p /etc/cni/net.d +cat <<'EOF' | sudo tee /etc/cni/net.d/10-containerd-net.conflist >/dev/null +{ + "cniVersion": "1.0.0", + "name": "containerd-net", + "plugins": [ + { + "type": "bridge", + "bridge": "cni0", + "isGateway": true, + "ipMasq": true, + "promiscMode": true, + "ipam": { + "type": "host-local", + "ranges": [ + [{ + "subnet": "10.88.0.0/16" + }], + [{ + "subnet": "2001:db8:4860::/64" + }] + ], + "routes": [ + { "dst": "0.0.0.0/0" }, + { "dst": "::/0" } + ] + } + }, + { + "type": "portmap", + "capabilities": {"portMappings": true} + } + ] +} +EOF + +echo "[6/8] Avvio e abilitazione containerd" +sudo systemctl daemon-reload +sudo systemctl enable --now containerd + +echo "[7/8] Installazione keadm ${KUBEEDGE_VERSION}" +cd "${TMP_DIR}" +curl -fsSL "https://github.com/kubeedge/kubeedge/releases/download/${KUBEEDGE_VERSION}/keadm-${KUBEEDGE_VERSION}-linux-amd64.tar.gz" | tar -xz +sudo mv "keadm-${KUBEEDGE_VERSION}-linux-amd64/keadm/keadm" /usr/local/bin/ + +echo "[8/8] Join edge node al cloud master" +sudo keadm join \ + --cloudcore-ipport="${CLOUD_MASTER_IP}:10000" \ + --edgenode-name="${EDGE_NODE_NAME}" \ + --token="${KUBEEDGE_TOKEN}" \ + --kubeedge-version="${KUBEEDGE_VERSION}" + +echo "Creazione script di cleanup edge" +cat <<'EOF' | sudo tee /usr/local/bin/edge-cleanup.sh >/dev/null +#!/usr/bin/env bash + +set -euo pipefail + +echo "==== EDGE NODE CLEANUP START ====" +echo "Timestamp: $(date)" + +echo "[1] Checking orphan processes..." +ORPHANS=$(ps -eo pid,ppid,cmd | awk '$2 == 1 {print $1}') +for PID in ${ORPHANS}; do + if [ "${PID}" != "1" ]; then + echo "Killing orphan PID: ${PID}" + kill -9 "${PID}" 2>/dev/null || true + fi +done + +echo "[2] Cleaning containerd..." +if command -v crictl >/dev/null 2>&1; then + crictl ps -a --state Exited -q | xargs -r crictl rm || true + crictl pods --state NotReady -q | xargs -r crictl rmp || true + crictl rmi --prune || true +else + echo "crictl not found, skipping..." +fi + +echo "[3] Restarting containerd..." +systemctl restart containerd || true + +echo "[4] Cleaning kubelet state (soft)..." +find /var/lib/kubelet/pods -mindepth 1 -maxdepth 1 -type d -mtime +1 -exec rm -rf {} + || true + +echo "[5] Restarting kubelet + edgecore..." +systemctl restart kubelet || true +systemctl restart edgecore || true + +echo "[6] Checking MQTT port..." +ss -tulnp | grep 1883 || echo "WARNING: Mosquitto not listening" + +echo "==== EDGE NODE CLEANUP DONE ====" +EOF + +sudo chmod +x /usr/local/bin/edge-cleanup.sh + +echo "Creazione service systemd edge-cleanup" +cat <<'EOF' | sudo tee /etc/systemd/system/edge-cleanup.service >/dev/null +[Unit] +Description=Edge Node Cleanup +After=network.target + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/edge-cleanup.sh +RemainAfterExit=true + +[Install] +WantedBy=multi-user.target +EOF + +sudo systemctl daemon-reload +sudo systemctl enable edge-cleanup + +echo "==== EDGE NODE INSTALL DONE ====" diff --git a/add-on/installa-cert-manager.sh b/add-on/installa-cert-manager.sh new file mode 100644 index 0000000..835e67a --- /dev/null +++ b/add-on/installa-cert-manager.sh @@ -0,0 +1,11 @@ +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 \ No newline at end of file diff --git a/add-on/installaRancher.sh b/add-on/installaRancher.sh new file mode 100644 index 0000000..ab93a02 --- /dev/null +++ b/add-on/installaRancher.sh @@ -0,0 +1,7 @@ +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=admin diff --git a/add-on/installa_helm.sh b/add-on/installa_helm.sh new file mode 100644 index 0000000..6e52865 --- /dev/null +++ b/add-on/installa_helm.sh @@ -0,0 +1,7 @@ +# 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 diff --git a/add-on/k8s-secret.jpg b/add-on/k8s-secret.jpg new file mode 100644 index 0000000..a055fdd Binary files /dev/null and b/add-on/k8s-secret.jpg differ diff --git a/add-on/longhornui.yaml b/add-on/longhornui.yaml new file mode 100644 index 0000000..eadadae --- /dev/null +++ b/add-on/longhornui.yaml @@ -0,0 +1,23 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: longhornui + annotations: + kubernetes.io/ingress.class: "nginx" + cert-manager.io/cluster-issuer: "letsencrypt-production" +spec: + tls: + - hosts: + - longhorn.pigreco66.it + secretName: longhornui-tls + rules: + - host: longhorn.pigreco66.it + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: longhorn-frontend + port: + number: 80 diff --git a/add-on/minio.txt b/add-on/minio.txt new file mode 100644 index 0000000..feecb7b --- /dev/null +++ b/add-on/minio.txt @@ -0,0 +1,111 @@ + +##helm +helm repo add minio https://charts.min.io/ +helm repo update + + +##values.yaml: +mode: distributed + +replicas: 2 + +drivesPerNode: 1 + +persistence: + enabled: true + storageClass: csi-rbdfs-sc # 👈 IL TUO STORAGE CLASS + size: 50Gi + +resources: + requests: + memory: 1Gi + cpu: 500m + limits: + memory: 2Gi + cpu: 1 + +rootUser: minioadmin +rootPassword: KAYQE1QA7uwUZ8uI + +service: + type: ClusterIP + +ingress: + enabled: false + +consoleService: + type: ClusterIP + +##Deploy + helm install minio minio/minio -n minio --create-namespace -f minio_values.yaml + + + Accesso: +kubectl port-forward svc/minio -n minio 9000 +kubectl port-forward svc/minio-console -n storage 9001 + +##per pod us nodi diversi +affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - minio + topologyKey: "kubernetes.io/hostname" + + +#################INFO########################## + +NAME: minio +LAST DEPLOYED: Sun Mar 29 16:23:17 2026 +NAMESPACE: minio +STATUS: deployed +REVISION: 1 +TEST SUITE: None +NOTES: +MinIO can be accessed via port 9000 on the following DNS name from within your cluster: +minio.minio.cluster.local + +To access MinIO from localhost, run the below commands: + + 1. export POD_NAME=$(kubectl get pods --namespace minio -l "release=minio" -o jsonpath="{.items[0].metadata.name}") + + 2. kubectl port-forward $POD_NAME 9000 --namespace minio + +Read more about port forwarding here: http://kubernetes.io/docs/user-guide/kubectl/kubectl_port-forward/ + +You can now access MinIO server on http://localhost:9000. Follow the below steps to connect to MinIO server with mc client: + + 1. Download the MinIO mc client - https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart + + 2. export MC_HOST_minio-local=http://$(kubectl get secret --namespace minio minio -o jsonpath="{.data.rootUser}" | base64 --decode):$(kubectl get secret --namespace minio minio -o jsonpath="{.data.rootPassword}" | base64 --decode)@localhost:9000 + + ###svc nodeport per accessi backup etc +apiVersion: v1 +kind: Service +metadata: + annotations: + meta.helm.sh/release-name: minio + meta.helm.sh/release-namespace: minio + labels: + app: minio + release: minio + name: minio-nodeport + namespace: minio +spec: + ports: + - name: http + nodePort: 30877 + port: 9000 + protocol: TCP + targetPort: 9000 + selector: + app: minio + release: minio + sessionAffinity: None + type: NodePort + + diff --git a/add-on/mosquitto.yaml b/add-on/mosquitto.yaml new file mode 100644 index 0000000..799f64c --- /dev/null +++ b/add-on/mosquitto.yaml @@ -0,0 +1,104 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mosquitto-config + namespace: mqtt +data: + mosquitto.conf: | + listener 1883 + allow_anonymous true + + persistence true + persistence_location /mosquitto/data/ + + log_dest stdout + log_type all + + # opzionale: retained messages + persistence_file mosquitto.db +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mosquitto-pvc + namespace: mqtt +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: csi-rbdfs-sc # 👈 cambia se necessario +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mosquitto + namespace: mqtt +spec: + replicas: 1 + selector: + matchLabels: + app: mosquitto + template: + metadata: + labels: + app: mosquitto + spec: + containers: + - name: mosquitto + image: eclipse-mosquitto:2 + ports: + - containerPort: 1883 + volumeMounts: + - name: config + mountPath: /mosquitto/config/mosquitto.conf + subPath: mosquitto.conf + - name: data + mountPath: /mosquitto/data + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "500m" + memory: "512Mi" + volumes: + - name: config + configMap: + name: mosquitto-config + - name: data + persistentVolumeClaim: + claimName: mosquitto-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: mqtt-broker + namespace: mqtt +spec: + selector: + app: mosquitto + ports: + - name: mqtt + port: 1883 + targetPort: 1883 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + name: mqtt-broker-nodeport + namespace: mqtt +spec: + ports: + - appProtocol: tcp + name: mqtt + nodePort: 31883 + port: 1883 + protocol: TCP + targetPort: 1883 + selector: + app: mosquitto + sessionAffinity: None + type: NodePort \ No newline at end of file diff --git a/add-on/mqtt.png b/add-on/mqtt.png new file mode 100644 index 0000000..19f83a8 Binary files /dev/null and b/add-on/mqtt.png differ diff --git a/add-on/mysql.txt b/add-on/mysql.txt new file mode 100644 index 0000000..5c9a401 --- /dev/null +++ b/add-on/mysql.txt @@ -0,0 +1,38 @@ +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="sakila" + + +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 | ++-------------+ + +This section utilizes the {innodbclustername}.{namespace}.svc.cluster.local form when connecting; and typically refers to the {innodbclustername} shorthand form that assumes the default namespace. See Section 3.4, “MySQL InnoDB Cluster Service Explanation” for additional information. \ No newline at end of file diff --git a/add-on/nginx-controller-service-nodeport.yaml b/add-on/nginx-controller-service-nodeport.yaml new file mode 100644 index 0000000..88aae65 --- /dev/null +++ b/add-on/nginx-controller-service-nodeport.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + meta.helm.sh/release-name: rke2-ingress-nginx + meta.helm.sh/release-namespace: kube-system + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: rke2-ingress-nginx + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: rke2-ingress-nginx + app.kubernetes.io/part-of: rke2-ingress-nginx + app.kubernetes.io/version: 1.13.4 + helm.sh/chart: rke2-ingress-nginx-4.13.400 + name: ingress-nginx-nodeport + namespace: kube-system +spec: + ports: + - appProtocol: https + name: https + nodePort: 30864 + port: 443 + protocol: TCP + targetPort: https + selector: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: rke2-ingress-nginx + app.kubernetes.io/name: rke2-ingress-nginx + sessionAffinity: None + type: NodePort \ No newline at end of file diff --git a/add-on/package-lock.json b/add-on/package-lock.json new file mode 100644 index 0000000..ac67fbc --- /dev/null +++ b/add-on/package-lock.json @@ -0,0 +1,38 @@ +{ + "name": "add-on", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "chokidar": "^5.0.0" + } + }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + } + } +} diff --git a/add-on/package.json b/add-on/package.json new file mode 100644 index 0000000..e7ab627 --- /dev/null +++ b/add-on/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "chokidar": "^5.0.0" + } +} diff --git a/add-on/pgdb.txt b/add-on/pgdb.txt new file mode 100644 index 0000000..537bcfe --- /dev/null +++ b/add-on/pgdb.txt @@ -0,0 +1,62 @@ + +kubectl create namespace + + +dbxx.yaml.yaml: + +--- +apiVersion: v1 +kind: Secret +metadata: + name: pg-app-user + namespace: +type: kubernetes.io/basic-auth +stringData: + username: devops + password: KAYQE1QA7uwUZ8uI +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: pg-devops + namespace: +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" + + + + +kubectl cnpg psql pg-devops -n devops + +CREATE DATABASE giteadb; +CREATE USER gitea WITH PASSWORD 'KAYQE1QA7uwUZ8uI'; +GRANT ALL PRIVILEGES ON DATABASE giteadb TO gitea; +ALTER DATABASE giteadb OWNER TO gitea; \ No newline at end of file diff --git a/add-on/pipeline.txt b/add-on/pipeline.txt new file mode 100644 index 0000000..3c53da5 --- /dev/null +++ b/add-on/pipeline.txt @@ -0,0 +1,71 @@ +#!/bin/bash +# Usage: ./customize.sh dev|qa|prod + +ENV=$1 +VALUES_FILE="env/$ENV/values.env" +YAML_FILE="kubernetes/infrastructure.yaml" + +if [ ! -f "$VALUES_FILE" ]; then + echo "File $VALUES_FILE non trovato." + exit 1 +fi + +if [ ! -f "$YAML_FILE" ]; then + echo "File $YAML_FILE non trovato." + exit 1 +fi + +while IFS='=' read -r key value; do + sed -i "s|<$key>|$value|g" "$YAML_FILE" +done < "$VALUES_FILE" + +echo "Sostituzione completata per ambiente $ENV." + + + + + +#!/bin/bash + +# Carica variabili dal file properties.env +source properties.env + +# Controlla che le variabili siano impostate +if [ -z "$REGISTRY_URL" ] || [ -z "$REGISTRY_USER" ] || [ -z "$REGISTRY_PASS" ]; then + echo "REGISTRY_URL, REGISTRY_USER o REGISTRY_PASS non impostate in properties.env" + exit 1 +fi + +REPO_NAME=$(basename "$PWD") +COMMIT_SHA=$(git rev-parse --short HEAD) + +# Login al registry +echo "$REGISTRY_PASS" | docker login "$REGISTRY_URL" -u "$REGISTRY_USER" --password-stdin + +for dir in containers/*/; do + CONTAINER_NAME=$(basename "$dir") + DOCKERFILE="$dir/dockerfile" + IMAGE_TAG="${REGISTRY_URL}/${REPO_NAME}/${CONTAINER_NAME}:${COMMIT_SHA}" + 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 + + + +#!/bin/bash +# Effettua il deploy del file infrastructure.yaml in Kubernetes + +YAML_FILE="kubernetes/infrastructure.yaml" + +if [ ! -f "$YAML_FILE" ]; then + echo "File $YAML_FILE non trovato." + exit 1 +fi + +kubectl apply -f "$YAML_FILE" +echo "Deploy completato." \ No newline at end of file diff --git a/add-on/pipeline_segregata.sh b/add-on/pipeline_segregata.sh new file mode 100644 index 0000000..72cd8c7 --- /dev/null +++ b/add-on/pipeline_segregata.sh @@ -0,0 +1,169 @@ +# creazione secret, SA, Role e Rolebinding all'interno del namespace applicativo + +kubectl create secret docker-registry harbor-regcred \ + -n poc \ + --docker-server=harbor.pigreco66.it \ + --docker-username=robot$tekton \ + --docker-password=p2oZtqcUJafMAlX0eUzgHax9fv0ML8te \ + --docker-email=alessandro.barucci66@gmail.com + +kubectl create secret generic harbor-push-secret -n poc --from-file=config.json=config.json + + +cat < apply -f su namespace centralizzato tekton-pipelines +#kubectl apply -f pipedep.yaml -n tekton-pipelines +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: deploy-infrastructure +spec: + description: | + This pipeline clones a git repo, builds a Docker image with Kaniko and + pushes it to a registry + params: + - name: repo-url + type: string + - name: image-reference + type: string + - name: dockerfile + type: string + - name: namespace + type: string + workspaces: + - name: shared-data + - name: docker-credentials + tasks: + - name: fetch-source + taskRef: + resolver: cluster + params: + - name: name + value: git-clone + - name: namespace + value: tekton-pipelines + - name: kind + value: task + workspaces: + - name: output + workspace: shared-data + params: + - name: url + value: $(params.repo-url) + - name: build-push + runAfter: ["fetch-source"] + taskRef: + resolver: cluster + params: + - name: name + value: kaniko + - name: namespace + value: tekton-pipelines + - name: kind + value: task + workspaces: + - name: source + workspace: shared-data + - name: dockerconfig + workspace: docker-credentials + params: + - name: IMAGE + value: $(params.image-reference) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: deploy + runAfter: [build-push] + taskRef: + resolver: cluster + params: + - name: name + value: kubectl-apply + - name: namespace + value: tekton-pipelines + - name: kind + value: task + params: + - name: namespace + value: $(params.namespace) + workspaces: + - name: source + workspace: shared-data + + +#PipelineRun creato su namespace applicativo che refenzia pipeline remote +#kubectl create -f pipedeprun2.yaml -n poc +apiVersion: tekton.dev/v1beta1 +kind: PipelineRun +metadata: + generateName: clone-build-push-run- +spec: + serviceAccountName: tekton-deployer + pipelineRef: + resolver: cluster + params: + - name: namespace + value: tekton-pipelines + - name: name + value: deploy-infrastructure + - name: kind + value: pipeline + podTemplate: + securityContext: + fsGroup: 65532 + workspaces: + - name: shared-data + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + storageClassName: longhorn + resources: + requests: + storage: 1Gi + - name: docker-credentials + secret: + secretName: harbor-push-secret + params: + - name: repo-url + value: https://gitea.pigreco66.it/pigreco/poc.git + - name: image-reference + value: harbor.pigreco66.it/library/nginx:1.30 + - name: dockerfile + value: ./container/nginx/dockerfile + - name: namespace + value: poc diff --git a/add-on/pipelines.sh b/add-on/pipelines.sh new file mode 100644 index 0000000..41dce87 --- /dev/null +++ b/add-on/pipelines.sh @@ -0,0 +1,349 @@ + +#installo task community "git-clone" +#kubectl apply -f https://api.hub.tekton.dev/v1/resource/tekton/task/git-clone/0.10/raw -n +kubectl apply -f https://github.com/tektoncd/catalog/raw/main/task/git-clone/0.10/git-clone.yaml -n tekton-pipelines + + +cat < redisvalues.yaml - +architecture: replication + +auth: + enabled: true + password: KAYQE1QA7uwUZ8uI + +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 KAYQE1QA7uwUZ8uI + + + +########################################################################################################################### +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 \ No newline at end of file diff --git a/add-on/run_validate_css.cmd b/add-on/run_validate_css.cmd new file mode 100644 index 0000000..23ca434 --- /dev/null +++ b/add-on/run_validate_css.cmd @@ -0,0 +1 @@ +powershell -ExecutionPolicy Bypass -File .\add-on\validate-scss.ps1 -RootPath "C:\Users\Public\git\limec-frontend\src\" \ No newline at end of file diff --git a/add-on/sonaquebe.txt b/add-on/sonaquebe.txt new file mode 100644 index 0000000..bc7e4c1 --- /dev/null +++ b/add-on/sonaquebe.txt @@ -0,0 +1,87 @@ +########### repo helm ################ +helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube +helm repo update + +########### creazione ns e secret db ################ +kubectl create namespace sonarqube + +kubectl create secret generic sonarqube-database-cred \ + --from-literal=username=sonarqube \ + --from-literal=password=KAYQE1QA7uwUZ8uI \ + -n sonarqube + + +########### creazione database ################ +kubectl cnpg psql pg-devops -n devops + +CREATE DATABASE sonarqube; +CREATE USER sonarqube WITH PASSWORD 'KAYQE1QA7uwUZ8uI'; +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 ################ +helm upgrade -f sonarvalues.yaml --install -n sonarqube sonarqube sonarqube/sonarqube --set community.enabled=true,monitoringPasscode="KAYQE1QA7uwUZ8uI" + + + +########### httproute ################ +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 + + +admin +$KAYQE1QA7uwUZ8uI \ No newline at end of file diff --git a/add-on/tekton.sh b/add-on/tekton.sh new file mode 100644 index 0000000..ad163d6 --- /dev/null +++ b/add-on/tekton.sh @@ -0,0 +1,197 @@ +kubectl create namespace tekton-pipelines + +kubectl apply -f https://infra.tekton.dev/tekton-releases/pipeline/previous/v1.7.0/release.yaml + +kubectl edit cm feature-flags -n tekton-pipelines +data: + enable-api-fields: "stable" + disable-affinity-assistant: "false" + enable-tekton-oci-bundles: "true" + enable-custom-tasks: "true" + + +kubectl edit cm config-defaults -n tekton-pipelines +data: + default-timeout-minutes: "60" + default-service-account: "tekton-sa" + +cat < tekton-sa.yaml - +apiVersion: v1 +kind: ServiceAccount +metadata: + name: tekton-sa + namespace: tekton-pipelines +EOF + +kubectl apply -f tekton-sa.yaml + +#STEP 1– Creare Robot Account in Harbor +#Harbor UI → Projects → (es. library o apps) → Robot Accounts +#Nome: k8s-pull +#Permessi: +#✔️ FULL permission + + +kubectl create secret docker-registry harbor-regcred \ + -n tekton-pipelines \ + --docker-server=harbor.italiadatacenter.com \ + --docker-username=robot$tekton \ + --docker-password=pyyMRe2kRIp6LQmIh8jaSWquL1mDtz04 \ + --docker-email=harbor@italiadatacenter.com + + +cat < config.json +{ + "auths": { + "harbor.italiadatacenter.com": { + "username": "robot\$tekton", + "password": "pyyMRe2kRIp6LQmIh8jaSWquL1mDtz04", + "email": "harbor@italiadatacenter.com", + "auth": "$(echo -n 'robot$tekton:pyyMRe2kRIp6LQmIh8jaSWquL1mDtz04' | base64)" + } + } +} +EOF + + +kubectl create secret generic harbor-push-secret -n tekton-pipelines --from-file=config.json=config.json + + + + +kubectl patch sa tekton-sa \ + -n tekton-pipelines \ + -p '{"imagePullSecrets":[{"name":"harbor-regcred"}]}' + +cat < tekton-workspace.yaml - +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: tekton-workspace + namespace: tekton-pipelines +spec: + accessModes: + - ReadWriteOnce + storageClassName: csi-rbdfs-sc + resources: + requests: + storage: 10Gi +EOF + +kubectl apply -f tekton-workspace.yaml -n tekton-pipelines + +#Tekton Triggers +kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml -n tekton-pipelines + +#Tekton Dashboard +kubectl apply -f https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yaml -n tekton-pipelines + +cat < tekton-ingress.yaml - +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tekton-dashboard + namespace: tekton-pipelines + annotations: + kubernetes.io/ingress.class: "nginx" + cert-manager.io/cluster-issuer: "letsencrypt-production" +spec: + tls: + - hosts: + - tekton.pigreco66.it + secretName: myapp-tls + rules: + - host: tekton.pigreco66.it + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: tekton-dashboard + port: + number: 9097 +EOF + +cat < tekton-httproute.yaml - +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: tekton + namespace: tekton-pipelines +spec: + hostnames: + - tekton.italiadatacenter.com + parentRefs: + - name: main-gateway + namespace: nginx-gateway + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: tekton-dashboard + port: 9097 +EOF + +kubectl apply -f tekton-httproute.yaml -n tekton-pipelines + +kubectl label namespace tekton-pipelines \ + pod-security.kubernetes.io/enforce=privileged \ + pod-security.kubernetes.io/audit=privileged \ + pod-security.kubernetes.io/warn=privileged \ + --overwrite + + +#installazione cli + +curl -LO https://github.com/tektoncd/cli/releases/download/v0.43.0/tkn_0.43.0_Linux_x86_64.tar.gz +tar xvf tkn_0.43.0_Linux_x86_64.tar.gz +sudo mv tkn /usr/local/bin/ + + +#TEST + + + +cat < tekton-test.yaml - +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: hello + namespace: tekton-pipelines +spec: + steps: + - name: echo + image: alpine + script: | + echo "Tekton OK" +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: hello-pipeline + namespace: tekton-pipelines +spec: + tasks: + - name: hello + taskRef: + name: hello +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: hello-pipeline-run +spec: + pipelineRef: + name: hello-pipeline + params: + - name: username + value: "Tekton" +EOF +kubectl apply -f tekton-test.yaml -n tekton-pipelines + + + + diff --git a/add-on/validate-scss.ps1 b/add-on/validate-scss.ps1 new file mode 100644 index 0000000..e3b88fa --- /dev/null +++ b/add-on/validate-scss.ps1 @@ -0,0 +1,134 @@ +param ( + [Parameter(Mandatory = $true)] + [string]$RootPath, + + [string]$NpxSassPackage = "sass@1.77.8", + + [bool]$NoErrorCss = $true +) + +$ErrorActionPreference = 'Stop' + +try { + $resolvedRoot = (Resolve-Path -Path $RootPath).Path +} catch { + Write-Host "ERROR: Root path not found: $RootPath" -ForegroundColor Red + exit 2 +} + +Write-Host "Scanning SCSS files in: $resolvedRoot" -ForegroundColor Cyan + +function Get-SassRunner { + param( + [Parameter(Mandatory = $true)] + [string]$StartPath, + + [Parameter(Mandatory = $true)] + [string]$PinnedNpxPackage + ) + + $current = $StartPath + while ($true) { + $localSass = Join-Path $current "node_modules\\.bin\\sass.cmd" + if (Test-Path $localSass) { + return @{ + Command = $localSass + PrefixArgs = @() + Source = "local" + } + } + + $parent = Split-Path -Path $current -Parent + if (-not $parent -or $parent -eq $current) { + break + } + $current = $parent + } + + $npxCmd = Get-Command npx.cmd -ErrorAction SilentlyContinue + if ($npxCmd) { + cmd /d /c "npx -y -p $PinnedNpxPackage sass --version >nul 2>&1" | Out-Null + if ($LASTEXITCODE -eq 0) { + return @{ + Command = $npxCmd.Source + PrefixArgs = @("-y", "-p", $PinnedNpxPackage, "sass") + Source = "npx:$PinnedNpxPackage" + } + } + } + + $sassCmd = Get-Command sass.cmd -ErrorAction SilentlyContinue + if ($sassCmd) { + cmd /d /c "sass --version >nul 2>&1" | Out-Null + if ($LASTEXITCODE -eq 0) { + return @{ + Command = $sassCmd.Source + PrefixArgs = @() + Source = "global" + } + } + } + + return $null +} + +$sassRunner = Get-SassRunner -StartPath $resolvedRoot -PinnedNpxPackage $NpxSassPackage +if (-not $sassRunner) { + Write-Host "ERROR: No working Sass runner found (local sass.cmd, global sass, or npx sass)." -ForegroundColor Red + exit 3 +} + +Write-Host "Using Sass runner: $($sassRunner.Source) [$($sassRunner.Command)]" -ForegroundColor DarkCyan + +# Find all SCSS files recursively from the given root path. +$files = Get-ChildItem -Path $resolvedRoot -Recurse -File -Filter "*.scss" + +if ($files.Count -eq 0) { + Write-Host "No SCSS files found." -ForegroundColor Yellow + exit 0 +} + +$hasErrors = $false +$checkedCount = 0 +$errorCount = 0 + +foreach ($file in $files) { + $checkedCount += 1 + Write-Host "Checking: $($file.FullName)" -ForegroundColor Gray + + # Syntax-only validation: compile to NUL to avoid creating/opening any CSS files. + $sassArgs = @($sassRunner.PrefixArgs) + @('--no-source-map', '--style=compressed', '--quiet', "--load-path=$resolvedRoot") + if ($NoErrorCss) { + $sassArgs += '--no-error-css' + } + $sassArgs += @($file.FullName, 'NUL') + + $previousErrorAction = $ErrorActionPreference + $ErrorActionPreference = 'Continue' + try { + $result = & $sassRunner.Command @sassArgs 2>&1 | Out-String + $exitCode = $LASTEXITCODE + } finally { + $ErrorActionPreference = $previousErrorAction + } + + if ($exitCode -ne 0) { + $hasErrors = $true + $errorCount += 1 + Write-Host "" + Write-Host "ERROR in $($file.FullName)" -ForegroundColor Red + Write-Host $result -ForegroundColor Yellow + Write-Host "----------------------------------------" + } +} + +Write-Host "" +Write-Host "Checked files: $checkedCount" + +if (-not $hasErrors) { + Write-Host "All SCSS files are syntactically valid." -ForegroundColor Green + exit 0 +} + +Write-Host "SCSS files with errors: $errorCount" -ForegroundColor Red +exit 1 \ No newline at end of file diff --git a/add-on/vol.png b/add-on/vol.png new file mode 100644 index 0000000..a8cec65 Binary files /dev/null and b/add-on/vol.png differ diff --git a/addworker.sh b/addworker.sh new file mode 100644 index 0000000..ddcdaf7 --- /dev/null +++ b/addworker.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +FILE="$1" +NEW_LINE="$2" + +if [[ ! -f "$FILE" ]]; then + echo "❌ File not found: $FILE" + exit 1 +fi + +if ! grep -q "^tls-san:" "$FILE"; then + echo "❌ 'tls-san:' not found in $FILE" + exit 1 +fi + +awk -v newline="$NEW_LINE" ' +{ + print + if ($0 ~ /^tls-san:/) { + print newline + } +} +' "$FILE" > "${FILE}.tmp" && mv "${FILE}.tmp" "$FILE" + +echo "✅ Line added after tls-san:" +echo " $NEW_LINE" diff --git a/build-listener-from-endpoint.sh b/build-listener-from-endpoint.sh new file mode 100644 index 0000000..cfb17d8 --- /dev/null +++ b/build-listener-from-endpoint.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Usa properties.env nella directory corrente, oppure un path passato come primo argomento. +PROPERTIES_FILE="${1:-properties.env}" + +if [[ ! -f "$PROPERTIES_FILE" ]]; then + echo "Errore: file non trovato: $PROPERTIES_FILE" >&2 + exit 1 +fi + +# Estrae endpoint ignorando commenti e spazi, supportando anche endpoint = valore +endpoint_raw="$({ grep -E '^[[:space:]]*endpoint[[:space:]]*=' "$PROPERTIES_FILE" | tail -n1 || true; } | sed -E 's/^[[:space:]]*endpoint[[:space:]]*=[[:space:]]*//')" + +# Rimuove eventuali virgolette e spazi ai bordi +endpoint="$(echo "$endpoint_raw" | sed -E 's/^[[:space:]"\x27]+//; s/[[:space:]"\x27]+$//')" + +if [[ -z "$endpoint" ]]; then + echo "La chiave endpoint non e valorizzata in $PROPERTIES_FILE" >&2 + exit 1 +fi + +# Per calcolare il token usa host pulito (senza schema e path) +host_for_token="${endpoint#*://}" +host_for_token="${host_for_token%%/*}" +token="${host_for_token%%.*}" + +if [[ -z "$token" ]]; then + echo "Impossibile estrarre il token da endpoint: $endpoint" >&2 + exit 1 +fi + +# Esegue lo script richiesto con la stringa costruita +/root/work/pipeline/add-listener.sh "$endpoint https-$token $token-secret" diff --git a/demo.yaml b/demo.yaml new file mode 100644 index 0000000..9a4749e --- /dev/null +++ b/demo.yaml @@ -0,0 +1,189 @@ +---DEMO --- + +--- +apiVersion: v1 +kind: Namespace +metadata: + name: demo-apps +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app-v1 + namespace: demo-apps +spec: + replicas: 2 + selector: + matchLabels: + app: demo + version: v1 + template: + metadata: + labels: + app: demo + version: v1 + spec: + containers: + - name: app + image: hashicorp/http-echo + args: + - "-text=Hello from App v1" + ports: + - containerPort: 5678 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app-v2 + namespace: demo-apps +spec: + replicas: 2 + selector: + matchLabels: + app: demo + version: v2 + template: + metadata: + labels: + app: demo + version: v2 + spec: + containers: + - name: app + image: hashicorp/http-echo + args: + - "-text=Hello from App v2" + ports: + - containerPort: 5678 +--- +apiVersion: v1 +kind: Service +metadata: + name: app-v1 + namespace: demo-apps +spec: + selector: + app: demo + version: v1 + ports: + - port: 80 + targetPort: 5678 +--- +apiVersion: v1 +kind: Service +metadata: + name: app-v2 + namespace: demo-apps +spec: + selector: + app: demo + version: v2 + ports: + - port: 80 + targetPort: 5678 + + + + + +---- HTTP ROUTE --- +kind: HTTPRoute +metadata: + name: demo-route + namespace: demo-apps +spec: + parentRefs: + - name: main-gateway + namespace: nginx-gateway + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: app-v1 + port: 80 + + + + + + + + + + + +***to add for https *** + + # HTTP'S Listener (Add Muliple HTTPS listner) + - name: https-api-artha-link + port: 443 + protocol: HTTPS + hostname: domain1.com + tls: + mode: Terminate + certificateRefs: + - kind: Secret + name: domain1-ssl + namespace: default + allowedRoutes: + namespaces: + from: All + + - name: https-app-artha-link + port: 443 + protocol: HTTPS + hostname: domain2.com + tls: + mode: Terminate + certificateRefs: + - kind: Secret + name: domain2-ssl + namespace: default + allowedRoutes: + namespaces: + from: All + + +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: demo-route + namespace: demo-apps +spec: + parentRefs: + - name: main-gateway + namespace: nginx-gateway + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: app-v1 + port: 80 + + + + + + + +kubectl create -n demo-apps -f - < /dev/null < /dev/null < /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: +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** +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=admin + + +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** +cat < 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 < 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 < 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 < 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 < 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 < 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** + # 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 - < + 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 +------------------------------------------------------------------------------------------------------------------------------ + +--- + +## Servizi DevOps + +-- **db devops** + +apiVersion: v1 +kind: Secret +metadata: + name: pg-app-user + namespace: demo-apps +type: kubernetes.io/basic-auth +stringData: + username: devops + password: KAYQE1QA7uwUZ8uI +--- +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** + +kubectl cnpg psql pg-devops -n devops + +CREATE DATABASE giteadb; +CREATE USER gitea WITH PASSWORD 'KAYQE1QA7uwUZ8uI'; +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 <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: KAYQE1QA7uwUZ8uI + email: gitadmin@italiadatacenter.com + + config: + database: + DB_TYPE: postgres + HOST: pg-devops-rw.devops.svc:5432 + NAME: giteadb + USER: gitea + PASSWD: KAYQE1QA7uwUZ8uI + 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** +#HARBOR +kubectl create namespace harbor + +helm repo add harbor https://helm.goharbor.io +helm repo update + +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 < 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: "KAYQE1QA7uwUZ8uI" + +# ----------------------- +# 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: "KAYQE1QA7uwUZ8uI" + database: registry + sslmode: require + +# ----------------------- +# REDIS (EXTERNAL) +# ----------------------- +redis: + type: external + external: + addr: redis.redis.svc.cluster.local:6379 + password: "KAYQE1QA7uwUZ8uI" + 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 'KAYQE1QA7uwUZ8uI'; +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 - < "$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 </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 < "$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** +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: admin +--- +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=admin" -- 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: KAYQE1QA7uwUZ8uI +--- +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 + + + + + +-------------------------------------------------------------------------------- + +cat < 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** + ------------------------------------------------------------------------------------------------------------------------------ +kubectl create namespace redis +helm repo add bitnami https://charts.bitnami.com/bitnami +helm repo update + + +cat < redisvalues.yaml - +architecture: replication + +auth: + enabled: true + password: KAYQE1QA7uwUZ8uI + +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 KAYQE1QA7uwUZ8uI + + + +########################################################################################################################### +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** + ------------------------------------------------------------------------------------------------------------------------------ +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: KAYQE1QA7uwUZ8uI5 + 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: KAYQE1QA7uwUZ8uI5 + + TEST API: + curl http://localhost:8086/health + + + link svc: + influxdb-influxdb2.influxdb.svc.cluster.local +- **MongoDB** + ------------------------------------------------------------------------------------------------------------------------------ + +- **DbGate** + ------------------------------------------------------------------------------------------------------------------------------ +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** +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: "", nella sezione adminAuth) + +kubectl delete pods node-red-bd88bc7df-knqfw -n nodered + ------------------------------------------------------------------------------------------------------------------------------ + +- **Grafana** + Aggiungere repository Helm Grafana + +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: KAYQE1QA7uwUZ8uI5 + +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: KAYQE1QA7uwUZ8uI5 + + + +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 ################ +helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube +helm repo update + +########### creazione ns e secret db ################ +kubectl create namespace sonarqube + +kubectl create secret generic sonarqube-database-cred \ + --from-literal=username=sonarqube \ + --from-literal=password=KAYQE1QA7uwUZ8uI \ + -n sonarqube + + +########### creazione database ################ +kubectl cnpg psql pg-devops -n devops + +CREATE DATABASE sonarqube; +CREATE USER sonarqube WITH PASSWORD 'KAYQE1QA7uwUZ8uI'; +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 ################ +helm upgrade -f sonarvalues.yaml --install -n sonarqube sonarqube sonarqube/sonarqube --set community.enabled=true,monitoringPasscode="KAYQE1QA7uwUZ8uI" + + + +########### httproute ################ +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** + ------------------------------------------------------------------------------------------------------------------------------ + + + \ No newline at end of file diff --git a/dockerbuild.sh b/dockerbuild.sh new file mode 100644 index 0000000..e69de29 diff --git a/gateway.yaml b/gateway.yaml new file mode 100644 index 0000000..30cf492 --- /dev/null +++ b/gateway.yaml @@ -0,0 +1,134 @@ +apiVersion: v1 +items: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: main-gateway + namespace: nginx-gateway + spec: + gatewayClassName: nginx + listeners: + - allowedRoutes: + namespaces: + from: All + name: http-all + port: 80 + protocol: HTTP + - 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: poc2.italiadatacenter.com + name: https2 + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: poc2-secret + mode: Terminate + - allowedRoutes: + namespaces: + from: All + hostname: k8s.italiadatacenter.com + name: https3 + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: k8s-secret + mode: Terminate + - allowedRoutes: + namespaces: + from: All + hostname: poc3.italiadatacenter.com + name: https4 + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: poc3-secret + mode: Terminate + - allowedRoutes: + namespaces: + from: All + hostname: git.italiadatacenter.com + name: https5 + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: git-secret + mode: Terminate + - allowedRoutes: + namespaces: + from: All + hostname: harbor.italiadatacenter.com + name: https6 + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: harbor-secret + mode: Terminate + - allowedRoutes: + namespaces: + from: All + hostname: git.pigreco66.it + name: httpsp66 + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: p66-secret + mode: Terminate + - allowedRoutes: + namespaces: + from: All + hostname: tekton.italiadatacenter.com + name: https-grafana + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: grafana-secret + mode: Terminate + - allowedRoutes: + namespaces: + from: All + hostname: prometheus.italiadatacenter.com + name: https-prometheus + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: prometheus-secret + mode: Terminate + \ No newline at end of file diff --git a/haproxy.html b/haproxy.html new file mode 100644 index 0000000..ec75aea --- /dev/null +++ b/haproxy.html @@ -0,0 +1,289 @@ + +Statistics Report for HAProxy on POC-Kube-Balancer + + + +

HAProxy version 2.8.16-0ubuntu0.24.04.2, released 2026/04/15

+

Statistics Report for pid 15647 on POC-Kube-Balancer

+
+

> General process information

+
+

pid = 15647 (process #1, nbproc = 1, nbthread = 2)
+uptime = 0d 16h25m19s; warnings = 2
+system limits: memmax = unlimited; ulimit-n = 40082
+maxsock = 40082; maxconn = 20000; reached = 0; maxpipes = 0
+current conns = 7; current pipes = 0/0; conn rate = 1/sec; bit rate = 20.393 kbps
+Running tasks: 0/61; idle = 100 %
+

+ + + + + + +
 active UP  backup UP
active UP, going down backup UP, going down
active DOWN, going up backup DOWN, going up
active or backup DOWN  not checked
active or backup DOWN for maintenance (MAINT)  
active or backup SOFT STOPPED for maintenance  
+Note: "NOLB"/"DRAIN" = UP with load-balancing disabled.
Display option:External resources:
+ + +
rke2_registration_frontend
+ + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
Frontend0
Current connection rate:0/s
Current session rate:0/s
0
Max connection rate:0/s
Max session rate:0/s
-00200000
Cum. connections:0
Cum. sessions:0
00
Response bytes in:0
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
000OPEN

+ + +
rke2_registration_backend
+ + + + + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
POC-Master000-000
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
0-0
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00000
Connection resets during transfers: 0 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master100-000
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
0-0
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00000
Connection resets during transfers: 0 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master200-000
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
0-0
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00000
Connection resets during transfers: 0 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
Backend00000020000
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00
Response bytes in:0
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
0000
Connection resets during transfers: 0 client, 0 server
0016h25m UP 3/330 00s

+ + +
k8s_api_frontend
+ + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
Frontend0
Current connection rate:0/s
Current session rate:0/s
0
Max connection rate:0/s
Max session rate:0/s
-00200000
Cum. connections:0
Cum. sessions:0
00
Response bytes in:0
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
000OPEN

+ + +
k8s_api_backend
+ + + + + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
POC-Master000-000
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
0-0
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00000
Connection resets during transfers: 0 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master100-000
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
0-0
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00000
Connection resets during transfers: 0 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master200-000
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
0-0
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00000
Connection resets during transfers: 0 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
Backend00000020000
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00
Response bytes in:0
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
0000
Connection resets during transfers: 0 client, 0 server
0016h25m UP 3/330 00s

+ + +
stats
+ + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
Frontend1
Current connection rate:1/s
Current session rate:1/s
Current request rate:1/s
1
Max connection rate:1/s
Max session rate:1/s
Max request rate:1/s
-11200005
Cum. connections:5
Cum. sessions:5
- HTTP/1 sessions:5
- HTTP/2 sessions:0
- HTTP/3 sessions:0
- other sessions:0
Cum. HTTP requests:5
- HTTP/1 requests:5
- HTTP/2 requests:0
- HTTP/3 requests:0
- other requests:0
- HTTP 1xx responses:0
- HTTP 2xx responses:3
  Compressed 2xx:0(0%)
- HTTP 3xx responses:0
- HTTP 4xx responses:1
- HTTP 5xx responses:0
- other responses:0
Intercepted requests:5
Cache lookups:0
Cache hits:0(0%)
Failed hdr rewrites:0
Internal errors:0
445266919
Response bytes in:266919
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
000OPEN
Backend00000020000
Cum. sessions:0
New connections:0
Reused connections:0(0%)
Cum. HTTP requests:0
- HTTP 1xx responses:0
- HTTP 2xx responses:0
  Compressed 2xx:0(0%)
- HTTP 3xx responses:0
- HTTP 4xx responses:0
- HTTP 5xx responses:0
- other responses:0
Cache lookups:0
Cache hits:0(0%)
Failed hdr rewrites:0
Internal errors:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Responses time:0 / 0ms
- Total time:0 / 0ms
00s445266919
Response bytes in:266919
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
0000
Connection resets during transfers: 2 client, 0 server
0016h25m UP 0/000 0 

+ + +
nginx_frontend_443
+ + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
Frontend0
Current connection rate:0/s
Current session rate:0/s
32
Max connection rate:32/s
Max session rate:32/s
-23420000467
Cum. connections:467
Cum. sessions:467
322973010172550
Response bytes in:10172550
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
000OPEN

+ + +
nginx_frontend_80
+ + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
Frontend0
Current connection rate:0/s
Current session rate:0/s
13
Max connection rate:13/s
Max session rate:13/s
-013200002114
Cum. connections:2114
Cum. sessions:2114
11493523721025
Response bytes in:3721025
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
001OPEN

+ + +
nginx_backend_80
+ + + + + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
POC-Master000-040
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
4-705
Cum. sessions:705
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:1 / 0ms
- Total time:85512 / 762ms
70549s402634641847000
Connection resets during transfers: 11 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master100-050
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
5-704
Cum. sessions:704
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:1441 / 3ms
- Total time:50001 / 519ms
7041m39s358180453761000
Connection resets during transfers: 4 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master200-040
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
4-704
Cum. sessions:704
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:1 / 0ms
- Total time:83147 / 1152ms
70449s3885382625417000
Connection resets during transfers: 12 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
Backend0001301320002114
Cum. sessions:2114
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:1441 / 2ms
- Total time:85512 / 741ms
211349s11493523721025
Response bytes in:3721025
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
0000
Connection resets during transfers: 28 client, 0 server
0016h25m UP 3/330 00s

+ + +
nginx_backend_443
+ + + + + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
POC-Master000-0110
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
11-156
Cum. sessions:156
Max / Avg over last 1024 success. conn.
- Queue time:5000 / 158ms
- Connect time:1 / 1ms
- Total time:1998998 / 183855ms
1565m14s13437622750246000
Connection resets during transfers: 19 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master100-0101
Current active connections:1
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
11-156
Cum. sessions:156
Max / Avg over last 1024 success. conn.
- Queue time:5001 / 208ms
- Connect time:1 / 1ms
- Total time:1998140 / 133971ms
1567s10336693925075000
Connection resets during transfers: 19 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master200-0111
Current active connections:1
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
12-155
Cum. sessions:155
Max / Avg over last 1024 success. conn.
- Queue time:5001 / 212ms
- Connect time:1 / 1ms
- Total time:1999230 / 108736ms
1558m36s8522993497229000
Connection resets during transfers: 22 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
Backend000322342000467
Cum. sessions:467
Max / Avg over last 1024 success. conn.
- Queue time:5001 / 193ms
- Connect time:1 / 1ms
- Total time:1999230 / 142259ms
4677s322973010172550
Response bytes in:10172550
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
0000
Connection resets during transfers: 60 client, 0 server
0016h25m UP 3/330 00s

+ + +
kubeedge_10000
+ + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
Frontend0
Current connection rate:0/s
Current session rate:0/s
2
Max connection rate:2/s
Max session rate:2/s
-242000035
Cum. connections:35
Cum. sessions:35
968175148781529
Response bytes in:48781529
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
000OPEN

+ + +
kubeedge_backend_10000
+ + + + + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
POC-Master000-010
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
2-12
Cum. sessions:12
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:32992202 / 2751494ms
121h17m967781048778458001
Connection resets during transfers: 2 client, 1 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master100-011
Current active connections:1
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
2-12
Cum. sessions:12
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:10001 / 2729ms
121h17m17881094001
Connection resets during transfers: 1 client, 1 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master200-011
Current active connections:1
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
2-11
Cum. sessions:11
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:10004 / 1444ms
111h17m21531977001
Connection resets during transfers: 2 client, 1 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
Backend000224200035
Cum. sessions:35
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:32992202 / 944759ms
351h17m968175148781529
Response bytes in:48781529
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
0003
Connection resets during transfers: 5 client, 3 server
0016h25m UP 3/330 00s

+ + +
kubeedge_10002
+ + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
Frontend0
Current connection rate:0/s
Current session rate:0/s
5
Max connection rate:5/s
Max session rate:5/s
-022000066
Cum. connections:66
Cum. sessions:66
2611735698
Response bytes in:35698
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
000OPEN

+ + +
kubeedge_backend_10002
+ + + + + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
POC-Master000-020
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
1-22
Cum. sessions:22
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:16153 / 2135ms
223h57m816711327000
Connection resets during transfers: 7 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master100-020
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
1-22
Cum. sessions:22
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:9139 / 1031ms
223h57m888512049000
Connection resets during transfers: 6 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master200-020
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
1-22
Cum. sessions:22
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:10005 / 1384ms
222h44m906512322000
Connection resets during transfers: 7 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
Backend000502200066
Cum. sessions:66
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:16153 / 1516ms
662h44m2611735698
Response bytes in:35698
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
0000
Connection resets during transfers: 20 client, 0 server
0016h25m UP 3/330 00s

+ + +
kubeedge_10004
+ + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
Frontend0
Current connection rate:0/s
Current session rate:0/s
0
Max connection rate:0/s
Max session rate:0/s
-00200000
Cum. connections:0
Cum. sessions:0
00
Response bytes in:0
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
000OPEN

+ + +
kubeedge_backend_10004
+ + + + + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
POC-Master000-000
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
0-0
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00000
Connection resets during transfers: 0 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master100-000
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
0-0
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00000
Connection resets during transfers: 0 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master200-000
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
0-0
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00000
Connection resets during transfers: 0 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
Backend00000020000
Cum. sessions:0
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:0 / 0ms
0?00
Response bytes in:0
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
0000
Connection resets during transfers: 0 client, 0 server
0016h25m UP 3/330 00s

+ + +
mqtt_broker
+ + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
Frontend0
Current connection rate:0/s
Current session rate:0/s
2
Max connection rate:2/s
Max session rate:2/s
-24200001062
Cum. connections:1062
Cum. sessions:1062
37998817426
Response bytes in:17426
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
000OPEN

+ + +
mqtt_broker_backend
+ + + + + + +
QueueSession rateSessionsBytesDeniedErrorsWarningsServer
CurMaxLimitCurMaxLimitCurMaxLimitTotalLbTotLastInOutReqRespReqConnRespRetrRedisStatusLastChkWghtActBckChkDwnDwntmeThrtle
POC-Master000-010
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
2-354
Cum. sessions:354
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:32945639 / 143010ms
3542m26s2674995353000
Connection resets during transfers: 354 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master100-010
Current active connections:0
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
1-354
Cum. sessions:354
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:1 / 1ms
- Total time:50218 / 50087ms
3541m30s566404248000
Connection resets during transfers: 354 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
POC-Master200-012
Current active connections:2
Current used connections:0
Current idle connections:0
- unsafe:0
- safe:0
Estimated need of connections:1
Active connections limit:-
Idle connections limit:-
2-354
Cum. sessions:354
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:0 / 0ms
- Total time:50223 / 49332ms
35434s558497825000
Connection resets during transfers: 349 client, 0 server
0016h25m UP L4OK in 0ms
Layer4 check passed
1/1Y-0
Failed Health Checks
00s-
Backend00022320001062
Cum. sessions:1062
Max / Avg over last 1024 success. conn.
- Queue time:0 / 0ms
- Connect time:1 / 0ms
- Total time:32945639 / 75592ms
106234s37998817426
Response bytes in:17426
Compression in:0
Compression out:0(0%)
Compression bypass:0
Total bytes saved:0(0%)
0000
Connection resets during transfers: 1057 client, 0 server
0016h25m UP 3/330 00s

+ \ No newline at end of file diff --git a/hosts b/hosts new file mode 100644 index 0000000..02db40f --- /dev/null +++ b/hosts @@ -0,0 +1,7 @@ +10.20.1.100 POC-Kube-Balancer +10.20.1.101 POC-Master0 +10.20.1.102 POC-Master1 +10.20.1.103 POC-Master2 +10.20.1.104 POC-Worker0 +10.20.1.105 POC-Worker1 +10.20.1.106 POC-Worker2 diff --git a/installa_haproxy.sh b/installa_haproxy.sh new file mode 100644 index 0000000..bf9e489 --- /dev/null +++ b/installa_haproxy.sh @@ -0,0 +1,123 @@ +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 \ No newline at end of file diff --git a/installazione.md b/installazione.md new file mode 100644 index 0000000..8a0f5e1 --- /dev/null +++ b/installazione.md @@ -0,0 +1,2437 @@ +# 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 < /dev/null < /dev/null < /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 < 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 < 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 < 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 < 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 < 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 < 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 - < + 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 <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 < 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 < 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 - < "$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 </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 < "$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 < 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 < 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: "", 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** + ------------------------------------------------------------------------------------------------------------------------------ + + + diff --git a/iscsiadm-open-iscsi.sh b/iscsiadm-open-iscsi.sh new file mode 100644 index 0000000..5f9ee6b --- /dev/null +++ b/iscsiadm-open-iscsi.sh @@ -0,0 +1,4 @@ +sudo apt install open-iscsi +systemctl enable open-iscsi +systemctl enable iscsid +systemctl restart iscsid.service \ No newline at end of file diff --git a/istruzioni.doc b/istruzioni.doc new file mode 100644 index 0000000..96c2fb0 Binary files /dev/null and b/istruzioni.doc differ diff --git a/istruzioni.docx b/istruzioni.docx new file mode 100644 index 0000000..2256132 Binary files /dev/null and b/istruzioni.docx differ diff --git a/istruzioni.txt b/istruzioni.txt new file mode 100644 index 0000000..8b239e3 --- /dev/null +++ b/istruzioni.txt @@ -0,0 +1,46 @@ +Creazione server: + +3 server RKE2 (master/etcd), + master1.local + master2.local + master3.local + + +1-3 worker nodes: + worker-a.local + worker-b.local + worker-c.local + + +1 Load Balancer (HAProxy) https/http pubblici + loadbalancer.internal + +DNS: rancher.pigreco66.it → IP esterno --> ip loadbalancer.internal + +Sequenza: + +Ogni server + 1)installazione vi (vi.txt) + +Ogni nodomaster e worker + 1) prepara_nodo.sh + +master1: + 1)master_1_installa_rke.sh + +master23: + 1)master23-installa_rke.sh + +Loadbalancer: + 1)installa_haproxy.sh + +worker: + 1)worker-installa_rke2.sh + +Add_on: +1) installa_helm.sh +2) installa-cert-manager.sh +3) kubectt apply -f nginx-controller-service-nodeport.yaml + +poc: +poc-testweb.yaml \ No newline at end of file diff --git a/master23-installa_rke.sh b/master23-installa_rke.sh new file mode 100644 index 0000000..de0c4c4 --- /dev/null +++ b/master23-installa_rke.sh @@ -0,0 +1,56 @@ +# 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 < /dev/null </` dentro `containers//`. +- Rileva il Dockerfile (`dockerfile` oppure `Dockerfile`). +- Costruisce due tag immagine: + - `${REGISTRY_URL}/${REPO_NAME}/${CONTAINER_NAME}:${COMMIT_SHA}` + - `${REGISTRY_URL}/${REPO_NAME}/${CONTAINER_NAME}:latest` +- Esegue push su registry. +- Scrive su file `./imglist` una riga per container: + - `IMAGE_TAG_=` + +Supporto multi-arch: +- Se presente `containers//platform.conf` con chiave `platform=...`, usa `docker buildx build --platform ... --push`. +- In assenza di `platform.conf` usa `docker build` + `docker push` classico. + +Input (argomenti): +- `$1`: `REPO_NAME` (passato dalla pipeline con `${{ github.event.repository.name }}`). +- `$2`: `REGISTRY_URL` (passato da `${{ vars.REGISTRY }}`). + +Prerequisiti runtime: +- Docker daemon disponibile nel runner. +- Permessi push su registry. +- Struttura cartelle coerente tra `containers/` e `src/`. + +### 2) `customize.sh` +Responsabilità funzionale attesa: +- Carica variabili da: + - `env//values.env` + - `properties.env` + - file temporaneo con: + - `TAG=` + - contenuto di `imglist` (generato da `build_container.sh`) +- Cerca tutti i manifest `kubernetes/**/*.yaml`. +- Esegue sostituzione placeholder nel formato `` con i valori trovati. + +Input (argomenti): +- `$1`: ambiente (`dev|qa|prod`). + - In pipeline attuale viene usato `dev`. + +Placeholder parametrizzabili nei manifest: +- Tutte le chiavi presenti in `env//values.env`. +- Tutte le chiavi presenti in `properties.env`. +- `TAG`. +- `IMAGE_TAG_` (una per ciascun container buildato). + +Output: +- Manifest Kubernetes in-place con valori sostituiti. + +### 3) `deploy.sh` +Responsabilità: +- Cerca manifest CNPG (`apiVersion: postgresql.cnpg.io/v1`). +- Se trovato: + - Estrae `metadata.name` del cluster PostgreSQL. + - Ricava namespace dal role `namespace-deployer` nel cluster. + - Crea/aggiorna ConfigMap `service-config` con: + - `tipodb=postgres` + - `urldb=..svc.cluster.local` +- Applica tutti i manifest YAML trovati in `kubernetes/` (directory per directory). +- Invoca `/root/work/pipeline/addlistener.sh` per configurare listener HTTPS sul Gateway. + +Prerequisiti runtime: +- `kubectl` disponibile nel runner. +- `./kubeconfig` presente e valido. +- Opzionale `yq` (se assente, usa fallback con `awk` per estrazione nome CNPG). + +### 4) `addlistener.sh` +Responsabilità: +- Legge la chiave `endpoint` da `properties.env`. +- Calcola token host-based dal dominio. +- Invoca `/root/work/pipeline/add-listener.sh` passando: + - `` + - `https-` + - `-secret` + +Input (argomenti): +- `$1` opzionale: path file properties (default `properties.env`). + +Comportamento: +- Se file non esiste o `endpoint` non valorizzato: termina senza errore bloccante (`exit 0`). + +### 5) `add-listener.sh` +Responsabilità: +- Effettua patch JSON sulla risorsa Gateway Kubernetes: + - Gateway: `main-gateway` + - Namespace: `nginx-gateway` +- Aggiunge un listener HTTPS con certificato TLS da Secret. +- Verifica idempotenza per `name` e `hostname` già presenti. + +Input (argomenti): +- `$1`: `hostname` +- `$2`: `name` +- `$3`: `secret-name` + +## Parametrizzazione complessiva + +### Variabili Gitea Actions +- `vars.REGISTRY`: URL registry target. + +### Secret Gitea Actions +- `secrets.HARBOR_USERNAME` +- `secrets.HARBOR_PASSWORD` +- `secrets.KUBECONFIG_DEV` + +### File di configurazione repository +- `env/dev/values.env` (o `qa`, `prod` se si cambia argomento di `customize.sh`) +- `properties.env` +- `containers//platform.conf` (opzionale) + +### Parametri indiretti derivati +- Nome repository da `${{ github.event.repository.name }}`. +- SHA commit da `git rev-parse HEAD`. +- Tag immagine per servizio in `imglist`. + +## Note operative importanti +1. Il file `imglist` viene creato/appeso da `build_container.sh` e poi letto da `customize.sh`; il job deve mantenere lo stesso workspace tra step. +2. I manifest Kubernetes vengono modificati in-place da `sed -i`. +3. La parte Gateway dipende da: + - presenza di `endpoint` in `properties.env` + - esistenza della risorsa `Gateway/nginx-gateway/main-gateway` + - esistenza del Secret TLS con nome `-secret` + + diff --git a/pipeline/DEV_build_deploy.yaml b/pipeline/DEV_build_deploy.yaml new file mode 100644 index 0000000..211db6d --- /dev/null +++ b/pipeline/DEV_build_deploy.yaml @@ -0,0 +1,36 @@ +name: Build and Deploy + +on: + push: + branches: + - main + +jobs: + docker: + runs-on: POC-Master0 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Login to Harbor + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY }} + username: ${{ secrets.HARBOR_USERNAME }} + password: ${{ secrets.HARBOR_PASSWORD }} + + - name: Build container + run: /root/work/pipeline/build_container.sh ${{ github.event.repository.name }} ${{ vars.REGISTRY }} + + - name: Create kubeconfig + run: | + echo "${{ secrets.KUBECONFIG_DEV }}" > ./kubeconfig + chmod 600 ./kubeconfig + + - name: variables sustitution + run: /root/work/pipeline/customize.sh dev + + - name: k8s deploy + run: /root/work/pipeline/deploy.sh + diff --git a/pipeline/add-listener.sh b/pipeline/add-listener.sh new file mode 100644 index 0000000..d989537 --- /dev/null +++ b/pipeline/add-listener.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# Aggiunge un listener HTTPS direttamente sulla risorsa K8s Gateway +# main-gateway nel namespace nginx-gateway, tramite kubectl patch. +# +# Uso: +# ./add-listener.sh +# +# Esempio: +# ./add-listener.sh sonarqube.italiadatacenter.com https-sonarqube sonarqube-secret + +set -euo pipefail + +GATEWAY_NAME="main-gateway" +GATEWAY_NS="nginx-gateway" + +HOSTNAME_VAL="${1:-}" +NAME_VAL="${2:-}" +SECRET_NAME="${3:-}" + +if [[ -z "$HOSTNAME_VAL" || -z "$NAME_VAL" || -z "$SECRET_NAME" ]]; then + echo "Uso: $0 " + echo "Es.: $0 sonarqube.italiadatacenter.com https-sonarqube sonarqube-secret" + exit 1 +fi + +# Controlla idempotenza: verifica se il listener esiste già per nome o hostname +EXISTING=$(kubectl get gateway "$GATEWAY_NAME" -n "$GATEWAY_NS" \ + -o jsonpath='{.spec.listeners[*].name}') + +if echo "$EXISTING" | grep -qw "$NAME_VAL"; then + echo "Attenzione: listener con name '${NAME_VAL}' già presente. Nessuna modifica." + exit 0 +fi + +EXISTING_HOSTS=$(kubectl get gateway "$GATEWAY_NAME" -n "$GATEWAY_NS" \ + -o jsonpath='{.spec.listeners[*].hostname}') + +if echo "$EXISTING_HOSTS" | grep -qw "$HOSTNAME_VAL"; then + echo "Attenzione: listener con hostname '${HOSTNAME_VAL}' già presente. Nessuna modifica." + exit 0 +fi + +# JSON Patch: aggiunge il nuovo listener in append alla lista +PATCH=$(cat <&2 + exit 0 +fi + +# Estrae endpoint ignorando commenti e spazi, supportando anche endpoint = valore +endpoint_raw="$({ grep -E '^[[:space:]]*endpoint[[:space:]]*=' "$PROPERTIES_FILE" | tail -n1 || true; } | sed -E 's/^[[:space:]]*endpoint[[:space:]]*=[[:space:]]*//')" + +# Rimuove eventuali virgolette e spazi ai bordi +endpoint="$(echo "$endpoint_raw" | sed -E 's/^[[:space:]"\x27]+//; s/[[:space:]"\x27]+$//')" + +if [[ -z "$endpoint" ]]; then + echo "La chiave endpoint non e valorizzata in $PROPERTIES_FILE" >&2 + exit 0 +fi + +# Per calcolare il token usa host pulito (senza schema e path) +host_for_token="${endpoint#*://}" +host_for_token="${host_for_token%%/*}" +token="${host_for_token%%.*}" + +if [[ -z "$token" ]]; then + echo "Impossibile estrarre il token da endpoint: $endpoint" >&2 + exit 1 +fi + +# Output richiesto: https- -secret +/root/work/pipeline/add-listener.sh $endpoint https-$token $token-secret diff --git a/pipeline/build_container.sh b/pipeline/build_container.sh new file mode 100644 index 0000000..17dd172 --- /dev/null +++ b/pipeline/build_container.sh @@ -0,0 +1,58 @@ +#!/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 + + # Cerca sia dockerfile che Dockerfile + if [ -f "$dir/dockerfile" ]; then + DOCKERFILE="$dir/dockerfile" + elif [ -f "$dir/Dockerfile" ]; then + DOCKERFILE="$dir/Dockerfile" + else + echo "Dockerfile non trovato in $dir" + continue + fi + + + + IMAGE_TAG="${REGISTRY_URL}/${REPO_NAME}/${CONTAINER_NAME}:${COMMIT_SHA}" + IMAGE_TAG_LATEST="${REGISTRY_URL}/${REPO_NAME}/${CONTAINER_NAME}:latest" + echo "IMAGE_TAG_${CONTAINER_NAME}=$IMAGE_TAG" >> ./imglist + + PLATFORM_CONF="$dir/platform.conf" + BUILD_PLATFORM="" + if [ -f "$PLATFORM_CONF" ]; then + BUILD_PLATFORM=$(grep -E '^[[:space:]]*platform[[:space:]]*=' "$PLATFORM_CONF" | tail -n 1 | cut -d '=' -f 2- | tr -d '[:space:]') + if [ -n "$BUILD_PLATFORM" ]; then + echo "platform.conf trovato in $dir: uso platform=$BUILD_PLATFORM" + else + echo "platform.conf trovato in $dir ma variabile platform non valorizzata, uso build standard" + fi + fi + + if [ -f "$DOCKERFILE" ]; then + if [ -n "$BUILD_PLATFORM" ]; then + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + docker buildx create --driver docker-container --use + docker buildx inspect --bootstrap + + docker buildx build --platform "$BUILD_PLATFORM" -t "$IMAGE_TAG" -t "$IMAGE_TAG_LATEST" -f "$DOCKERFILE" "$dir" --push + else + docker build -t "$IMAGE_TAG" -t "$IMAGE_TAG_LATEST" -f "$DOCKERFILE" "$dir" + docker push "$IMAGE_TAG" + docker push "$IMAGE_TAG_LATEST" + fi + echo "Build e push completate: $IMAGE_TAG" + else + echo "Dockerfile non trovato in $dir" + fi +done diff --git a/pipeline/customize.sh b/pipeline/customize.sh new file mode 100644 index 0000000..50c6b8e --- /dev/null +++ b/pipeline/customize.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Usage: ./customize.sh dev|qa|prod +echo "tetst" $IMAGE_TAG_backend +ENV=$1 +VALUES_DIR="env/$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) +TMP_VALUES_FILE=$(mktemp) +echo "TAG=$TAG" > "$TMP_TAG_FILE" +cat ./imglist >> "$TMP_TAG_FILE" + + +if [ ! -d "$VALUES_DIR" ] || ! ls "$VALUES_DIR"/*.env &>/dev/null; then + echo "Nessun file .env trovato in $VALUES_DIR" + exit 1 +fi + +if [ ! -f "$PROPERTIES_FILE" ]; then + echo "File $PROPERTIES_FILE non trovato." + exit 1 +fi + +# Crea una lista key=value temporanea partendo da tutti i file *.env in env/$ENV e aggiunge env dinamico +> "$TMP_VALUES_FILE" +for env_file in "$VALUES_DIR"/*.env; do + cat "$env_file" >> "$TMP_VALUES_FILE" + printf '\n' >> "$TMP_VALUES_FILE" +done +printf '\nenv=%s\n' "$ENV" >> "$TMP_VALUES_FILE" + +# 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 < "$TMP_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 +cat "$TMP_VALUES_FILE" +rm -f "$TMP_TAG_FILE" "$TMP_VALUES_FILE" \ No newline at end of file diff --git a/pipeline/deploy.sh b/pipeline/deploy.sh new file mode 100644 index 0000000..113c138 --- /dev/null +++ b/pipeline/deploy.sh @@ -0,0 +1,60 @@ +#!/bin/bash +set -euo pipefail + +# Esegue kubectl apply per ogni sottodirectory di kubernetes separatamente + +YAML_DIR="kubernetes" + +# --------------------------------------------------------------------------- +# Cerca risorse postgresql.cnpg.io/v1 nei manifest e deploya una ConfigMap +# --------------------------------------------------------------------------- +CNPG_FILE=$(grep -rl "postgresql.cnpg.io/v1" "$YAML_DIR" 2>/dev/null | head -1 || true) + +if [ -n "$CNPG_FILE" ]; then + echo "Trovata risorsa postgresql.cnpg.io/v1 in: $CNPG_FILE" + + # Estrae metadata.name dal manifest CNPG preferendo yq, altrimenti awk + if command -v yq >/dev/null 2>&1; then + PG_NAME=$(yq eval 'select(.apiVersion == "postgresql.cnpg.io/v1") | .metadata.name' "$CNPG_FILE") + else + PG_NAME=$(awk '/postgresql\.cnpg\.io\/v1/{found=1} found && /^metadata:/{meta=1} meta && /^\s+name:/{print $2; exit}' "$CNPG_FILE") + fi + + # Ricava il namespace dal Role namespace-deployer presente nel cluster + PG_NS=$(kubectl --kubeconfig=./kubeconfig get role namespace-deployer \ + --no-headers \ + -o custom-columns='NS:.metadata.namespace' 2>/dev/null | head -1 || true) + #PG_NS="${PG_NS:-default}" + + if [ -z "$PG_NAME" ]; then + echo "⚠️ Impossibile estrarre metadata.name dal cluster CNPG, skip ConfigMap." >&2 + else + echo " → cluster: $PG_NAME namespace: $PG_NS" + kubectl --kubeconfig=./kubeconfig apply -f - < /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." + +echo "Eseguo check su endpoint da pubblicare" +/root/work/pipeline/addlistener.sh diff --git a/prepara_nodo.sh b/prepara_nodo.sh new file mode 100644 index 0000000..7701675 --- /dev/null +++ b/prepara_nodo.sh @@ -0,0 +1,36 @@ +# 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 <>/etc/hosts diff --git a/st_migrationlist.xlsx b/st_migrationlist.xlsx new file mode 100644 index 0000000..d56cd14 Binary files /dev/null and b/st_migrationlist.xlsx differ diff --git a/st_size.csv b/st_size.csv new file mode 100644 index 0000000..c6dcf6d --- /dev/null +++ b/st_size.csv @@ -0,0 +1,297 @@ +namespace;tipo;nome;replicas;cpu_req_cores;mem_req_Mi +accessi-enba;deployments;stqrcodeapi;1;0,002;0 +accessi-enbadev;deployments;stqrcodeapi;1;0,002;90 +accessi-enbaqa;deployments;stqrcodeapi;0;0,002;62 +accessi;deployments;nest;1;0,01;200 +accessidev;deployments;nest;1;0,01;200 +accessiqa;deployments;nest;0;0,01;200 +adria;deployments;nginx;1;0,001;0 +agimdev;deployments;allegati;0;0,01;200 +agimdev;deployments;apigateway;0;0,01;200 +agimdev;deployments;geocode;0;0,01;200 +agimdev;deployments;postgrest;0;0;0 +algoranddev;deployments;algo;0;0,01;100 +allenamenti;deployments;nest;1;0,2;1024 +allenamentidev;deployments;nest;1;0,1;512 +allenamentiqa;deployments;nest;0;0,1;512 +anagrafiche;deployments;nest;1;0,5;4096 +anagrafichedev;deployments;nest;1;0,1;512 +anagraficheqa;deployments;nest;0;0,1;512 +cert-manager;deployments;cert-manager;1;0;0 +cert-manager;deployments;cert-manager-cainjector;1;0;0 +cert-manager;deployments;cert-manager-webhook;1;0;0 +companies;deployments;nest;1;0,5;2048 +companiesdev;deployments;nest;1;0,1;512 +companiesqa;deployments;nest;0;0,1;512 +convocazioni;deployments;nest;1;0,1;0 +convocazionidev;deployments;nest;1;0,1;0 +convocazioniqa;deployments;nest;0;0,1;0 +db;deployments;adminer;1;0,002;0 +db;deployments;filebrowser2;1;0,01;0 +db;deployments;nfs-server;1;0,002;0 +db;deployments;nginx;1;0,001;0 +db;deployments;php;1;0,002;0 +db;deployments;postgrestadmin;0;0;0 +db;deployments;postgrestadminmatch;0;0;0 +dbdev;deployments;filebrowser2;1;0,001;8 +dbdev;deployments;nfs-server;1;0,002;186 +dbdev;deployments;nginx;1;0,001;4 +dbdev;deployments;php;1;0,002;8 +dbqa;deployments;filebrowser2;0;0,1;0 +dbqa;deployments;nfs-server;0;0,001;186 +dbqa;deployments;nginx;0;0,001;7 +dbqa;deployments;php;0;0,002;8 +default;deployments;locust-master;0;0;0 +default;deployments;locust-worker;0;0;0 +demodev;deployments;nginx;2;0,01;100 +dev;deployments;nginx;0;0;0 +enbabeapi;deployments;nest;1;0,1;0 +enbabeapidev;deployments;nest;1;0,1;0 +enbafe;deployments;nginx;1;0;0 +enbafedev;deployments;nginx;1;0,001;8 +eventi-wow;deployments;nest;1;0,1;0 +eventi-wowdev;deployments;nest;1;0,1;0 +eventi-wowqa;deployments;nest;0;0,1;0 +eventi;deployments;nest;1;0,1;0 +eventidev;deployments;nest;1;0,1;0 +eventiqa;deployments;nest;0;0,1;0 +frontend-club;deployments;nginx;1;0,1;200 +frontend-clubdev;deployments;nginx;1;0,001;3 +frontend-clubqa;deployments;nginx;0;0,001;3 +frontend-limec;deployments;nginx;1;0;0 +frontend-limecdev;deployments;nginx;1;0;0 +frontend-limecqa;deployments;nginx;1;0;0 +frontend-matchdev;deployments;nginx;1;0;0 +frontend-sestra;deployments;nginx;1;0;0 +frontend-sestradev;deployments;nginx;1;0;0 +frontend-sestraqa;deployments;nginx;0;0;0 +frontend-wow;deployments;nginx;1;0,001;0 +frontend-wowdev;deployments;nginx;1;0,001;3 +frontend-wowqa;deployments;nginx;0;0,001;3 +gare;deployments;nest;1;0,3;0 +garedev;deployments;nest;1;0,1;0 +gareqa;deployments;nest;0;0,1;768 +gateway-accessi;deployments;nest;1;0,1;0 +gateway-accessidev;deployments;nest;1;0,1;0 +gateway-accessiqa;deployments;nest;0;0,1;0 +gateway-club;deployments;nest;4;0,5;4096 +gateway-clubdev;deployments;nest;1;0,3;1024 +gateway-clubqa;deployments;nest;0;0,1;0 +gateway-csi;deployments;nest;1;0,1;0 +gateway-csidev;deployments;nest;1;0,1;0 +gateway-csiqa;deployments;nest;0;0,1;0 +gateway-limec;deployments;nest;4;0,5;4096 +gateway-limecdev;deployments;nest;1;0,3;1024 +gateway-match;deployments;nest;1;0,1;0 +gateway-matchdev;deployments;nest;1;0,1;0 +gateway-matchqa;deployments;nest;0;0,1;0 +geco;deployments;nginx;1;0,001;0 +gecobe;deployments;nest;1;0,1;0 +gecobedev;deployments;nest;1;0,1;0 +gecobeqa;deployments;nest;0;0,1;0 +gecodev;deployments;nginx;1;0,001;3 +gecoqa;deployments;nginx;0;0,001;3 +giornalistadev;deployments;nginx;1;0,01;100 +gke-connect;deployments;gke-connect-agent-20210430-00-00;1;0,002;0 +grafana;deployments;grafana;0;0,002;0 +homepage;deployments;nginx;1;0;0 +homepagedev;deployments;nginx;1;0,002;5 +ingress-nginx2;deployments;nginx2-nginx-ingress;1;1;2000 +isclubdev;deployments;apiserver;1;0,1;0 +isclubdev;deployments;identityserver;1;0,1;0 +isclubdev;deployments;isadmin;1;0,1;0 +isclubqa;deployments;apiserver;0;0,1;0 +isclubqa;deployments;identityserver;0;0,1;0 +isclubqa;deployments;isadmin;0;0,1;0 +iscsi;deployments;apiserver;1;0,002;0 +iscsi;deployments;identityserver;1;0,002;0 +iscsi;deployments;isadmin;1;0,002;0 +iscsidev;deployments;apiserver;1;0,1;0 +iscsidev;deployments;identityserver;1;0,1;0 +iscsidev;deployments;isadmin;1;0,1;0 +iscsiqa;deployments;apiserver;0;0,002;70 +iscsiqa;deployments;identityserver;0;0,002;78 +iscsiqa;deployments;isadmin;0;0,002;70 +isenba;deployments;apiserver;1;0,1;0 +isenba;deployments;identityserver;1;0,1;0 +isenba;deployments;isadmin;1;0,1;0 +isenbadev;deployments;apiserver;1;0,1;0 +isenbadev;deployments;identityserver;1;0,1;0 +isenbadev;deployments;isadmin;1;0,1;0 +isenbaqa;deployments;apiserver;0;0,1;0 +isenbaqa;deployments;identityserver;0;0,1;0 +isenbaqa;deployments;isadmin;0;0,1;0 +ismatch;deployments;apiserver;1;0,002;0 +ismatch;deployments;identityserver;1;0,002;0 +ismatch;deployments;isadmin;1;0,002;0 +ismatchdev;deployments;apiserver;1;0,1;0 +ismatchdev;deployments;identityserver;1;0,1;0 +ismatchdev;deployments;isadmin;1;0,1;0 +ismatchqa;deployments;apiserver;0;0,002;64 +ismatchqa;deployments;identityserver;0;0,002;80 +ismatchqa;deployments;isadmin;0;0,002;59 +ispub;deployments;apiserver;1;0,002;0 +ispub;deployments;identityserver;1;0,002;0 +ispub;deployments;isadmin;1;0,002;0 +ispubdev;deployments;apiserver;1;0,1;0 +ispubdev;deployments;identityserver;1;0,1;0 +ispubdev;deployments;isadmin;1;0,1;0 +ispubqa;deployments;apiserver;0;0,002;69 +ispubqa;deployments;identityserver;0;0,002;84 +ispubqa;deployments;isadmin;0;0,002;60 +isstaysafe-primario;deployments;apiserver;1;0,1;0 +isstaysafe-primario;deployments;identityserver;1;0,1;0 +isstaysafe-primario;deployments;isadmin;1;0,1;0 +isstaysafe-primariodev;deployments;apiserver;1;0,1;0 +isstaysafe-primariodev;deployments;identityserver;1;0,1;0 +isstaysafe-primariodev;deployments;isadmin;1;0,1;0 +isstaysafe-primarioqa;deployments;apiserver;0;0,1;0 +isstaysafe-primarioqa;deployments;identityserver;0;0,1;0 +isstaysafe-primarioqa;deployments;isadmin;0;0,1;0 +isstaysafe;deployments;apiserver;1;0,002;0 +isstaysafe;deployments;identityserver;1;0,002;0 +isstaysafe;deployments;isadmin;1;0,002;0 +isstaysafedev;deployments;apiserver;1;0,002;80 +isstaysafedev;deployments;identityserver;1;0,002;76 +isstaysafedev;deployments;isadmin;1;0,002;61 +isstaysafeqa;deployments;apiserver;0;0,002;67 +isstaysafeqa;deployments;identityserver;0;0,002;83 +isstaysafeqa;deployments;isadmin;0;0,002;59 +kube-downscaler;deployments;kube-downscaler;1;0,03;0 +kube-system;deployments;konnectivity-agent;8;0,015;60 +kube-system;deployments;konnectivity-agent-autoscaler;1;0,01;10 +kube-system;deployments;kube-dns;3;0,27;155 +kube-system;deployments;kube-dns-autoscaler;1;0,02;10 +kube-system;deployments;kube-state-metrics;1;0;0 +kube-system;deployments;l7-default-backend;1;0,01;20 +kube-system;deployments;metrics-server-v1,35,1;1;0,065;231 +kube-system;deployments;tiller-deploy;0;0;0 +licenze;deployments;nest;1;0,01;200 +licenzedev;deployments;nest;1;0,01;200 +licenzeqa;deployments;nest;0;0,01;200 +limecaccessi;deployments;nest;1;0,01;200 +limecaccessidev;deployments;nest;1;0,01;200 +limecallenamenti;deployments;nest;1;0,2;1024 +limecallenamentidev;deployments;nest;1;0,1;512 +limecanagrafiche;deployments;nest;1;0,5;2048 +limecanagrafichedev;deployments;nest;1;0,1;512 +limeccarriere;deployments;nest;1;0,5;2048 +limeccarrieredev;deployments;nest;1;0,1;512 +limeccompanies;deployments;nest;1;0,5;2048 +limeccompaniesdev;deployments;nest;1;0,1;512 +limecconvocazioni;deployments;nest;1;0,1;0 +limecconvocazionidev;deployments;nest;1;0,1;0 +limeceventi;deployments;nest;1;0,1;0 +limeceventidev;deployments;nest;1;0,1;0 +limecgare;deployments;nest;1;0,3;0 +limecgaredev;deployments;nest;1;0,1;0 +limeclicenze;deployments;nest;1;0,01;200 +limeclicenzedev;deployments;nest;1;0,01;200 +limecmailsms;deployments;nest;1;0,1;0 +limecmailsmsdev;deployments;nest;1;0,1;0 +limecmoduli;deployments;nest;1;0,5;2048 +limecmodulidev;deployments;nest;1;0,1;0 +limecnotifiche;deployments;nest;1;0,01;200 +limecnotifichedev;deployments;nest;1;0,01;200 +limecsponsor;deployments;nest;1;0,5;2048 +limecsponsordev;deployments;nest;1;0,1;0 +limecstrutture;deployments;nest;1;0,1;0 +limecstrutturedev;deployments;nest;1;0,1;0 +limecsupertokens;deployments;supertoken;1;0,1;200 +limecsupertokensdev;deployments;supertoken;1;0,1;200 +localita;deployments;nest;1;0,1;0 +localitadev;deployments;nest;1;0,1;0 +localitaqa;deployments;nest;0;0,1;0 +mailsms;deployments;nest;1;0,1;0 +mailsmsdev;deployments;nest;1;0,1;0 +mailsmsqa;deployments;nest;0;0,1;0 +mockapidev;deployments;node;1;0,001;35 +moduli;deployments;nest;1;0,5;2048 +modulidev;deployments;nest;1;0,1;0 +moduliqa;deployments;nest;0;0,1;0 +mongodb;deployments;mongo-express;1;0,002;0 +mongodb;deployments;mongodb-kubernetes-operator;1;0,002;0 +mongodbdev;deployments;mongo-express;1;0,002;61 +mongodbdev;deployments;mongodb-kubernetes-operator;1;0,002;18 +mongodbqa;deployments;mongodb-kubernetes-operator;0;0,002;16 +nocodbdev;deployments;nocodb;1;0,01;100 +notifiche;deployments;nest;1;0,01;200 +notifichedev;deployments;nest;1;0,01;200 +notificheqa;deployments;nest;0;0,01;200 +pgare;deployments;nginx;0;0,002;0 +pgare;deployments;nodepgare;1;0,001;0 +pgare;deployments;postgrest;1;0,004;0 +pgare;deployments;pwafed;1;0,001;0 +pgaredev;deployments;nginx;0;0,001;3 +pgaredev;deployments;nodepgare;0;0,1;0 +pgaredev;deployments;postgrest;0;0,003;19 +pgaredev;deployments;pwafed;0;0,001;4 +prenotazione;deployments;prenotazione;1;0,003;0 +prenotazionedev;deployments;prenotazione;1;0,1;0 +prenotazioneqa;deployments;prenotazione;0;0,003;121 +prenotazioni-clubdev;deployments;prenotazione;1;0,1;0 +prenotazioni-clubqa;deployments;prenotazione;0;0,002;37 +prenotazioni-csi;deployments;prenotazione;1;0,003;0 +prenotazioni-csidev;deployments;prenotazione;1;0,1;0 +prenotazioni-csiqa;deployments;prenotazione;0;0,003;122 +prenotazioni-enba;deployments;prenotazione;1;0,1;0 +prenotazioni-enbadev;deployments;prenotazione;1;0,1;0 +prenotazioni-enbaqa;deployments;prenotazione;0;0,1;0 +qrcodeapi;deployments;stqrcodeapi;0;0,002;0 +rabbitmq-system;deployments;rabbitmq-cluster-operator;1;0,2;500 +referti;deployments;nest;1;0,1;256 +refertidev;deployments;nest;1;0,1;256 +refertiqa;deployments;nest;0;0,1;0 +sestrabeapi;deployments;nest;1;0,1;0 +sestrabeapidev;deployments;nest;1;0,1;0 +sestrabeapiqa;deployments;nest;0;0,1;0 +sonarq;deployments;sonarqube;0;0,009;0 +sponsor;deployments;nest;1;0,5;2048 +sponsordev;deployments;nest;1;0,1;0 +sponsorqa;deployments;nest;0;0,1;0 +stayrsa;deployments;nginx;1;0,001;0 +stayrsadev;deployments;nginx;1;0,001;8 +stayrsaqa;deployments;nginx;0;0,001;4 +staysafebeapi;deployments;nest;1;0,1;0 +staysafebeapidev;deployments;nest;1;0,1;0 +staysafebeapiqa;deployments;nest;0;0,06;581 +staysafebeqa;deployments;nodestaysafebe;0;0,08;505 +strutture;deployments;nest;1;0,1;0 +strutturedev;deployments;nest;1;0,1;0 +struttureqa;deployments;nest;0;0,1;0 +supertokens;deployments;supertoken;1;0,1;200 +supertokens;deployments;supertoken-match;1;0,1;200 +supertokens;deployments;supertoken-sestra;1;0,101;200 +supertokensdev;deployments;supertoken;1;0,1;200 +supertokensdev;deployments;supertoken-match;1;0,1;200 +supertokensdev;deployments;supertoken-sestra;1;0,101;200 +supertokensqa;deployments;supertoken;0;0,1;200 +supertokensqa;deployments;supertoken-match;0;0,1;200 +supertokensqa;deployments;supertoken-sestra;0;0,101;200 +tornei;deployments;nest;1;0,01;200 +torneidev;deployments;nest;1;0,01;200 +torneiqa;deployments;nest;0;0,01;200 +utenti-sporteamsdev;deployments;nest;1;0,1;0 +utenti-sporteamsqa;deployments;nest;0;0,1;0 +verdaccio;deployments;verdaccio;1;0,001;0 +webhooks;deployments;nest;1;0,01;200 +webhooksdev;deployments;nest;1;0,01;200 +webhooksqa;deployments;nest;0;0,01;200 +db;statefulsets;limecrabbitmqcluster-server;1;0,1;1024 +db;statefulsets;postgresql-1-postgresql;1;1,5;3000 +db;statefulsets;rabbitmqcluster-server;1;0,1;1024 +db16;statefulsets;postgresql-16-postgresql;1;0,1;100 +dbdev;statefulsets;limecrabbitmqcluster-server;1;0,1;1024 +dbdev;statefulsets;postgresql-1-postgresql;1;0,1;100 +dbdev;statefulsets;rabbitmqcluster-server;3;0,1;1024 +dbdev16;statefulsets;postgresql-16-postgresql;1;0,1;100 +dbqa;statefulsets;limecrabbitmqcluster-server;1;0,1;1024 +dbqa;statefulsets;postgresql-1-postgresql;0;0,1;100 +dbqa;statefulsets;rabbitmqcluster-server;1;0,1;1024 +dbqa16;statefulsets;postgresql-16-postgresql;1;0,1;100 +isdb;statefulsets;postgresql-1-postgresql;1;0,1;100 +isdbdev;statefulsets;postgresql-1-postgresql;0;0,1;100 +isdbqa;statefulsets;postgresql-1-postgresql;0;0,1;100 +mongodb;statefulsets;mongodb-replica-set;3;0,4;400 +mongodbdev;statefulsets;mongodb-replica-set;3;0,4;400 +mongodbqa;statefulsets;mongodb-replica-set;0;0,4;400 \ No newline at end of file diff --git a/st_size.xlsx b/st_size.xlsx new file mode 100644 index 0000000..33e42db Binary files /dev/null and b/st_size.xlsx differ diff --git a/template.txt b/template.txt new file mode 100644 index 0000000..6ad6075 --- /dev/null +++ b/template.txt @@ -0,0 +1,135 @@ +Template architetturali + +1) fronteend (nginx) + backend (nodejs) +2) fronteend (nginx) + backend (nodejs) + db Postgresql +3) fronteend (nginx) + backend (nodejs) + db Mysql +4) fronteend (nginx) + backend (nodejs) + db mongoDb +5) fronteend (nginx) + backend (nodejs) + db mongoDb + S3 +6) fronteend (nginx) + backend (nodejs) + db InfluxDb + S3 + + +Opzione proporre i vari "Lego Bricks" da comporre come vuoi + +--- + +# 🧱 Categorie di template (essenziali) + +## 1️⃣ Microservizio Backend (core della piattaforma) + +### 🎯 Use case + +* API REST +* business logic +* servizi core + +### 🔧 Stack tipici + +* Java (Spring Boot) +* Node.js (NestJS) +* Python (FastAPI) + + +--- + +## 2️⃣ Worker / Job / Event-driven + +### 🎯 Use case + +* consumer Kafka / RabbitMQ +* batch processing +* cron job + +### 📦 Include + +* queue integration +* retry / DLQ +* idempotenza +* scaling (HPA su queue) + +--- + +## 3️⃣ Frontend Web App + + +### 🎯 Use case + +* UI applicativa + +### 🔧 Stack + +* React / Angular / Vue + + +--- + +## 4️⃣ API Gateway / BFF + + +### 🎯 Use case + +* orchestrazione API +* security +* aggregation + +### 📦 Include + +* auth (OIDC) +* rate limit +* routing + +--- + +## 5️⃣ Data Service (DB-enabled service) + +### 🎯 Use case + +* servizi con DB dedicato + +### 📦 Include + +* provisioning DB (CNPG 👀) +* migration (Flyway/Liquibase) +* backup automatico +* secret injection + + +## 6️⃣ AI / Batch / Data Pipeline (avanzato) + +### 🎯 Use case + +* ETL +* ML +* data processing + +--------------------------------------------------------------------- + +# 🧩 Template trasversali (fondamentali) + +## 🔐 Security baseline + +* OIDC (Keycloak) +* RBAC +* Secret management + + +## 📊 Observability + +* logging (Loki) +* metrics (Prometheus) +* tracing (Tempo) + +## 🚀 CI/CD template + +* build +* scan (SAST, container) +* deploy +* rollback + + +## 🧪 Testing + +* unit +* integration +* contract test + + diff --git a/todo_list.txt b/todo_list.txt new file mode 100644 index 0000000..203ab65 --- /dev/null +++ b/todo_list.txt @@ -0,0 +1,32 @@ +attività: + +backup database +-->backup etcd +gestione centralizzta log +-->idp portal - k8s Ui + log +idp portal - identificare legobrick +idp portal - formato file legobrick +idp portal - formato file architettura +idp portal - display architettura componente +idp portal - display palette legobrick +idp portal - funzioni UI di drag and drop +idp portal - comandi git di merge template repo +idp portal - remove componenti +idp portal - autenticazione/profilazione +idp portal - accesso log applicativi +Kyverno - installazione +Kyverno - predisposizione policy per taint autmatica edgenode +-->kubeedge - label/taint per progetto +git - gestione release + + +git tagging +curl -X 'POST' \ + 'https://git.italiadatacenter.com/api/v1/repos/STS_Lab/idcidp/tags?access_token=65fc5f07365bd3f89c5b9ddca3d2d2e7b3777a88' \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "message": "string", + "tag_name": "v1.0", + "target": "ab3e33a214" +}' \ No newline at end of file diff --git a/utils.txt b/utils.txt new file mode 100644 index 0000000..f9dfcc8 --- /dev/null +++ b/utils.txt @@ -0,0 +1,59 @@ + +#master node + cd /etc/rancher/rke2/ + sudo systemctl restart rke2-server.service + journalctl -xeu rke2-server.service -f + +#worker node +sudo systemctl restart rke2-agent.service +sudo systemctl stop rke2-agent.service + +sudo systemctl start rke2-agent.service +journalctl -xeu rke2-agent.service -f +cat /var/lib/rancher/rke2/agent/logs/kubelet.log + + +#load balancer +/etc/haproxy/haproxy.cfg +sudo systemctl restart haproxy +journalctl -xeu haproxy.service -f +tail -f /var/log/haproxy.log +http://:8080/stats (admin/admin) + +Console rancher: https://rancher.pigreco66.it/ (AdminJapp0cam) + + +************Check risorse*************** +kubectl resource-capacity + + +kubectl create -n demo-apps -f - < /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