I container sono strumenti ottimi per l'incapsulamento di applicazioni, incluse le loro funzionalità, risorse nonché le dipendenze di cui hanno bisogno. Il vantaggio di costruire immagini container appropriate è che possiamo avviare tante istanze tutte totalmente identiche tra loro rendendo omogenei in ogni aspetto i carichi di lavoro. D'altro canto però ciò potrebbe limitare la nostra capacità di configurazione, molto spesso necessaria alla personalizzazione delle applicazioni che lanciamo. Ciò può essere gestito in Kubernetes con due caratteristiche molto importanti che mettono anche in condizione di trattare correttamente i dati riservati. Parliamo di:
- ConfigMap per la specifica di configurazioni personali al lancio del container;
- Secret per la condivisione di dati riservati come password.
Nel corso di questa lezione le sperimenteremo entrambe. Come di consueto in Kubernetes, potremmo passare per la via imperativa o quella dichiarativa: adotteremo a seconda delle situazioni ciò che sarà più congeniale all'illustrazione dei nostri casi d'uso rimandando il lettore ad un ulteriore approfondimento nella documentazione ufficiale.
ConfigMap
Le ConfigMap sono oggetti che inglobano proprietà nel formato chiave/valore che possiamo usare all'interno dei container tramite file system o variabili d'ambiente. Vediamole subito al lavoro con una sperimentazione che potrà essere attuata anche in minikube.
Predisporre una ConfigMap significa creare un elenco di proprietà che vogliamo vengano passate all'interno di un Pod. Gli scopi di ciò possono essere dei più disparati per regolare comportamento, impostazioni e performance degli applicativi containerizzati. La nostra ConfigMap conterrà un solo parametro chiamato PARAMETRO_PROVA
di valore uguale a valore_a_mia_scelta
:
kubectl create configmap example-config \
--from-literal=PARAMETRO_PROVA=valore_a_mia_scelta
Possiamo verificare di averla davvero a disposizione con un comando get
:
$ kubectl get configmaps
NAME DATA AGE
example-config 1 11s
kube-root-ca.crt 1 5m46s
e con un describe:
$ kubectl describe configmaps/example-config
Name: example-config
Namespace: default
Labels:
Annotations:
Data
====
PARAMETRO_PROVA:
----
valore_a_mia_scelta
Per utilizzarla creiamo un Pod – un server Web in modo che resti on line e ci dia tempo di effettuare la nostra prova – in cui la ConfigMap sia collegata ed utilizzabile come variabile d'ambiente:
apiVersion: v1
kind: Pod
metadata:
name: pod-per-config
spec:
containers:
- name: mioserver
image: httpd
env:
- name: PARAMETRO_PROVA_ENV
valueFrom:
configMapKeyRef:
name: example-config
key: PARAMETRO_PROVA
Si tratta di un Pod molto semplice basato su immagine httpd ma che dispone di una sezione env
in cui dichiareremo una variabile d'ambiente di nome PARAMETRO_PROVA_ENV
. Il valore di quest'ultima non sarà però statico ma estratto da PARAMETRO_PROVA
della ConfigMap. Una volta avviato il Pod si potrà verificare la disponibilità della nuova variabile d'ambiente con:
kubectl exec pod-per-config -- env
che produrrà in output tutte quelle disponibili nel sistema.
Secret
I Secret perseguono uno scopo simile alle ConfigMap con la differenza che sono specializzati nella gestione di dati sensibili, prime tra tutte le password. Possiamo crearli imperativamente con un comando del genere:
$ kubectl create secret generic \
passwd-secret --from-literal=password=topolino
A questo punto esisterà un secret di nome passwd-secret
contenente l'accoppiata chiave/valore password=topolino
. Verifichiamone l'esistenza con i comandi get secrets
e describe
:
$ kubectl get secrets
NAME TYPE DATA AGE
passwd-secret Opaque 1 11s
$ kubectl describe secrets passwd-secret
Name: passwd-secret
Namespace: default
Labels:
Annotations:
Type: Opaque
Data
====
password: 8 bytes
Una password sicurizzata in questo modo può, a questo punto, essere impiegata per lanciare un Pod con un database MySQL in esecuzione:
apiVersion: v1
kind: Pod
metadata:
name: database-server
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: passwd-secret
key: password
Come vediamo la password di root viene passata come variabile d'ambiente, senza scriverne il valore esplicitamente, ma solo fissando il riferimento al Secret: proprio da questo verrà prelevata.
Possiamo verificare il funzionamento avviando il Pod con kubectl apply
e loggandoci presso il server di database usando il client che esso stesso offre:
$ kubectl exec -it database-server -- mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.51 MySQL Community Server (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
Alla richiesta di password avremo passato "topolino" come da nostre impostazioni ed avremo ottenuto un corretto accesso al sistema con il prompt di MySQL che attende comandi.