Durante il deployment di Kubernetes in un ambiente aziendale o dietro un firewall, spesso sorge la necessità di configurare un server proxy per accedere a risorse esterne. Questo è fondamentale per il download delle immagini dei container, l'aggiornamento dei pacchetti e l'interazione con API esterne. In questa guida esamineremo tutti i livelli di configurazione del proxy in Kubernetes, dalla configurazione dei nodi ai singoli pod.
Perché è necessario un proxy nei cluster Kubernetes
I cluster Kubernetes in ambienti aziendali spesso operano in reti isolate con accesso limitato a Internet. Un server proxy risolve diverse problematiche critiche:
- Download delle immagini dei container — Docker Hub, Google Container Registry, registri privati richiedono accesso esterno
- Aggiornamento dei pacchetti — installazione delle dipendenze tramite apt, yum, pip all'interno dei container
- Accesso a API esterne — integrazione con servizi cloud, monitoraggio, logging
- Sicurezza — controllo del traffico, filtraggio dei domini, logging delle richieste
- Caching — accelerazione delle richieste ripetute verso le stesse risorse
Senza una corretta configurazione del proxy, si possono verificare errori come "image pull failed", "connection timeout" o "network unreachable" durante il tentativo di deploy delle applicazioni. Questo è particolarmente critico per i pipeline CI/CD automatici, dove ogni secondo di inattività costa denaro.
Importante: Per i cluster aziendali si consiglia di utilizzare proxy di data center con alta capacità e stabilità della connessione, poiché la loro funzionalità dipende dall'intera infrastruttura.
Livelli di configurazione del proxy in Kubernetes
Kubernetes ha un'architettura a più livelli, e il proxy deve essere configurato a ciascun livello a seconda delle necessità:
| Livello | Cosa viene configurato | A cosa serve |
|---|---|---|
| Sistema operativo | Variabili d'ambiente di sistema | Accesso agli strumenti (curl, wget, apt) |
| Container Runtime (Docker/containerd) | Configurazione del demone | Download delle immagini dei container |
| kubelet | Parametri di avvio di kubelet | Interazione con l'API server |
| Pod | Variabili d'ambiente nei manifesti | Accesso delle applicazioni alle API esterne |
| kubectl | Variabili d'ambiente del client | Gestione del cluster tramite proxy |
Ogni livello richiede una configurazione separata e trascurare uno di essi può portare a problemi. Ad esempio, se si configura il proxy solo per Docker, ma non per i pod, le immagini verranno scaricate, ma le applicazioni all'interno dei container non potranno accedere alle API esterne.
Configurazione del proxy per Docker e containerd
Il container runtime è il primo componente da configurare, poiché è responsabile del download delle immagini dei container dai registri esterni. Esaminiamo la configurazione per entrambi i runtime popolari.
Configurazione del proxy per Docker
Per Docker è necessario creare un file drop-in di systemd, che aggiungerà le variabili d'ambiente al servizio Docker:
# Creiamo la directory per la configurazione
sudo mkdir -p /etc/systemd/system/docker.service.d
# Creiamo il file con le impostazioni del proxy
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.cluster.local,.svc"
EOF
# Ricarichiamo la configurazione di systemd
sudo systemctl daemon-reload
# Riavviamo Docker
sudo systemctl restart docker
# Verifichiamo che le impostazioni siano state applicate
sudo systemctl show --property=Environment docker
Dopo questo, Docker sarà in grado di scaricare le immagini tramite il server proxy. È possibile verificare il funzionamento con il comando:
docker pull nginx:latest
Configurazione del proxy per containerd
Containerd è utilizzato nei moderni cluster Kubernetes come principale container runtime. La configurazione del proxy per esso è leggermente diversa:
# Creiamo la directory per la configurazione
sudo mkdir -p /etc/systemd/system/containerd.service.d
# Creiamo il file con le impostazioni del proxy
sudo tee /etc/systemd/system/containerd.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.cluster.local,.svc"
EOF
# Ricarichiamo la configurazione
sudo systemctl daemon-reload
sudo systemctl restart containerd
# Verifichiamo lo stato
sudo systemctl status containerd
Consiglio: Se utilizzi un registro di container privato, aggiungi il suo dominio in NO_PROXY per evitare ritardi e problemi con i certificati SSL.
Configurazione del proxy per kubelet
Kubelet è l'agente di Kubernetes che opera su ogni nodo del cluster. Ha anche bisogno di accesso all'API server e alle risorse esterne. La configurazione dipende dal metodo di installazione di Kubernetes.
Per cluster kubeadm
Se utilizzi kubeadm, configura il proxy tramite systemd:
# Creiamo la directory per la configurazione di kubelet
sudo mkdir -p /etc/systemd/system/kubelet.service.d
# Creiamo il file con le impostazioni del proxy
sudo tee /etc/systemd/system/kubelet.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.96.0.0/12,10.244.0.0/16,.cluster.local,.svc"
EOF
# Ricarichiamo kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
Per Kubernetes gestiti (EKS, GKE, AKS)
Nei servizi Kubernetes gestiti, la configurazione di kubelet viene solitamente eseguita tramite parametri di avvio dei nodi o script di user data. Ad esempio, per AWS EKS:
#!/bin/bash
# Script di user data per i nodi worker EKS
# Configurazione del proxy per il sistema
cat <<EOF >> /etc/environment
HTTP_PROXY=http://proxy.company.com:8080
HTTPS_PROXY=http://proxy.company.com:8080
NO_PROXY=localhost,127.0.0.1,169.254.169.254,.ec2.internal,.cluster.local
EOF
# Configurazione per kubelet
mkdir -p /etc/systemd/system/kubelet.service.d
cat <<EOF > /etc/systemd/system/kubelet.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,169.254.169.254,.ec2.internal,.cluster.local"
EOF
systemctl daemon-reload
systemctl restart kubelet
Nota l'aggiunta di 169.254.169.254 in NO_PROXY — questo è l'indirizzo del servizio di metadata AWS, che deve essere accessibile senza proxy.
Configurazione del proxy a livello di pod
Anche se hai configurato il proxy per Docker e kubelet, le applicazioni all'interno dei pod non utilizzeranno automaticamente il proxy. È necessario specificare esplicitamente le variabili d'ambiente nei manifesti Kubernetes.
Configurazione tramite il manifesto Deployment
Il modo più semplice è aggiungere le variabili d'ambiente nella specifica del container:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-company/my-app:latest
env:
- name: HTTP_PROXY
value: "http://proxy.company.com:8080"
- name: HTTPS_PROXY
value: "http://proxy.company.com:8080"
- name: NO_PROXY
value: "localhost,127.0.0.1,.cluster.local,.svc,10.0.0.0/8"
ports:
- containerPort: 8080
Utilizzo di ConfigMap per una configurazione centralizzata
Per evitare di duplicare le impostazioni del proxy in ogni Deployment, crea una ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: proxy-config
namespace: default
data:
HTTP_PROXY: "http://proxy.company.com:8080"
HTTPS_PROXY: "http://proxy.company.com:8080"
NO_PROXY: "localhost,127.0.0.1,.cluster.local,.svc,10.0.0.0/8"
Poi utilizza questa ConfigMap nel Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: my-company/my-app:latest
envFrom:
- configMapRef:
name: proxy-config
Questo approccio semplifica la gestione: quando si modifica l'indirizzo del proxy, è sufficiente aggiornare la ConfigMap, e dopo il riavvio dei pod, le nuove impostazioni verranno applicate automaticamente.
Iniezione automatica tramite MutatingWebhook
Per aggiungere automaticamente le variabili del proxy a tutti i pod, è possibile utilizzare MutatingAdmissionWebhook. Questo è un approccio avanzato che richiede lo sviluppo di un proprio servizio webhook, ma consente di gestire centralmente le impostazioni senza modificare i manifesti delle applicazioni.
Configurazione corretta di NO_PROXY
La variabile NO_PROXY definisce quali indirizzi e domini devono bypassare il server proxy. Una configurazione errata di NO_PROXY è la causa più comune di problemi nei cluster Kubernetes.
Eccezioni obbligatorie per Kubernetes
I seguenti indirizzi e intervalli DEVONO SEMPRE essere in NO_PROXY:
| Indirizzo/Intervallo | Scopo |
|---|---|
localhost, 127.0.0.1 |
Connessioni locali |
.cluster.local |
DNS interno del cluster |
.svc |
Servizi Kubernetes |
10.0.0.0/8 |
Rete dei pod (dipende da CNI) |
10.96.0.0/12 |
Rete dei servizi (predefinita) |
172.16.0.0/12 |
Reti private Docker |
192.168.0.0/16 |
Reti locali private |
Esempio di configurazione completa di NO_PROXY
NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,10.96.0.0/12,.cluster.local,.svc,.default.svc,.default.svc.cluster.local,kubernetes.default.svc,kubernetes.default.svc.cluster.local
Attenzione: Alcune applicazioni non supportano la notazione CIDR in NO_PROXY. In questi casi, utilizza i caratteri jolly: 10.* invece di 10.0.0.0/8.
Configurazione di kubectl per funzionare tramite proxy
Se gestisci un cluster da una workstation che si trova dietro un proxy, configura le variabili d'ambiente per kubectl:
# Per Linux/macOS - aggiungi a ~/.bashrc o ~/.zshrc
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=http://proxy.company.com:8080
export NO_PROXY=localhost,127.0.0.1,kubernetes.default.svc,.cluster.local
# Per Windows PowerShell
$env:HTTP_PROXY="http://proxy.company.com:8080"
$env:HTTPS_PROXY="http://proxy.company.com:8080"
$env:NO_PROXY="localhost,127.0.0.1,kubernetes.default.svc,.cluster.local"
Dopo questo, kubectl sarà in grado di connettersi all'API server del cluster tramite proxy. Verifica il funzionamento:
kubectl cluster-info
kubectl get nodes
Configurazione del proxy con autenticazione
Se il server proxy richiede autenticazione, aggiungi le credenziali nell'URL:
export HTTP_PROXY=http://username:password@proxy.company.com:8080
export HTTPS_PROXY=http://username:password@proxy.company.com:8080
Sicurezza: Non memorizzare le password in chiaro nei file di configurazione. Utilizza variabili d'ambiente o segreti Kubernetes per memorizzare le credenziali del proxy.
Diagnosi e risoluzione dei problemi comuni
Anche con una configurazione corretta, possono sorgere problemi. Esaminiamo gli errori più comuni e come risolverli.
Errore "ImagePullBackOff" durante il download delle immagini
Sintomi: I pod non si avviano, negli eventi viene mostrato l'errore "Failed to pull image" o "connection timeout".
Diagnosi:
# Controlla gli eventi del pod
kubectl describe pod <pod-name>
# Controlla le impostazioni del proxy in Docker/containerd
sudo systemctl show --property=Environment docker
sudo systemctl show --property=Environment containerd
# Prova a scaricare l'immagine manualmente sul nodo
sudo docker pull nginx:latest
sudo crictl pull nginx:latest
Soluzione: Assicurati che il proxy sia configurato per il container runtime e che il dominio del registro delle immagini non si trovi in NO_PROXY.
Problemi di risoluzione DNS all'interno del cluster
Sintomi: I pod non possono comunicare tra loro tramite nomi DNS (ad esempio, service-name.namespace.svc.cluster.local).
Diagnosi:
# Controlla DNS dal pod
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default
# Controlla le variabili del proxy nel pod
kubectl exec -it <pod-name> -- env | grep PROXY
Soluzione: Aggiungi .cluster.local e .svc in NO_PROXY.
Lentezza o timeout durante l'accesso a API esterne
Sintomi: Le applicazioni funzionano lentamente o ricevono timeout durante le richieste ai servizi esterni.
Diagnosi:
# Controlla la disponibilità del proxy dal pod
kubectl exec -it <pod-name> -- curl -v -x http://proxy.company.com:8080 https://www.google.com
# Misura il tempo di risposta
kubectl exec -it <pod-name> -- time curl -x http://proxy.company.com:8080 https://api.example.com
Soluzione: Il problema potrebbe essere nelle prestazioni del server proxy. Considera di utilizzare proxy residenziali con una posizione geograficamente vicina per ridurre i ritardi.
Errori SSL/TLS durante l'uso tramite proxy
Sintomi: Errori come "certificate verify failed" o "SSL handshake failed".
Motivo: Alcuni server proxy eseguono l'ispezione SSL (decrittazione del traffico HTTPS), il che richiede l'installazione del certificato radice del proxy.
Soluzione:
# Crea una ConfigMap con il certificato del proxy
kubectl create configmap proxy-ca-cert --from-file=ca.crt=/path/to/proxy-ca.crt
# Monta il certificato nel pod e aggiungilo allo store di sistema
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
volumeMounts:
- name: proxy-ca
mountPath: /usr/local/share/ca-certificates/proxy-ca.crt
subPath: ca.crt
volumes:
- name: proxy-ca
configMap:
name: proxy-ca-cert
Best practices per il proxy in produzione
Basandosi sull'esperienza di gestione dei cluster Kubernetes in ambienti aziendali, ecco alcune raccomandazioni per un funzionamento affidabile con il proxy:
1. Utilizza server proxy ad alta disponibilità
Il proxy diventa un singolo punto di guasto per l'intero cluster. Configura più server proxy dietro un load balancer:
HTTP_PROXY=http://proxy-lb.company.com:8080
Dove proxy-lb.company.com è il load balancer davanti a più server proxy.
2. Gestione centralizzata della configurazione
Utilizza ConfigMap o Secret per memorizzare le impostazioni del proxy invece di hardcodificarle in ogni manifesto:
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-proxy-config
namespace: kube-system
data:
HTTP_PROXY: "http://proxy-lb.company.com:8080"
HTTPS_PROXY: "http://proxy-lb.company.com:8080"
NO_PROXY: "localhost,127.0.0.1,.cluster.local,.svc,10.0.0.0/8"
3. Monitoraggio e alerting
Configura il monitoraggio della disponibilità dei server proxy e alert quando ci sono problemi:
- Tempo di risposta del proxy (dovrebbe essere < 100ms per i proxy locali)
- Numero di errori di connessione al proxy
- Numero di eventi ImagePullBackOff nel cluster
- Carico CPU e rete sui server proxy
4. Documenta le eccezioni NO_PROXY
Tieni traccia di quali domini e indirizzi IP sono stati aggiunti a NO_PROXY e perché. Questo aiuterà nella risoluzione dei problemi e nell'audit della sicurezza.
5. Testa le modifiche in un ambiente dev
Prima di modificare le impostazioni del proxy in produzione, testa sempre in un cluster dev/staging:
# Pod di test per verificare il proxy
apiVersion: v1
kind: Pod
metadata:
name: proxy-test
spec:
containers:
- name: test
image: curlimages/curl:latest
command: ["sleep", "3600"]
env:
- name: HTTP_PROXY
value: "http://new-proxy.company.com:8080"
- name: HTTPS_PROXY
value: "http://new-proxy.company.com:8080"
# Controlla la disponibilità delle risorse esterne
kubectl exec -it proxy-test -- curl -v https://registry.k8s.io
kubectl exec -it proxy-test -- curl -v https://docker.io
6. Utilizza diversi tipi di proxy per compiti diversi
Per componenti critici (download delle immagini, API del cluster) utilizza proxy veloci di data center, mentre per applicazioni che richiedono una diversità geografica degli IP — proxy residenziali o mobili.
7. Aggiorna regolarmente l'elenco NO_PROXY
Quando aggiungi nuovi servizi o modifichi la topologia di rete, aggiorna NO_PROXY. Automatizza questo tramite Helm charts o Kustomize:
# values.yaml per Helm chart
proxy:
enabled: true
http: "http://proxy.company.com:8080"
https: "http://proxy.company.com:8080"
noProxy:
- localhost
- 127.0.0.1
- .cluster.local
- .svc
- 10.0.0.0/8
- internal-service.company.com
Conclusione
La configurazione del proxy nei cluster Kubernetes è un compito multilivello che richiede attenzione ai dettagli a ogni livello: dal sistema operativo e dal container runtime ai singoli pod. Una configurazione corretta garantisce un funzionamento senza interruzioni del cluster, accesso sicuro alle risorse esterne e conformità alle politiche di sicurezza aziendali.
Punti chiave da ricordare:
- Configura il proxy a tutti i livelli: OS, container runtime, kubelet, pod
- Configura correttamente NO_PROXY, includendo tutte le reti interne del cluster
- Utilizza la gestione centralizzata tramite ConfigMap
- Monitora la disponibilità e le prestazioni dei server proxy
- Testa le modifiche prima di applicarle in produzione
Per cluster Kubernetes critici, si consiglia di utilizzare affidabili proxy di data center con alta disponibilità e bassa latenza. Questo garantirà un funzionamento stabile dell'infrastruttura e minimizzerà i rischi di inattività a causa di problemi di accesso alla rete.
In caso di problemi, utilizza un approccio sistematico alla diagnosi: controlla le impostazioni a ogni livello, analizza i log e gli eventi, testa manualmente la connessione. La maggior parte dei problemi con il proxy in Kubernetes può essere risolta con una corretta configurazione delle variabili d'ambiente e di NO_PROXY.