Cos'è un template in OpenShift
Docker Compose usa il file docker-compose.yml, mentre Kubernetes usa i chart. E OpenShift?
OpenShift definisce i template, ossia dei modelli che possono essere utilizzati per descrivere lo stack di un’applicazione.
Come funziona e come scriverne uno?
Definizione
Un template descrive un insieme di oggetti che possono essere parametrizzati ed elaborati per produrre un elenco di risorse che possono essere create all’interno di un cluster OpenShift.
Un template può essere definito per creare qualsiasi oggetto tu abbia l’autorizzazione di creare all’interno di un progetto, ad esempio Service, Build e DeploymentConfigs. Un template può anche definire una serie di etichette -o label- da applicare a ogni oggetto definito nel template.
Come crearne uno vuoto
Per creare un template bootstrap, puoi usare il seguente comando:
oc adm create-bootstrap-project-template -o yaml > template.yaml
Questo andrà a produrre, sfruttando l’istruzione create-bootstrap-project-template, un template di base che potrai andare a completare secondo le tue necessità.
L’output prodotto sarà simile al seguente:
apiVersion: template.openshift.io/v1
kind: Template
metadata:
creationTimestamp: null
name: project-request
objects:
- apiVersion: project.openshift.io/v1
kind: Project
metadata:
annotations:
openshift.io/description: ${PROJECT_DESCRIPTION}
openshift.io/display-name: ${PROJECT_DISPLAYNAME}
openshift.io/requester: ${PROJECT_REQUESTING_USER}
creationTimestamp: null
name: ${PROJECT_NAME}
spec: {}
status: {}
- apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: admin
namespace: ${PROJECT_NAME}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: ${PROJECT_ADMIN_USER}
parameters:
- name: PROJECT_NAME
- name: PROJECT_DISPLAYNAME
- name: PROJECT_DESCRIPTION
- name: PROJECT_ADMIN_USER
- name: PROJECT_REQUESTING_USER
Come funziona
La chiave apiVersion rappresenta la versione di riferimento dell’oggetto di tipo Template a cui farà riferimento il nostro oggetto, così come la proprietà kind.
I metadata sono le informazioni che riguardano il template stesso, come il suo nome -che possiamo modificare liberamente- e la data di creazione.
Tieni presente che il nome del template dev’essere univoco per singolo namespace!
All’interno della chiave objects andremo invece a definire tutte le risorse che il template andrà a creare o istanziare: DeploymentConfig, Service, ConfigMaps, Secret e tutte quelle che OpenShift e Kubernetes ci mette a disposizione.
Queste andranno definite come oggetti singoli che fanno parte della lista di objects, quindi ognuno di essi avrà un trattino che separa la definizione di una risorsa dall’altra.
In questo caso, il template va a definire un oggetto di tipo Project, quindi un vero e proprio namespace, con le relative informazioni: il nome univoco da associare (ossia name), il nome mostrato sulla console (ovvero metadata>annotations>openshift.io/display-name) e anche una descrizione (sempre all’interno di metadata>annotations).
Il nome è l’unico parametro obbligatorio.
Oltre al progetto, viene definito il RoleBinding che permette di associare l’utente al progetto; qui notiamo che, così come nella sezione precedente, ci sono alcune espressioni tra parentesi graffe.
${PLACEHOLDER} rappresenta il modo in cui possiamo parametrizzare dei campi nel template e valorizzarli solo in fase di creazione dell’istanza del template.
Se osserviamo bene, come proprietà sibling di objects abbiamo parameters: questo oggetto permette la definizione dei parametri che possono essere valorizzati quando il template viene processato.
Mentre le proprietà che abbiamo elencato finora, come apiVersion e objects sono obbligatorie, i parametri non lo sono: è possibile scrivere un template con all’interno tutti i campi già valorizzati. Questo è solitamente sconsigliato perché il template dovrebbe rappresentare un modello astratto e configurabile a seconda delle necessità, piuttosto che un oggetto.
Creare le risorse
Per poter creare le risorse contenute in un template, sarà sufficiente eseguire un comando come il seguente:
$ oc process -f my-template.yml -p PROJECT_NAME=my-namespace -p PROJECT_DISPLAYNAME="My Project" ...
Ogni parametro presente nel template potrà essere valorizzato usando l’opzione -p. Tuttavia, il comando oc process ci andrà a restituire il template con i parametri aggiornati grazie ai valori passati in input, ma non andrà a creare le risorse al suo interno.
Questo perché oc process prende il template e i parametri come input e lo processa, ma non lo esegue.
Per farlo, useremo oc apply:
$ oc process -f my-template.yml -p PROJECT_NAME=my-namespace -p PROJECT_DISPLAYNAME="My Project" ... oc apply -f -
oc apply andrà a sovrascrivere le risorse da creare a quelle esistenti, eventualmente apportando modifiche o aggiornamenti esistenti in questa versione. Per creare da zero, usare oc create.
Tip
Includere un’etichetta chiamata label in tutti gli oggetti che vengono creati a partire da quel template è una delle best practice.
L’aggiunta di un’etichetta comune a tutti gli oggetti creati da un template consente agli utenti e agli amministratori di tenere traccia degli oggetti creati da un determinato template come un gruppo di risorse dipendenti.
Ad esempio, è sufficiente aggiungere una label come template=my-app-template.
Inoltre, includere un’etichetta app in tutti gli oggetti fornisce un’etichetta dinamica che può essere utilizzata per eseguire query su un’istanza specifica di un template e che può valorizzata usando un parametro come ${APPLICATION_NAME}.