Project

General

Profile

Actions

Milestone #61

open

kubernetes projects

Milestone #61: kubernetes projects

Added by Daniele Cruciani 3 months ago. Updated 3 months ago.

Status:
new
Priority:
wishlist
Assignee:
-
Start date:
Due date:
% Done:

0%

Estimated time:
Sprint:

Description

Service Topology

  • Gitlab deploy on kubernetes
  • ArgoCD
  • Jenkins
  • Private Image Repository
  • Deploy Redmine

Namespaces

  • devops:
    • Gitlab
    • jenkins
    • argoCD
  • production:
    • redmine
  • development:
  • stage:

Updated by Daniele Cruciani 3 months ago Actions #1

[2025-12-18 13:34 CET]

Risposta secca: si puo usare ArgoCD senza GUI e non sei obbligato a usare Helm.
ArgoCD lavora nativamente con YAML Kubernetes.

Ora i dettagli, senza fuffa.


1) ArgoCD senza GUI: solo file di configurazione

ArgoCD non richiede la GUI.
La GUI e solo un frontend sopra CRD Kubernetes.

Tutto cio che ArgoCD fa e pilotabile con:

  • manifest YAML
  • kubectl apply
  • Git (GitOps vero)

Oggetto chiave: Application

Tu definisci Application come risorsa Kubernetes.

Esempio minimale:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://gitea.example.com/org/repo.git
    targetRevision: main
    path: k8s
  destination:
    server: https://kubernetes.default.svc
    namespace: my-namespace
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Questo sostituisce completamente la GUI.

  • Repo definiti in YAML
  • Branch definiti in YAML
  • Namespace target in YAML
  • Policy in YAML

La GUI diventa irrilevante.


2) Gestire molte Application: ApplicationSet

Se vuoi evitare N file Application quasi uguali, usi ApplicationSet.

Esempio (repo-based):

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: apps
  namespace: argocd
spec:
  generators:
  - git:
      repoURL: https://gitea.example.com/org/gitops.git
      revision: main
      directories:
      - path: apps/*
  template:
    metadata:
      name: '{{path.basename}}'
    spec:
      project: default
      source:
        repoURL: https://gitea.example.com/org/gitops.git
        targetRevision: main
        path: '{{path.path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{path.basename}}'

Risultato:

  • aggiungi una directory
  • ArgoCD crea automaticamente una Application
  • zero click
  • zero GUI

3) ArgoCD supporta solo Helm? No.

ArgoCD supporta quattro modalita principali:

1. Plain Kubernetes YAML (la piu semplice)

Repo tipo:

k8s/
  deployment.yaml
  service.yaml
  secret.yaml

ArgoCD:

  • fa kubectl apply
  • gestisce drift
  • fa prune
  • fa rollback via Git

Questa e la base di tutto.


2. Kustomize (consigliato se non vuoi Helm)

Supporto nativo, zero plugin.

k8s/
  base/
  overlays/
  • Patch
  • Env diversi
  • Niente templating logico
  • Dichiarativo

Per molti team e meglio di Helm.


3. Helm chart

Supportato nativamente.

source:
  chart: mychart
  repoURL: https://charts.example.com
  targetRevision: 1.2.3
  helm:
    valuesFiles:
    - values-prod.yaml

Oppure Helm chart nel tuo repo Git.


4. Plugin (sconsigliato salvo casi estremi)

  • Helmfile
  • Jsonnet
  • Script custom

Potente ma:

  • rompe il modello GitOps
  • aumenta superficie di attacco

4) Gestione dei Secret: chiarimento importante

ArgoCD NON e un secret manager.

Puoi:

  • applicare Secret YAML (base64)
  • usare SealedSecrets
  • usare ExternalSecrets
  • usare SOPS (molto usato)

Non mettere segreti in chiaro nel repo GitOps.


5) ArgoCD come “controller”, non come pipeline

Concetto fondamentale:

  • ArgoCD non esegue
  • ArgoCD confronta stato desiderato vs reale
  • Se differiscono, riallinea

Non fa:

  • build
  • test
  • push image

Questo resta CI (Jenkins, ecc.).


6) Installazione via Helm: ok, ma fai attenzione a questo

Quando installi ArgoCD via Helm:

  • abilita --set configs.cm.application.instanceLabelKey
  • configura RBAC via argocd-rbac-cm
  • disabilita ingress GUI se non la usi
  • usa argocd-repo-server con access token readonly

La GUI puoi:

  • ignorarla
  • non esporla
  • lasciarla solo interna

Conclusione netta

  • Si, puoi usare ArgoCD solo via YAML
  • La GUI e opzionale
  • Supporta YAML puri, Kustomize, Helm
  • Non sei vincolato a Helm
  • Git e l’unica fonte di verita

Se vuoi, nel prossimo passo posso:

  • proporti una struttura repo GitOps concreta
  • mostrarti come gestire env (dev/stage/prod) senza Helm
  • spiegarti come versionare le Application stesse in Git (bootstrap GitOps)

Updated by Daniele Cruciani 3 months ago Actions #2

[2025-12-18 13:47 CET]

Si.
E una architettura valida, comune, e funziona in produzione.
Ma va fatta bene, altrimenti diventa instabile o insicura.

Risposta strutturata.


1) Image registry dentro il cluster: e possibile?

Si.
Kubernetes non ha alcun problema a pullare image da un registry che gira nello stesso cluster.

Soluzioni tipiche:

  • Docker Registry v2 (container registry:2)
  • Harbor (molto piu completo)
  • GitLab Container Registry
  • Nexus Repository
  • Quay (piu raro on-prem)

Minimo sindacale:

  • registry:2 + PVC + Service

Produzione vera:

  • Harbor

2) Flusso completo corretto (senza scorciatoie pericolose)

Jenkins (CI)
  -> build image
  -> tag image (commit SHA, version)
  -> push to registry.internal.svc.cluster.local
      -> Kubernetes nodes pull image
          -> ArgoCD deploya manifest che puntano a quella image

ArgoCD NON tocca le image.
Legge solo YAML.


3) Jenkins: push verso registry interno

Jenkins deve:

  • risolvere DNS del Service
  • autenticarsi al registry
  • usare TLS (o accettare insecure)

Esempio registry interno:

registry.registry.svc.cluster.local:5000

Pipeline Jenkins (concettuale):

docker build -t registry.registry.svc.cluster.local:5000/myapp:${GIT_SHA} .
docker push registry.registry.svc.cluster.local:5000/myapp:${GIT_SHA}

Jenkins non deve avere accesso al cluster API.
Solo al registry.


4) Kubernetes: pull image dal registry interno

Caso A: registry senza auth (sconsigliato)

Funziona subito, ma:

  • chiunque nel cluster puo pullare
  • nessun audit

Solo per test.


Caso B: registry con auth (corretto)

  1. Crei secret docker-registry:
kubectl create secret docker-registry registry-cred \
  --docker-server=registry.registry.svc.cluster.local:5000 \
  --docker-username=jenkins \
  --docker-password=******** \
  --namespace=my-namespace
  1. Lo referenzi nel Deployment:
spec:
  template:
    spec:
      imagePullSecrets:
      - name: registry-cred

5) ArgoCD: nessun problema

ArgoCD:

  • non pulla image
  • non valida image
  • non parla col registry

ArgoCD:

  • applica Deployment YAML
  • Kubernetes fa il pull

Quindi:

  • registry interno = trasparente per ArgoCD
  • zero configurazione extra in ArgoCD

6) Come aggiornare il tag image (punto critico)

Hai due approcci.


Approccio 1 (consigliato): Jenkins aggiorna il manifest GitOps

Flow:

  1. Jenkins builda image
  2. Jenkins pusha image
  3. Jenkins aggiorna deployment.yaml
  4. Jenkins fa commit su repo GitOps
  5. ArgoCD sincronizza

Esempio:

image: registry.registry.svc.cluster.local:5000/myapp:abc1234

Pro:

  • Git e fonte di verita
  • Rollback semplice
  • Audit completo

Contro:

  • Jenkins fa commit (va bene)

Approccio 2: ArgoCD Image Updater

Tool separato:

  • legge registry
  • aggiorna Application
  • scrive commit su Git

Utile se:

  • vuoi separare CI e GitOps
  • accetti un componente in piu

Ma:

  • piu moving parts
  • meno controllo esplicito

7) Tagging: NON usare latest

Mai.

Usa:

  • commit SHA
  • semver immutabile

Esempio:

myapp:1.4.3
myapp:git-7c91f2a

Altrimenti:

  • ArgoCD non vede cambi
  • cache image impazziscono
  • rollback impossibili

8) Networking: attenzione pratica

Registry interno deve essere:

  • raggiungibile dai node
  • non solo dai pod

Se usi:

  • containerd
  • cri-o

I node devono risolvere DNS del Service.

Se hai problemi:

  • usa NodePort
  • o LoadBalancer interno
  • o hostname risolto via CoreDNS

Questo e il punto dove molti sbagliano.


9) Storage: non improvvisare

Registry:

  • non e stateless
  • serve PVC serio

Produzione:

  • RWX se HA
  • snapshot
  • backup

Harbor risolve tutto questo.


10) Quando NON farlo

Evita registry interno se:

  • cluster effimero
  • ambienti molto piccoli
  • vuoi disaster recovery semplice

In quei casi:

  • registry esterno (Harbor esterno, ECR, GCR)

Conclusione netta

  • Si, registry dentro il cluster e fattibile
  • Jenkins puo pushare li
  • Kubernetes puo pullare da li
  • ArgoCD e completamente agnostico
  • Git resta la fonte di verita
  • Tag immutabili o stai sprecando tempo

Se vuoi, nel prossimo passo posso:

  • disegnarti una struttura repo GitOps completa
  • mostrarti una pipeline Jenkins reale (build + commit GitOps)
  • confrontare Harbor vs registry:2 senza marketing

Updated by Daniele Cruciani 3 months ago Actions #3

[2025-12-18 14:01 CET]

Smettiamo subito le ambiguita: NodePort da solo NON e una protezione.
Se e routabile, e accessibile. Punto.

Ora ti spiego come farlo correttamente, senza illusioni.


Scenario riassunto

  • Jenkins gira fuori dal cluster (Docker Swarm)
  • Vuoi un registry esposto dal cluster
  • Accessibile solo dalla rete interna
  • Non esposto pubblicamente
  • Niente GUI, niente ingress pubblico

Questo e un caso classico.


1) NodePort: cosa fa e cosa NON fa

NodePort:

  • apre una porta su tutti i nodi
  • ascolta su 0.0.0.0:<nodePort>
  • non filtra per IP

Se il nodo:

  • ha IP pubblico
  • o e dietro NAT con forwarding

👉 il servizio e esposto.

NodePort NON e una policy di sicurezza.


2) Soluzione corretta: firewall / network filter (si, ntfilter)

La sicurezza non si fa in Kubernetes, si fa a livello rete.

Opzione A (consigliata): firewall sui nodi

Sul nodo Kubernetes:

iptables -A INPUT -p tcp --dport 32000 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 32000 -j DROP

Risultato:

  • Jenkins (rete interna) accede
  • resto del mondo no

Pulito. Efficace. Prevedibile.


Opzione B: proxy / load balancer che ascolta solo IP interni

Se hai un proxy (nginx, haproxy, traefik):

Esempio nginx:

server {
    listen 5000;
    allow 10.0.0.0/8;
    deny all;

    location / {
        proxy_pass http://node1:32000;
    }
}

Il proxy:

  • ascolta solo IP interni
  • il NodePort resta tecnico

Questo e meglio se hai gia un proxy perimetrale.


Opzione C: LoadBalancer interno (se cloud / metallb)

Se usi MetalLB:

spec:
  type: LoadBalancer
  loadBalancerSourceRanges:
  - 10.0.0.0/8

Questo e superiore a NodePort, ma richiede infrastruttura.


3) NetworkPolicy NON basta

NetworkPolicy:

  • filtra traffico pod-to-pod
  • NON filtra traffico NodePort

Quindi:

  • inutile per questo caso
  • chi dice il contrario mente o non ha capito

4) Jenkins fuori cluster: attenzione TLS

Se il registry:

  • espone HTTP -> sconsigliato
  • espone HTTPS -> meglio

Se TLS:

  • Jenkins deve fidarsi della CA
  • oppure usare --insecure-registry (male, ma possibile)

Produzione seria:

  • CA interna
  • certificato valido

5) DNS: non usare .svc da fuori

Da Jenkins:

  • NON risolvi *.svc.cluster.local

Devi usare:

  • IP nodo
  • hostname proxy
  • VIP MetalLB

6) Riassunto delle scelte sane

Soluzione Sicurezza Semplicita
NodePort + iptables Alta Media
NodePort + proxy IP-filter Alta Alta
LoadBalancer interno Molto alta Alta
NodePort puro Bassa Facile ma sbagliata

Conclusione netta

  • NodePort non protegge niente
  • Il filtro va fatto fuori da k8s
  • Firewall o proxy IP-based
  • NetworkPolicy non serve
  • Usa TLS o stai accettando rischio

Se vuoi, nel prossimo passo posso:

  • darti una config completa nginx o haproxy
  • mostrarti iptables persistenti
  • valutare MetalLB vs NodePort per il tuo scenario

Updated by Daniele Cruciani 3 months ago Actions #4

  • Description updated (diff)

Updated by Daniele Cruciani 3 months ago Actions #5

  • Description updated (diff)
Actions

Also available in: PDF Atom