Creare l’immagine Docker di OpenWhisk
Adesso che sappiamo come compilare OpenWhisk in locale, è il momento di automatizzare il tutto scrivendo un Dockerfile.
Un Dockerfile è un descrittore che Docker utilizza per creare le sue immagini; generalmente contiene tutti i comandi di compilazione necessari, più eventuali direttive sempre relative alla creazione di immagini. Vediamo passo passo come scrivere un Dockerfile per OpenWhisk standalone.
Direttiva FROM
La prima direttiva che vedremo è FROM che sostanzialmente indica un’immagine base che possiamo usare come punto di partenza. Poiché OpenWhisk è fatto in Scala, iniziamo proprio con
FROM scala as builder
WORKDIR
Notare che abbiamo dato un nome all’immagine, perché la utilizzeremo solo come area temporanea per la compilazione e ci serve il nome per riferirla dopo. E notare che abbiamo impostato come directory principale la radice.
Aggiungere componenti per la compilazione
A questo punto ci preoccupiamo di aggiungere un po’ di componenti che si serviranno per la compilazione. Java — che è usato da Scala — è già presente nell’immagine Scala, ma mancano git, che serve per scaricare i sorgent, e npm più nodejs, che servono per compilare il frontend. Quindi li aggiungiamo usando la direttiva RUN:
RUN apt-get update && apt-get install -y git nodejs npm
L’immagine di Scala è basata, come moltissime altre immagini Docker, su Linux Debian. Quindi utilizziamo apt-get install che è il comando di questa distribuzione per installare pacchetti. Notare che, prima di installare, dobbiamo precedere il comando con una apt-get update per aggiornare gli indici per scaricare i pacchetti.
Ci servono anche degli altri componenti che non sono disponibili nel repository ufficiale di Debian. In particolare, ci serve una specifica versione di Docker compilata in modalità statica e la riga di comando di OpenWhisk. Aggiungiamo questi componenti con dei download diretti dei pacchetti binari in questione:
RUN curl https://download.docker.com/linux/static/stable/x86_64/docker-18.06.3-ce.tgz | tar xzvf -
RUN curl -sL https://github.com/apache/openwhisk-cli/releases/download/1.2.0/OpenWhisk_CLI-1.2.0-linux-amd64.tgz | tar xzvf -
Compilazione e build
A questo punto possiamo scaricare e compilare: “cloniamo” i sorgenti da GitHub, cambiamo alla directory di lavoro e compiliamo il tutto:
RUN git clone https://github.com/apache/openwhisk
RUN cd openwhisk && ./gradlew :core:standalone:build
Ora l’immagine è più o meno pronta, ma non vogliamo portarci dietro tutti i sorgenti e gli artefatti della compilazione. Per questo motivo usiamo la feature di Docker che permette di fare delle build, e poi usare un’altra immagine come base per produrre il risultato finale, estraendo dalla prima immagine i file che servono.
Quindi facciamo esattamente questo: aggiungiamo al Dockerfile le direttive per “ripartire” da capo con l’immagine Scala, aggiorniamo i pacchetti all’ultima versione e poi ci mettiamo dentro solo quello che serve.
FROM scala
RUN apt-get update && apt-get -y upgrade
COPY --from=builder /openwhisk/bin/openwhisk-standalone.jar /lib/openwhisk-standalone.jar
COPY --from=builder /docker/docker /usr/bin/docker
COPY --from=builder /wsk /usr/bin/wsk
Tutto pronto per “rilasciare”. Impostiamo ora la directory principale (usiamo /home) e il comando di avvio (spiegato nel prossimo paragrafo).
ADD start.sh /usr/bin/start.sh
WORKDIR /homem
ENTRYPOINT [“/usr/bin/bash”, “/usr/bin/start.sh”]
È importante notare che utilizzando ENTRYPOINT questo comando viene sempre eseguito quando lanceremo l’immagine con docker run <immagine> [<parametri>]. I parametri, come vedremo, verranno propagati al runtime stesso e ci saranno utili in seguito per collegare altri componenti.
Lo script di avvio
OpenWhisk ha parecchi parametri, che useremo intensamente nei prossimi articoli. Questi parametri possono essere passati come Java System Property, o con variabili di ambiente o con file di configurazione. AI nostri fini, per l’esecuzione di OpenWhisk standalone in una singola immagine Docker occorre impostare 3 properties:
- il nome dell’host all’interno dell’immagine Docker;
- l’indirizzo IP dove il runtime deve stare in ascolto;
- l’indirizzo esterno che si usa per connettersi.
Le prime due possono essere ricavate da un comando Linux:
$(hostname) e $(hostname –i)
La terza dipende da una configurazione e quindi va passata con una variabile di ambiente.
Infine, dato che all’interno di una immagine Docker non possiamo lanciare il browser, dovremo chiedere a OpenWhisk di farlo, con il parametro –no-browser. Tradotto in codice questo diventa il seguente scritpt start.sh:
java $EXTRA_JVM_ARGS
-Dwhisk.standalone.host.name=“$(hostname)”
-Dwhisk.standalone.host.internal=“$(hostname -i)”
-Dwhisk.standalone.host.external=“$HOST_EXTERNAL”
-jar /usr/lib/openwhisk-standalone.jar --no-browser “$@”
Non useremo gli EXTRA_JVM_ARGS per ora, ma abbiamo lasciato un modo per poterli specificare in seguito se servissero. E serviranno…
Conclusioni
Abbiamo visto fin qui come compilare OpenWhisk (in versione standalone) e poi come usare le istruzioni di compilazione per creare un’immagine Docker. Nella prossima parte, terza e ultima, illustreremo come chiudere il cerchio lanciando l’immagine Docker che abbiamo costruito. Il che, come vedremo, non è banale.
Michele Sciabarrà, CTO della Sciabarra srl (ma vah!) si occupa di Java da... molto tempo. Per esempio nel 1996 ha scritto il primo articolo su Java, sulla storica rivista Computer Programming, e ha partecipato alla prima conferenza italiana su Java, presentando alcune delle sue applicazioni, tra le prime in Italia realizzate in Java. Strada facendo ha inoltre scritto un paio di libri, è andato a lavorare a Londra dove è stato anche dipendente di Fatwire Software. Dopo mille peripezie si occupa attualmente (che strano) di Fatwire... ops Oracle WebCenter Site e scrive sul suo sito http://www.sciabarra.com/ uno dei più apprezzati blog sull