From 63649a642a9681bb72bd6d3cd0862de43a6d5510 Mon Sep 17 00:00:00 2001 From: alessandro barucci Date: Sun, 20 Sep 2026 19:26:05 +0200 Subject: [PATCH] varie --- .../Dockerfile.byo-agent-example | 21 +++ add-on/AgentPlatform/IDP-AgentPlatform.docx | Bin 0 -> 19239 bytes .../Langflow/Langflow installazione.txt | 7 + .../Langflow/langflow-httproute.yaml | 61 +++++++ .../Langflow/langflow-secrets-setup.sh | 35 ++++ .../Langflow/langflow-values.yaml | 87 +++++++++ .../agent-declarative-vs-byo.yaml | 166 ++++++++++++++++++ add-on/monitoring/blackbox-exporter.md | 126 ++++++++++++- pipeline/add-hostalias.sh | 75 ++++++++ pipeline/addlistener.sh | 8 +- pipeline/deploy.sh | 37 ---- 11 files changed, 578 insertions(+), 45 deletions(-) create mode 100644 add-on/AgentPlatform/Dockerfile.byo-agent-example create mode 100644 add-on/AgentPlatform/IDP-AgentPlatform.docx create mode 100644 add-on/AgentPlatform/Langflow/Langflow installazione.txt create mode 100644 add-on/AgentPlatform/Langflow/langflow-httproute.yaml create mode 100644 add-on/AgentPlatform/Langflow/langflow-secrets-setup.sh create mode 100644 add-on/AgentPlatform/Langflow/langflow-values.yaml create mode 100644 add-on/AgentPlatform/agent-declarative-vs-byo.yaml create mode 100644 pipeline/add-hostalias.sh diff --git a/add-on/AgentPlatform/Dockerfile.byo-agent-example b/add-on/AgentPlatform/Dockerfile.byo-agent-example new file mode 100644 index 0000000..d17151d --- /dev/null +++ b/add-on/AgentPlatform/Dockerfile.byo-agent-example @@ -0,0 +1,21 @@ +# Dockerfile di esempio — containerizza un flow esportato da Langflow +# come Python app standalone, da usare nel percorso BYO (Esempio B). + +FROM python:3.11-slim + +WORKDIR /app + +# requirements.txt generato/estratto insieme all'export del flow +# (langflow, langgraph-checkpointer-kagent, e le dipendenze del tuo flow) +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Codice esportato dal builder low-code + eventuali customizzazioni +# del developer (es. integrazione kagentCheckpointer se usi LangGraph) +COPY . . + +# L'agente deve esporre un endpoint compatibile A2A sulla porta +# dichiarata in byo.deployment.port dell'Agent CR +EXPOSE 8080 + +CMD ["python", "agent_server.py"] diff --git a/add-on/AgentPlatform/IDP-AgentPlatform.docx b/add-on/AgentPlatform/IDP-AgentPlatform.docx new file mode 100644 index 0000000000000000000000000000000000000000..d82f72aa98f287f4baf058ccd9ea9aebf4e7f414 GIT binary patch literal 19239 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" + +# 3. Secret credenziali LLM — STESSO Secret già usato per kagent nel +# golden path di onboarding-team: se lo hai già creato per kagent +# in questo namespace, questo passaggio è già fatto, verifica solo +# che contenga le chiavi coi nomi attesi (vedi sotto). +# +# Se non esiste ancora, crealo così (aggiungi/rimuovi provider a +# seconda di cosa serve al team): +kubectl create secret generic llm-credentials \ + -n langflow-team-alpha \ + --from-literal=openai-api-key="sk-..." \ + --from-literal=anthropic-api-key="sk-ant-..." + +# Se il Secret esiste già (es. creato per kagent) e vuoi solo +# aggiungere/aggiornare una chiave senza ricrearlo da zero: +kubectl patch secret llm-credentials -n langflow-team-alpha \ + --type=json \ + -p='[{"op":"add","path":"/data/openai-api-key","value":"'$(echo -n "sk-..." | base64)'"}]' + +# 4. Verifica che tutti i Secret siano presenti prima di installare/ +# aggiornare la release Helm +kubectl get secrets -n langflow-team-alpha diff --git a/add-on/AgentPlatform/Langflow/langflow-values.yaml b/add-on/AgentPlatform/Langflow/langflow-values.yaml new file mode 100644 index 0000000..632ff97 --- /dev/null +++ b/add-on/AgentPlatform/Langflow/langflow-values.yaml @@ -0,0 +1,87 @@ +# values.yaml — Langflow IDE, personalizzato per un namespace-tenant +# Uso: helm install langflow-ide langflow/langflow-ide -f values.yaml -n + +langflow: + backend: + image: + repository: langflowai/langflow + tag: "1.10.0" # fissa una versione esplicita, evita 'latest' in produzione + + resources: + requests: + cpu: 250m + memory: 512Mi + limits: + cpu: "1" + memory: 2Gi + + # Variabili LLM/DB — usa Secret, mai valori in chiaro qui + env: + - name: LANGFLOW_DATABASE_URL + valueFrom: + secretKeyRef: + name: langflow-db-secret + key: connection-string + - name: LANGFLOW_SUPERUSER + valueFrom: + secretKeyRef: + name: langflow-admin-secret + key: username + - name: LANGFLOW_SUPERUSER_PASSWORD + valueFrom: + secretKeyRef: + name: langflow-admin-secret + key: password + # Rimuove automaticamente eventuali API key salvate nei flow prima + # di persisterli a DB — best practice di sicurezza, seconda linea + # di difesa oltre alle Global Variable qui sotto + - name: LANGFLOW_REMOVE_API_KEYS + value: "true" + + # --- Pre-caricamento credenziali LLM come Global Variable --- + # Riusa lo stesso Secret 'llm-credentials' già previsto per kagent + # in fase di onboarding del team (vedi golden path Backstage). + # I developer trovano le chiavi già pronte nel dropdown Global + # Variable, senza mai vederne il valore reale. + - name: LANGFLOW_STORE_ENVIRONMENT_VARIABLES + value: "true" + - name: LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT + value: "OPENAI_API_KEY,ANTHROPIC_API_KEY" + - name: OPENAI_API_KEY + valueFrom: + secretKeyRef: + name: llm-credentials + key: openai-api-key + optional: true # non tutti i team useranno tutti i provider + - name: ANTHROPIC_API_KEY + valueFrom: + secretKeyRef: + name: llm-credentials + key: anthropic-api-key + optional: true + + frontend: + image: + repository: langflowai/langflow + tag: "1.10.0" + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + +# Ingress classico DISABILITATO — l'esposizione avviene via Gateway API +# (nginx Gateway Fabric), vedi manifest separato langflow-httproute.yaml +ingress: + enabled: false + +# Il Service del frontend resta ClusterIP (default del chart), sarà +# l'HTTPRoute a instradare il traffico dal Gateway verso questo Service + +# Persistenza dei flow salvati (altrimenti persi al riavvio del pod) +persistence: + enabled: true + size: 5Gi + storageClassName: standard # adatta alla tua StorageClass diff --git a/add-on/AgentPlatform/agent-declarative-vs-byo.yaml b/add-on/AgentPlatform/agent-declarative-vs-byo.yaml new file mode 100644 index 0000000..8a43ca1 --- /dev/null +++ b/add-on/AgentPlatform/agent-declarative-vs-byo.yaml @@ -0,0 +1,166 @@ +# ===================================================================== +# ESEMPIO A — Agent dichiarativo nativo (kagent esegue direttamente) +# Caso d'uso: flow Langflow/Flowise semplice — un LLM + un paio di tool, +# nessuna logica custom complessa. Tradotto 1:1 in prompt + tool MCP. +# ===================================================================== +apiVersion: kagent.dev/v1alpha2 +kind: Agent +metadata: + name: k8s-troubleshooter + namespace: team-alpha +spec: + description: Agente di troubleshooting Kubernetes + type: Declarative + declarative: + modelConfig: gpt4o-config + systemMessage: | + Sei un agente di troubleshooting per Kubernetes... + a2aConfig: + skills: + - id: diagnose-pod-issue + name: Diagnose Pod Issue + description: Investiga problemi su pod/servizi Kubernetes + inputModes: ["text"] + outputModes: ["text"] + tags: ["kubernetes"] + tools: + - type: McpServer + mcpServer: + name: kagent-tool-server + kind: RemoteMCPServer + toolNames: + - k8s_get_pods + - k8s_describe_pod + - k8s_get_logs +--- +apiVersion: kagent.dev/v1alpha1 +kind: ModelConfig +metadata: + name: gpt4o-config + namespace: team-alpha +spec: + provider: OpenAI + model: gpt-4o + apiKeySecretRef: + name: llm-credentials + key: openai-api-key + + + + +# invocazione +Le 4 modalità di invocazione +1. Dashboard kagent (per gli utenti umani, uso interattivo) +bash +kagent dashboard + +Apre una UI web dove cerchi k8s-troubleshooter nella lista e chatti direttamente — il modo più immediato per un developer che vuole testare l'agente senza altri strumenti. + +2. CLI kagent (per script, pipeline, debug da terminale) +bash +kagent invoke --agent k8s-troubleshooter -n team-alpha \ + --task "Il pod payment-service-7d9f in default sta crashando, investiga" +3. Chiamata diretta via A2A REST (per integrazione da altri sistemi/servizi) + +Ogni Agent espone un endpoint A2A standard, con un "agent card" che ne descrive le capability: + +bash +kubectl port-forward -n kagent svc/kagent-service 8083:8083 + +# scopri le capability dell'agente +curl localhost:8083/api/a2a/team-alpha/k8s-troubleshooter/.well-known/agent.json + +# invocalo +curl -X POST localhost:8083/api/a2a/team-alpha/k8s-troubleshooter/ \ + -H "Content-Type: application/json" \ + -d '{"task": "Perché il pod payment-service sta in CrashLoopBackOff?"}' + +Questa è la via che useresti se, ad esempio, un tuo servizio interno (o un'automazione CI/CD) deve invocare l'agente programmaticamente. + +4. Canali chat (Slack/Teams/Discord/Telegram) — via AgentHarness CRD + +Se vuoi che i developer interroghino l'agente direttamente da Slack invece che aprire la dashboard, kagent ha una CRD dedicata (AgentHarness) che fa da ponte: + +yaml +apiVersion: kagent.dev/v1alpha2 +kind: AgentHarness +metadata: + name: k8s-troubleshooter-slack + namespace: kagent +spec: + backend: hermes + modelConfigRef: default-model-config + channels: + - name: platform + type: slack + slack: + botToken: + valueFrom: {type: Secret, name: slack-tokens, key: bot-token} + appToken: + valueFrom: {type: Secret, name: slack-tokens, key: app-token} + +Poi in Slack: /mykagent perché il pod X sta crashando? — il bot inoltra la richiesta all'agente via A2A e posta la risposta nel canale. Interessante per un'IDP perché è il canale più naturale per i developer, senza dover imparare dashboard o CLI dedicate. + +# ===================================================================== +# ESEMPIO B — Agent BYO (Bring Your Own), container esportato da +# Langflow/Flowise dopo containerizzazione custom. +# Caso d'uso: flow complesso con logica di stato/loop che il developer +# ha personalizzato oltre quello che il builder low-code esporta, +# quindi ha bisogno di pieno controllo del codice. +# ===================================================================== +apiVersion: kagent.dev/v1alpha1 +kind: Agent +metadata: + name: currency-exchange-agent + namespace: team-alpha +spec: + type: BYO + byo: + deployment: + image: ghcr.io/team-alpha/langflow-currency-agent:latest + workingDir: /app + env: + - name: GOOGLE_API_KEY + valueFrom: + secretKeyRef: + name: llm-credentials + key: gemini-api-key + port: 8080 # porta su cui l'agente espone l'endpoint A2A + + # Nota: kagent invoca questo agente via protocollo A2A, trattandolo + # come black box — nessuna decomposizione in prompt/tool separati, + # perché la logica vive interamente dentro l'immagine. + + +## Esempio Agent di Orchestrazione +apiVersion: kagent.dev/v1alpha2 +kind: Agent +metadata: + name: incident-commander + namespace: team-alpha +spec: + type: Declarative + declarative: + systemMessage: | + Sei il coordinatore per la gestione incidenti. Quando ricevi una + segnalazione, decidi quali specialisti coinvolgere: se riguarda + pod/servizi K8s, delega al k8s-troubleshooter; se servono i log, + delega al log-analyzer. Puoi chiamare entrambi in sequenza se + il problema lo richiede. + modelConfig: gpt4o-config + tools: + - type: McpServer + mcpServer: + name: kagent-tool-server + toolNames: ["k8s_get_events"] + + # Sotto-agenti esposti come "tool" — la scelta di chiamarli + # è dell'LLM di incident-commander, non di kagent + - type: Agent + agent: + name: k8s-troubleshooter + namespace: team-alpha + - type: Agent + agent: + name: log-analyzer + namespace: team-alpha \ No newline at end of file diff --git a/add-on/monitoring/blackbox-exporter.md b/add-on/monitoring/blackbox-exporter.md index 42eab03..f271882 100644 --- a/add-on/monitoring/blackbox-exporter.md +++ b/add-on/monitoring/blackbox-exporter.md @@ -619,6 +619,11 @@ spec: EOF ``` + + + + + COMANDO - applica alert ```bash kubectl apply -f blackbox-http-alerts.yaml @@ -631,8 +636,119 @@ kubectl describe prometheusrule blackbox-http-alerts -n monitoring ``` -10. TEST MANUALE BLACKBOX EXPORTER -================================= +10. CONFIGURA ALERTMANAGER - INVIO EMAIL SU FAIL DI UN SERVIZIO +================================================================ + +Obiettivo: +- inviare una email a un indirizzo specifico quando la probe di un + servizio specifico (serviceX) fallisce (alert BlackboxHttpProbeFailed). + +FILE - blackbox-email-alert.yaml + +Descrizione: +- crea un receiver email dedicato al servizio da monitorare; +- instrada verso quel receiver solo gli alert che riguardano il + target specifico, identificato tramite il label instance. + +NOTA - credenziali SMTP +Se il server SMTP richiede autenticazione, crea prima un Secret con +la password: + +COMANDO - crea secret con password SMTP +```bash +kubectl create secret generic alertmanager-smtp \ + -n monitoring --from-literal=password='' +``` + +COMANDO - crea blackbox-email-alert.yaml +```bash +cat > blackbox-email-alert.yaml <<'EOF' +apiVersion: monitoring.coreos.com/v1alpha1 +kind: AlertmanagerConfig +metadata: + name: blackbox-email-routing + namespace: monitoring + labels: + release: kube-prometheus-stack +spec: + route: + groupBy: ["alertname", "instance"] + groupWait: 30s + groupInterval: 5m + repeatInterval: 1h + receiver: "email-default" + routes: + - matchers: + - name: alertname + value: BlackboxHttpProbeFailed + matchType: "=" + - name: instance + value: "" + matchType: "=" + receiver: "email-servizioX" + + receivers: + - name: "email-default" + emailConfigs: [] + + - name: "email-servizioX" + emailConfigs: + - to: "" + from: "" + smarthost: ":" + authUsername: "" + authPassword: + name: alertmanager-smtp + key: password + requireTLS: true + sendResolved: true + headers: + subject: "[ALERT] Servizio X non raggiungibile" + html: | +

Il servizio {{ "{{" }} .CommonLabels.instance {{ "}}" }} non risponde.

+

{{ "{{" }} .CommonAnnotations.description {{ "}}" }}

+EOF +``` + +Da personalizzare: +- : valore del label instance della probe da + monitorare (es. http://my-service.my-namespace.svc.cluster.local:8080/health); +- : indirizzo email destinatario; +- , : server SMTP (es. smtp.gmail.com:587); +- : mittente email; +- : utente SMTP, se richiesta autenticazione. + +COMANDO - applica la configurazione +```bash +kubectl apply -f blackbox-email-alert.yaml +``` + +COMANDO - verifica AlertmanagerConfig +```bash +kubectl get alertmanagerconfig -n monitoring +kubectl describe alertmanagerconfig blackbox-email-routing -n monitoring +``` + +NOTA - matcher su instance vs job +Se vuoi far scattare l'email per TUTTI i target di una Probe (job) +invece che per un singolo servizio, sostituisci il matcher su +`instance` con: +```yaml +- name: job + value: "http-services-probe" + matchType: "=" +``` + +COMANDO - verifica alert in Alertmanager +```bash +kubectl port-forward -n monitoring svc/kube-prometheus-stack-alertmanager 9093 +# -> http://localhost:9093, controlla che l'alert BlackboxHttpProbeFailed +# per il servizio X sia instradato sul receiver email-servizioX +``` + + +11. TEST MANUALE BLACKBOX EXPORTER +================================== COMANDO - port-forward blackbox-exporter ```bash @@ -651,7 +767,7 @@ probe_http_status_code 200 ``` -11. TROUBLESHOOTING +12. TROUBLESHOOTING =================== CASO - Prometheus non vede la Probe @@ -700,7 +816,7 @@ Azioni consigliate: - aggiungere un modulo dedicato in blackbox-values.yaml se serve una configurazione HTTP specifica. -12. ORDINE DI ESECUZIONE CONSIGLIATO +13. ORDINE DI ESECUZIONE CONSIGLIATO ==================================== COMANDO - sequenza completa @@ -727,7 +843,7 @@ blackbox-http-alerts.yaml ``` -13. NOTE PER DEV, QA E PROD +14. NOTE PER DEV, QA E PROD =========================== Per separare gli ambienti e semplificare dashboard e alert, usa Probe distinte: diff --git a/pipeline/add-hostalias.sh b/pipeline/add-hostalias.sh new file mode 100644 index 0000000..c52bcac --- /dev/null +++ b/pipeline/add-hostalias.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Aggiunge un hostname a spec.template.spec.hostAliases del Deployment blackbox. +# +# Uso: +# ./add-hostalias.sh +# +# Esempio: +# ./add-hostalias.sh idcidcp.pigreco66.it cert-manager cert-manager +# + +DEPLOYMENT_NAME="${2:-}" +DEPLOYMENT_NS="${3:-}" +TARGET_IP="10.43.37.118" +HOSTNAME_VAL="${1:-}" + +if [[ -z "$HOSTNAME_VAL" ]]; then + echo "Uso: $0 " >&2 + exit 1 +fi + +if ! command -v kubectl >/dev/null 2>&1; then + echo "Errore: kubectl non trovato nel PATH" >&2 + exit 1 +fi + +if ! command -v jq >/dev/null 2>&1; then + echo "Errore: jq non trovato nel PATH" >&2 + echo "Installa jq e riprova." >&2 + exit 1 +fi + +# Idempotenza: controlla solo il blocco hostAliases associato a TARGET_IP. +EXISTING_HOSTNAMES="$(kubectl get deployment "$DEPLOYMENT_NAME" -n "$DEPLOYMENT_NS" -o jsonpath="{.spec.template.spec.hostAliases[?(@.ip=='${TARGET_IP}')].hostnames[*]}" 2>/dev/null || true)" +if echo " $EXISTING_HOSTNAMES " | grep -Fq " $HOSTNAME_VAL "; then + echo "Hostname '$HOSTNAME_VAL' gia presente per IP ${TARGET_IP} in ${DEPLOYMENT_NS}/${DEPLOYMENT_NAME}. Nessuna modifica." + exit 0 +fi + +DEPLOY_JSON="$(kubectl get deployment "$DEPLOYMENT_NAME" -n "$DEPLOYMENT_NS" -o json)" + +UPDATED_HOST_ALIASES="$({ + echo "$DEPLOY_JSON" | jq -c --arg ip "$TARGET_IP" --arg hostname "$HOSTNAME_VAL" ' + (.spec.template.spec.hostAliases //= []) + | if any(.spec.template.spec.hostAliases[]?; .ip == $ip) then + .spec.template.spec.hostAliases |= map( + if .ip == $ip then + if ((.hostnames // []) | index($hostname)) then + . + else + .hostnames = ((.hostnames // []) + [$hostname]) + end + else + . + end + ) + else + .spec.template.spec.hostAliases += [{"ip": $ip, "hostnames": [$hostname]}] + end + | .spec.template.spec.hostAliases + ' +} )" + +PATCH_PAYLOAD="$(jq -cn --argjson hostAliases "$UPDATED_HOST_ALIASES" '{spec:{template:{spec:{hostAliases:$hostAliases}}}}')" + +kubectl patch deployment "$DEPLOYMENT_NAME" \ + -n "$DEPLOYMENT_NS" \ + --type=merge \ + -p "$PATCH_PAYLOAD" >/dev/null + +echo "Hostname aggiunto con successo." +echo " Deployment: ${DEPLOYMENT_NS}/${DEPLOYMENT_NAME}" +echo " IP : ${TARGET_IP}" +echo " Hostname : ${HOSTNAME_VAL}" diff --git a/pipeline/addlistener.sh b/pipeline/addlistener.sh index 389ca07..69fef11 100644 --- a/pipeline/addlistener.sh +++ b/pipeline/addlistener.sh @@ -45,11 +45,13 @@ fi # Se l'hostname non e nel dominio *.italiadatacenter.com, aggiungilo anche a cert-manager hostAliases. if [[ "$host_no_port" != *.italiadatacenter.com ]]; then - HOSTALIAS_SCRIPT="/root/work/pipeline/add-cert-manager-hostalias.sh" + HOSTALIAS_SCRIPT="/root/work/pipeline/add-hostalias.sh" if [[ -x "$HOSTALIAS_SCRIPT" ]]; then - "$HOSTALIAS_SCRIPT" "$host_no_port" + "$HOSTALIAS_SCRIPT" "$host_no_port" "cert-manager" "cert-manager" + "$HOSTALIAS_SCRIPT" "$host_no_port" "blackbox-exporter" "monitoring" elif [[ -f "$HOSTALIAS_SCRIPT" ]]; then - bash "$HOSTALIAS_SCRIPT" "$host_no_port" + bash "$HOSTALIAS_SCRIPT" "$host_no_port" "cert-manager" "cert-manager" + bash "$HOSTALIAS_SCRIPT" "$host_no_port" "blackbox-exporter" "monitoring" else echo "Errore: script non trovato: $HOSTALIAS_SCRIPT" >&2 exit 1 diff --git a/pipeline/deploy.sh b/pipeline/deploy.sh index 1ea3c62..869d222 100644 --- a/pipeline/deploy.sh +++ b/pipeline/deploy.sh @@ -7,44 +7,7 @@ ENVIRONMENT="${1:-dev}" 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 - <