Differenze tra Deployment e DeploymentConfig
Gli oggetti Deployment e DeploymentConfig in OpenShift forniscono due metodi simili ma diversi per gestire in maniera precisa il comportamento delle applicazioni. I due oggetti, spesso confusi, hanno grandi differenze nella loro esecuzione e gestione: quali?
Andiamo ad analizzare nel dettaglio questi due controller!
DeploymentConfig
Gli oggetti di tipo DeploymentConfig coinvolgono uno o più Replication Controllers, ossia delle risorse che contengono un point-in-time dello stato di uno o più pod, di cui ne gestiscono peraltro la numerosità.
Sarà proprio il Replication controllers ad assicurarsi che il numero specificato di pod siano in esecuzione; qualora un pod venisse eliminato o andasse in errore, sarà sua cura istanziarne uno in sostituzione.
La cosa interessante è la possibilità di gestire le versioni dell’applicazione per supportare i rollback manualmente o automaticamente in caso di un deploy che fallisce, oltre alla possibilità di catturare ogni cambiamento alla configurazione dell’oggetto attraverso un trigger: questo fa sì che una modifica all’environment del DeploymentConfig o delle sue risorse, produca una nuova versione.
Non a caso, i DeploymentConfig creano dei Replication Controller i cui nomi riportano la versione di riferimento: se, ad esempio, il DeploymentConfig si chiama mongodb, il suo Replication Controller si chiamerà mongodb-1, perché fa riferimento al rollout (o versione) numero 1.
Quando crei un oggetto DeploymentConfig, viene creato un Replication Controller che rappresenta il modello pod dell’oggetto DeploymentConfig.
Se il DeploymentConfig cambia, viene creato un nuovo Replication Controller con il template aggiornato e viene eseguito un processo di deploy che porti a termine la precedente versione del Replication Controller, per avviare quello nuovo.
Esempio di DeploymentConfig
apiVersion: v1
kind: DeploymentConfig
metadata:
name: frontend
spec:
replicas: 5
selector:
name: frontend
template: { ... }
triggers:
- type: ConfigChange
- imageChangeParams:
automatic: true
containerNames:
- helloworld
from:
kind: ImageStreamTag
name: hello-openshift:latest
type: ImageChange
strategy:
type: Rolling
Esempio di Replication Controller
apiVersion: v1
kind: ReplicationController
metadata:
name: frontend-1
spec:
replicas: 1
selector:
name: frontend
template:
metadata:
labels:
name: frontend
spec:
containers:
- image: openshift/hello-openshift
name: helloworld
ports:
- containerPort: 8080
protocol: TCP
restartPolicy: Always
Deployment
Allo stesso modo, gli oggetti di tipo Deployment lavorano grazie a degli oggetti chiamati Replica Set, i quali rappresentano un successore dei ReplicationController.
Simile a un Replication controller, un ReplicaSet è un oggetto API nativo di Kubernetes che garantisce che un numero specificato di pod sia in esecuzione in un dato momento.
I ReplicaSet possono essere usati in modo indipendente, ma vengono usati dai Deployment per gestire la creazione, l’eliminazione e gli aggiornamenti dei pod. I Deployment gestiscono automaticamente i ReplicaSet, motivo per cui non andrebbero utilizzati come oggetti a sé stanti.
Il vantaggio dell’utilizzo dei Deployment è che supportano il rollback automatico all’ultimo ReplicaSet che ha avuto esito positivo nel deploy in caso di errore; questo vuol dire che se viene avviata una nuova versione del ReplicaSet, in caso quest’ultima vada in errore, sarà possibile sfruttare la versione precedente che verrà riavviata in maniera automatica.
Esempio di Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-openshift
spec:
replicas: 1
selector:
matchLabels:
app: hello-openshift
template:
metadata:
labels:
app: hello-openshift
spec:
containers:
- name: hello-openshift
image: openshift/hello-openshift:latest
ports:
- containerPort: 80
Esempio di ReplicaSet
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend-1
labels:
tier: frontend
spec:
replicas: 3
selector:
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels:
tier: frontend
spec:
containers:
- image: openshift/hello-openshift
name: helloworld
ports:
- containerPort: 8080
protocol: TCP
restartPolicy: Always
ReplicaSet vs ReplicationController
La differenza tra un ReplicaSet e un Replication Controller sta nel fatto che il primo supporta la possibilità di gestire i selettori sulla base di alcune espressioni che ne controllino il match, mentre nel caso del Replication controller viene utilizzato un selettore che si basi sull’uguaglianza.
In altre parole, nel ReplicaSet ci possiamo aspettare una label come matchExpressions che riporta i criteri per individuare i pod sulla base di una chiave, un operatore e dei valori.
Nel primo caso di esempio, la chiave è tier, l’operatore è In (verifica l’esistenza in un insieme definito) e i valori sono espressi tramite un array pari a frontend.
Nel secondo caso, si esprime una label la cui chiave tier deve matchare il valore frontend.
Esempio di ReplicaSet con matchExpressions
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend-1
labels:
tier: frontend
spec:
replicas: 3
selector:
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
...
Esempio di ReplicaSet con matchLabels
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend-1
labels:
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
...
Il campo .spec.selector rappresenta un selettore di etichette. Un ReplicationController gestisce tutti i pod con label che corrispondono al selettore. Non fa distinzione tra pod creati o eliminati e pod creati o eliminati da un’altra persona o processo. Ciò consente di sostituire ReplicationController senza influire sui pod in esecuzione.
Esempio di ReplicationController
apiVersion: v1
kind: ReplicationController
metadata:
name: frontend-1
spec:
replicas: 1
selector:
name: frontend
template:
metadata:
labels:
name: frontend
...
Risorse utili
- Docker - per cominciare bene con Docker e Kubernetes
- Kubernetes - Guida per gestire e orchestrare i container
- Canale di Emmecilab