kubectl apply vs set: Scegliere il Comando Giusto per gli Aggiornamenti delle Risorse
Comprendi quando utilizzare kubectl apply, set e edit senza creare divergenze tra gli oggetti Kubernetes live e Git.
kubectl apply vs set: Scegliere il Comando Giusto per gli Aggiornamenti delle Risorse
La differenza tra kubectl apply e kubectl set non è solo sintattica. È la differenza tra gestire Kubernetes da una fonte di verità dichiarata e modificare direttamente gli oggetti live. Entrambi sono utili. Entrambi possono farti del male se li usi nel posto sbagliato.
Usa kubectl apply quando la modifica dovrebbe diventare lo stato desiderato del sistema. Usa kubectl set quando hai bisogno di una modifica live mirata, solitamente temporanea o urgente. Usa kubectl edit quando devi ispezionare e correggere un oggetto live in modo interattivo, ma comprendi che è il modo più semplice per creare divergenze da Git.
Un oggetto Kubernetes ha uno stato desiderato memorizzato nel server API. Un Deployment dice quante repliche dovrebbero esistere, quale immagine dovrebbe essere eseguita, quali etichette identificano i pod, quali risorse sono richieste e altro ancora. I controller lavorano per far sì che la realtà corrisponda a quello stato desiderato. Il tuo comando di aggiornamento cambia lo stato desiderato; i controller fanno il resto.
Con kubectl apply, mantieni quello stato desiderato in file YAML o JSON. Il file è la cosa che rivedi, committi, promuovi e ripristini. Un comando tipico è semplice:
kubectl apply -f deployment.yaml
Se l'oggetto non esiste, Kubernetes lo crea. Se esiste, Kubernetes lo aggiorna per corrispondere al manifest. Applicare lo stesso file di nuovo non dovrebbe causare un nuovo cambiamento comportamentale. Quella idempotenza è uno dei motivi per cui apply funziona bene nei flussi di lavoro CI/CD e GitOps.
kubectl apply lato client storicamente utilizzava un'annotazione last-applied per calcolare le modifiche. L'apply lato server, abilitato con --server-side, traccia la proprietà dei campi attraverso i campi gestiti nel server API. I dettagli differiscono, ma l'idea operativa è la stessa: una configurazione dichiarata possiede lo stato desiderato.
Ecco un piccolo manifest di Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
Se cambi l'immagine nel file ed esegui kubectl apply -f deployment.yaml, il Deployment si aggiorna. Se il file è in Git, la modifica può essere revisionata. Se il rollout si rompe, puoi annullare il commit o utilizzare la cronologia dei rollout di Kubernetes a seconda di come il tuo processo di deployment registra le revisioni.
kubectl set funziona diversamente. Cambia un campo specifico su un oggetto live. L'esempio comune è cambiare un'immagine del container:
kubectl set image deployment/web nginx=nginx:1.26
Quel comando è veloce e leggibile. Durante un incidente, la velocità conta. Se l'immagine corrente è rotta e devi spostare un Deployment su un'immagine nota come buona, kubectl set image potrebbe essere la via più rapida. Il pericolo è ciò che accade dopo. Se deployment.yaml dice ancora nginx:1.25, il prossimo kubectl apply -f deployment.yaml potrebbe riportare il carico di lavoro a 1.25.
Quella discrepanza è deriva della configurazione. Il cluster live dice una cosa. Il file sorgente dice un'altra. La deriva non è sempre catastrofica, ma rende il debugging più difficile perché le persone smettono di fidarsi del repository. Qualcuno chiede: "Cosa è in esecuzione in produzione?" e la risposta onesta diventa: "Fammi controllare il cluster."
kubectl set ha diversi sottocomandi utili:
kubectl set image deployment/web nginx=nginx:1.26
kubectl set env deployment/web FEATURE_FLAG=true
kubectl set resources deployment/web -c=nginx --requests=cpu=200m,memory=256Mi --limits=cpu=500m,memory=512Mi
Questi sono pratici per cluster di sviluppo, demo, test di breve durata e modifiche di emergenza in produzione con un commit di follow-up. Non sono un sostituto per manifest mantenuti.
kubectl edit recupera l'oggetto live, lo apre nel tuo editor e invia l'oggetto modificato al server API quando salvi:
kubectl edit deployment/web
È comodo perché puoi vedere l'intero YAML live, inclusi i campi aggiunti dai controller. È anche rischioso perché gli oggetti live contengono molti campi che non dovresti gestire manualmente, come status, metadati generati, versioni delle risorse e campi gestiti. Kubernetes ignorerà o rifiuterà alcune modifiche non valide, ma non tutte le modifiche errate sono sintatticamente non valide.
Un uso sicuro comune di kubectl edit è un esperimento rapido non di produzione: aumentare le repliche, cambiare un'annotazione o testare un valore di probe. Un uso non sicuro comune è modificare manualmente i Deployment di produzione ogni settimana e non aggiornare mai i manifest. Questo crea un cluster che nessuno può ricostruire con fiducia.
La regola pratica è questa: se vuoi che la modifica sopravviva al prossimo deployment, mettila nel manifest e usa apply. Se hai solo bisogno di toccare l'oggetto live, usa set o edit, poi annulla la modifica o riportala in Git.
Ci sono alcuni casi in cui i comandi imperativi non solo sono accettabili ma anche utili. Durante il debugging, potresti temporaneamente aggiungere una variabile d'ambiente che aumenta la verbosità del log:
kubectl set env deployment/api LOG_LEVEL=debug
Dopo aver raccolto i log, rimuovila:
kubectl set env deployment/api LOG_LEVEL-
Se l'impostazione di debug dovesse diventare permanente, committala nel manifest invece. Non fare affidamento sulla memoria.
Un altro caso è il rollback di emergenza. Se la tua pipeline di deployment è bloccata e i clienti sono colpiti, impostare l'immagine direttamente può essere ragionevole:
kubectl set image deployment/api api=registry.example.com/api:2026-05-23-good
kubectl rollout status deployment/api
Il follow-up dovrebbe avvenire immediatamente: apri una pull request o un commit che faccia corrispondere il manifest dichiarato allo stato di emergenza, o esegui il normale processo di rollback una volta che la pipeline è sana. La correzione live compra tempo; non dovrebbe diventare il nuovo metodo di deployment non documentato.
kubectl apply ha anche delle insidie. Se mescoli più strumenti che gestiscono gli stessi campi, puoi ottenere conflitti o sovrascritture sorprendenti. Ad esempio, un controller GitOps, Helm e un umano che esegue kubectl apply contro lo stesso Deployment possono tutti credere di possedere parte dell'oggetto. Scegli una proprietà chiara. Se Helm gestisce la risorsa, aggiorna i valori di Helm ed esegui il processo di rilascio di Helm. Se Argo CD o Flux la gestisce, cambia Git e lascia che il controller riconcili.
Per segreti e configurazioni, fai particolare attenzione. kubectl set env può inserire modifiche rapide in un Deployment, ma può esporre valori nella cronologia della shell o nei log di audit. Per valori sensibili, aggiorna il Secret attraverso il tuo normale processo di gestione dei segreti. Non incollare credenziali di produzione in un comando ad hoc a meno che il tuo team non abbia esplicitamente accettato quel flusso di lavoro.
Prima di modificare un oggetto live, ispezionalo:
kubectl get deployment web -o yaml
kubectl diff -f deployment.yaml
kubectl diff è sottoutilizzato. Mostra cosa apply cambierebbe prima di fare la modifica. In produzione, quell'anteprima può cogliere errori come rimuovere accidentalmente un selettore di etichette, eliminare un limite di risorse o applicare il manifest dell'ambiente sbagliato.
Per l'apply lato server, il comando appare così:
kubectl apply --server-side -f deployment.yaml
L'apply lato server può essere utile quando più attori gestiscono campi diversi, ma non rimuove la necessità di disciplina nella proprietà. Se due manager cercano di possedere lo stesso campo, Kubernetes potrebbe segnalare un conflitto. Questa è una caratteristica; ti sta dicendo che il flusso di lavoro è ambiguo.
Ecco una semplice guida decisionale che uso in cluster reali. Nuovo rilascio dell'applicazione? Cambia il manifest e usa apply attraverso la pipeline. Aumentare le repliche per un test di carico in staging? kubectl scale o kubectl set va bene se lo annulli. Hotfix di un'immagine rotta in produzione? kubectl set image può essere accettabile, ma crea subito la modifica della fonte di verità. Ottimizzare le richieste CPU in modo permanente? Aggiorna il manifest. Esplorare quali campi esistono su una risorsa? Usa kubectl get -o yaml prima di ricorrere a edit.
Quando i team fanno questo correttamente, Kubernetes diventa più facile da comprendere. Il repository racconta la storia. Il cluster corrisponde al repository la maggior parte del tempo. Le modifiche live temporanee sono etichettate come temporanee e pulite. Gli incidenti sono ancora stressanti, ma la configurazione non diventa un secondo mistero.
Il comando in sé non è il punto. Il punto è se puoi ricostruire lo stato del cluster domani da file affidabili. kubectl apply supporta quell'abitudine. kubectl set e kubectl edit sono strumenti affilati per momenti in cui l'azione diretta è utile. Mantieni quel confine chiaro ed eviterai molta confusione evitabile su Kubernetes.
C'è un altro comando che le persone mettono nello stesso secchio mentale: kubectl patch. È anche imperativo, ma è migliore per modifiche scriptate precise rispetto a edit. Ad esempio, puoi patchare un'annotazione di Deployment per attivare un riavvio o aggiornare un piccolo campo in automazione. La stessa regola di deriva si applica. Se il campo patchato rappresenta lo stato desiderato a lungo termine, aggiorna anche il manifest sorgente.
kubectl patch deployment web -p '{"spec":{"template":{"metadata":{"annotations":{"restartedAt":"2026-05-24T10:00:00Z"}}}}}'
Per i riavvii, preferisci il comando appositamente costruito:
kubectl rollout restart deployment/web
Quel comando cambia ancora l'oggetto live, ma il suo intento è chiaro: avviare un nuovo rollout dal template pod corrente. Non è un sostituto per cambiare la configurazione in Git.
Negli ambienti GitOps, il confine è ancora più stretto. Se Argo CD o Flux possiede un oggetto, un kubectl set image manuale potrebbe essere annullato automaticamente perché il controller vede la deriva e riconcilia tornando a Git. Questo può essere sorprendente durante un incidente. Prima di fare una modifica manuale in produzione, sappi se un controller GitOps ti combatterà. A volte l'azione di emergenza giusta è mettere in pausa la riconciliazione per quell'applicazione, fare la correzione, poi committare la modifica Git corrispondente e riprendere la riconciliazione.
Dovresti anche sapere come catturare una differenza live senza committare ciecamente campi generati. kubectl get deployment web -o yaml include status, versioni delle risorse, campi gestiti e altri dati che non dovrebbero andare in un manifest pulito. Se devi riportare un hotfix, modifica il manifest sorgente a mano o usa uno strumento come Kustomize o valori Helm, poi esegui kubectl diff per verificare la modifica intenzionale. Non sostituire il tuo file sorgente con YAML live grezzo a meno che non lo pulisca attentamente.
Per i team, la politica più sana è solitamente breve ed esplicita. Le modifiche in produzione passano attraverso Git. Le modifiche live di emergenza sono consentite quando necessario, ma richiedono una modifica sorgente di follow-up o un rollback. I cluster di sviluppo sono più permissivi, ma qualsiasi cosa promossa oltre lo sviluppo deve essere dichiarata. Quella politica è più facile da seguire di una lunga lista di comandi proibiti.
C'è anche un lato umano in questo. Durante un'interruzione, la persona con accesso al cluster potrebbe fare la correzione più veloce possibile. Va bene quando il team lo tratta come un'eccezione di emergenza. Diventa pericoloso quando quelle eccezioni diventano operazioni normali. Se la produzione viene sistemata abitualmente a mano, il processo di deployment è o troppo lento, troppo fragile o non affidabile. Risolvi quel processo piuttosto che insegnare a tutti più trucchi di modifica live.
RBAC può rafforzare il flusso di lavoro. Molti team consentono un ampio accesso kubectl in sviluppo ma limitano le scritture in produzione a sistemi CI/CD, controller GitOps o un piccolo gruppo di turno. Questa non è burocrazia fine a se stessa. Riduce il numero di percorsi che possono cambiare lo stato desiderato. Quando qualcosa cambia, i log di audit e la cronologia Git sono più facili da seguire.
Per l'apprendimento, vale comunque la pena praticare tutti e tre i comandi in un namespace usa e getta. Crea un Deployment con apply, cambia la sua immagine con set, ispeziona la deriva con kubectl diff, poi aggiorna il manifest e applica di nuovo. Vedere la deriva una volta in un ambiente sicuro rende molto più facile ricordare la regola di produzione.