Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

Ciao a tutti su questo blog! Questo è il terzo post di una serie in cui mostriamo come distribuire applicazioni Web moderne su Red Hat OpenShift.

Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

Nei due post precedenti, abbiamo mostrato come distribuire applicazioni web moderne in pochi passaggi e come utilizzare una nuova immagine S2I insieme a un'immagine del server HTTP standard, come NGINX, utilizzando build concatenate per orchestrare le distribuzioni di produzione .

Oggi mostreremo come eseguire un server di sviluppo per la tua applicazione sulla piattaforma OpenShift e sincronizzarlo con il file system locale, e parleremo anche di cosa sono le OpenShift Pipelines e come possono essere utilizzate come alternativa agli assembly collegati.

OpenShift come ambiente di sviluppo

Flusso di lavoro di sviluppo

Come menzionato in primo post, il tipico processo di sviluppo per le moderne applicazioni web è semplicemente una sorta di "server di sviluppo" che tiene traccia delle modifiche ai file locali. Quando si verificano, viene attivata la compilazione dell'applicazione e quindi viene aggiornata nel browser.

Nella maggior parte dei framework moderni, tale “server di sviluppo” è integrato nei corrispondenti strumenti da riga di comando.

Esempio locale

Innanzitutto, vediamo come funziona quando si eseguono applicazioni localmente. Prendiamo l'applicazione come esempio Reagire dagli articoli precedenti, sebbene quasi gli stessi concetti di flusso di lavoro si applichino a tutti gli altri framework moderni.
Quindi, per avviare il "server di sviluppo" nel nostro esempio React, inseriremo il seguente comando:

$ npm run start

Quindi nella finestra del terminale vedremo qualcosa del genere:

Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

E la nostra applicazione si aprirà nel browser predefinito:

Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

Ora, se apportiamo modifiche al file, l'applicazione dovrebbe aggiornarsi nel browser.

OK, tutto è chiaro con lo sviluppo in modalità locale, ma come ottenere lo stesso su OpenShift?

Server di sviluppo su OpenShift

Se ricordi, dentro messaggio precedente, abbiamo esaminato la cosiddetta fase di esecuzione dell'immagine S2I e abbiamo visto che, per impostazione predefinita, il modulo serve è responsabile della manutenzione della nostra applicazione web.

Tuttavia, se dai un'occhiata più da vicino esegui script da quell'esempio, contiene la variabile d'ambiente $NPM_RUN, che ti consente di eseguire il tuo comando.

Ad esempio, possiamo utilizzare il modulo nodeshift per distribuire la nostra applicazione:

$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app

Nota: l'esempio sopra è abbreviato per illustrare l'idea generale.

Qui abbiamo aggiunto la variabile di ambiente NPM_RUN alla nostra distribuzione, che indica al runtime di eseguire il comando Yarn Start, che avvia il server di sviluppo React all'interno del nostro pod OpenShift.

Se guardi il registro di un pod in esecuzione, sarà simile a questo:

Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

Naturalmente, tutto questo non sarà nulla finché non saremo in grado di sincronizzare il codice locale con il codice, anch'esso monitorato per le modifiche, ma residente su un server remoto.

Sincronizzazione del codice remoto e locale

Fortunatamente, nodeshift può facilmente aiutare con la sincronizzazione e puoi utilizzare il comando watch per tenere traccia delle modifiche.

Quindi, dopo aver eseguito il comando per distribuire il server di sviluppo per la nostra applicazione, possiamo tranquillamente utilizzare il seguente comando:

$ npx nodeshift watch

Di conseguenza, verrà stabilita una connessione al pod in esecuzione che abbiamo creato poco prima, verrà attivata la sincronizzazione dei nostri file locali con il cluster remoto e i file sul nostro sistema locale inizieranno a essere monitorati per eventuali modifiche.

Pertanto, se ora aggiorniamo il file src/App.js, il sistema reagirà a queste modifiche, le copierà sul cluster remoto e avvierà il server di sviluppo, che aggiornerà poi la nostra applicazione nel browser.

Per completare l'immagine, mostriamo come appaiono questi comandi interi:

$ npx nodeshift --strictSSL=false --dockerImage=nodeshift/ubi8-s2i-web-app --build.env YARN_ENABLED=true --expose --deploy.env NPM_RUN="yarn start" --deploy.port 3000

$ npx nodeshift watch --strictSSL=false

Il comando watch è un'astrazione sopra il comando oc rsync, puoi saperne di più su come funziona qui.

Questo era un esempio per React, ma lo stesso identico metodo può essere utilizzato con altri framework, basta impostare la variabile d'ambiente NPM_RUN secondo necessità.

Pipeline OpenShift

Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

Successivamente parleremo di uno strumento come OpenShift Pipelines e di come può essere utilizzato come alternativa alle build concatenate.

Cosa sono le pipeline OpenShift

OpenShift Pipelines è un sistema di integrazione e distribuzione continua CI/CD nativo del cloud progettato per l'organizzazione di pipeline utilizzando Tekton. Tekton è un framework CI/CD nativo Kubernetes open source flessibile che consente di automatizzare la distribuzione su varie piattaforme (Kubernetes, serverless, macchine virtuali, ecc.) estraendo dal livello sottostante.

La comprensione di questo articolo richiede una certa conoscenza di Pipelines, quindi ti consigliamo vivamente di leggerlo prima libro di testo ufficiale.

Configurazione dell'ambiente di lavoro

Per giocare con gli esempi presenti in questo articolo, devi prima preparare il tuo ambiente di lavoro:

  1. Installa e configura un cluster OpenShift 4. I nostri esempi utilizzano CodeReady Containers (CRD) per questo, le cui istruzioni di installazione possono essere trovate qui.
  2. Dopo che il cluster è pronto, è necessario installare Pipeline Operator su di esso. Non aver paura, è facile, istruzioni di installazione qui.
  3. Scarica Tekton CLI (tkn) qui.
  4. Esegui lo strumento da riga di comando create-react-app per creare un'applicazione che poi distribuirai (si tratta di un'applicazione semplice Reagire).
  5. (Facoltativo) Clonare il repository per eseguire l'applicazione di esempio localmente con npm install e quindi npm start.

Il repository dell'applicazione avrà anche una cartella k8s, che conterrà gli YAML Kubernetes/OpenShift utilizzati per distribuire l'applicazione. Ci saranno attività, attività cluster, risorse e pipeline che creeremo in questo repository.

Scendendo

Il primo passo per il nostro esempio è creare un nuovo progetto nel cluster OpenShift. Chiamiamo questo progetto webapp-pipeline e creiamolo con il seguente comando:

$ oc new-project webapp-pipeline

Il nome del progetto apparirà nel codice in seguito, quindi se decidi di chiamarlo diversamente, non dimenticare di modificare di conseguenza il codice di esempio. Partendo da questo punto non andremo dall'alto verso il basso, ma dal basso verso l'alto: creeremo cioè prima tutti i componenti del trasportatore, e solo dopo il trasportatore stesso.

Quindi, prima di tutto...

Compiti

Creiamo un paio di attività, che aiuteranno quindi a distribuire l'applicazione all'interno della nostra pipeline. La prima attività - apply_manifests_task - è responsabile dell'applicazione dello YAML di quelle risorse Kubernetes (servizio, distribuzione e percorso) che si trovano nella cartella k8s della nostra applicazione. La seconda attività – update_deployment_task – è responsabile dell'aggiornamento di un'immagine già distribuita a quella creata dalla nostra pipeline.

Non preoccuparti se non è ancora molto chiaro. In realtà, queste attività sono qualcosa di simile alle utilità e le esamineremo più in dettaglio un po 'più tardi. Per ora, creiamoli e basta:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/update_deployment_task.yaml
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/apply_manifests_task.yaml

Quindi, utilizzando il comando tkn CLI, controlleremo che le attività siano state create:

$ tkn task ls

NAME                AGE
apply-manifests     1 minute ago
update-deployment   1 minute ago

Nota: queste sono attività locali per il tuo progetto corrente.

Compiti del cluster

Le attività del cluster sono fondamentalmente le stesse delle attività semplici. Cioè, è una raccolta riutilizzabile di passaggi che vengono combinati in un modo o nell'altro durante l'esecuzione di un'attività specifica. La differenza è che un'attività del cluster è disponibile ovunque all'interno del cluster. Per visualizzare l'elenco delle attività del cluster create automaticamente quando si aggiunge l'operatore Pipeline, utilizzeremo nuovamente il comando CLI tkn:

$ tkn clustertask ls

NAME                       AGE
buildah                    1 day ago
buildah-v0-10-0            1 day ago
jib-maven                  1 day ago
kn                         1 day ago
maven                      1 day ago
openshift-client           1 day ago
openshift-client-v0-10-0   1 day ago
s2i                        1 day ago
s2i-go                     1 day ago
s2i-go-v0-10-0             1 day ago
s2i-java-11                1 day ago
s2i-java-11-v0-10-0        1 day ago
s2i-java-8                 1 day ago
s2i-java-8-v0-10-0         1 day ago
s2i-nodejs                 1 day ago
s2i-nodejs-v0-10-0         1 day ago
s2i-perl                   1 day ago
s2i-perl-v0-10-0           1 day ago
s2i-php                    1 day ago
s2i-php-v0-10-0            1 day ago
s2i-python-3               1 day ago
s2i-python-3-v0-10-0       1 day ago
s2i-ruby                   1 day ago
s2i-ruby-v0-10-0           1 day ago
s2i-v0-10-0                1 day ago

Ora creiamo due attività del cluster. Il primo genererà l'immagine S2I e la invierà al registro interno di OpenShift; il secondo è costruire la nostra immagine basata su NGINX, utilizzando come contenuto l'applicazione che abbiamo già realizzato.

Crea e invia l'immagine

Quando creeremo la prima attività, ripeteremo ciò che abbiamo già fatto nell'articolo precedente sugli assiemi collegati. Ricordiamo che abbiamo utilizzato l'immagine S2I (ubi8-s2i-web-app) per "costruire" la nostra applicazione e ci siamo ritrovati con un'immagine archiviata nel registro interno di OpenShift. Ora utilizzeremo questa immagine dell'app Web S2I per creare un DockerFile per la nostra app e quindi utilizzeremo Buildah per eseguire la build effettiva e inviare l'immagine risultante al registro interno di OpenShift, poiché è esattamente ciò che fa OpenShift quando distribuisci le tue applicazioni utilizzando NodeShift .

Come facevamo a sapere tutto questo, chiedi? Da versione ufficiale di Node.js ufficiale, l'abbiamo semplicemente copiato e modificato per noi stessi.

Quindi, ora creiamo l'attività del cluster s2i-web-app:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml

Non lo analizzeremo nel dettaglio, ma ci concentreremo solo sul parametro OUTPUT_DIR:

params:
      - name: OUTPUT_DIR
        description: The location of the build output directory
        default: build

Per impostazione predefinita, questo parametro è uguale a build, che è dove React inserisce il contenuto assemblato. Altri framework utilizzano percorsi diversi, ad esempio in Ember è dist. L'output della nostra prima attività del cluster sarà un'immagine contenente HTML, JavaScript e CSS che abbiamo raccolto.

Costruisci un'immagine basata su NGINX

Per quanto riguarda la nostra seconda attività del cluster, dovrebbe creare per noi un'immagine basata su NGINX, utilizzando il contenuto dell'applicazione che abbiamo già creato. Essenzialmente, questa è la parte della sezione precedente in cui abbiamo esaminato le build concatenate.

Per fare ciò, esattamente come sopra, creeremo un'attività cluster webapp-build-runtime:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml

Se guardi il codice di queste attività del cluster, puoi vedere che non specifica il repository Git con cui stiamo lavorando o i nomi delle immagini che stiamo creando. Specifichiamo solo cosa stiamo trasferendo esattamente su Git, o una determinata immagine in cui dovrebbe essere generata l'immagine finale. Ecco perché queste attività del cluster possono essere riutilizzate quando si lavora con altre applicazioni.

E qui passiamo con grazia al punto successivo...

Ресурсы

Quindi, poiché, come abbiamo appena detto, le attività del cluster dovrebbero essere il più generali possibile, dobbiamo creare risorse che verranno utilizzate come input (il repository Git) e come output (le immagini finali). La prima risorsa di cui abbiamo bisogno è Git, dove risiede la nostra applicazione, qualcosa del genere:

# This resource is the location of the git repo with the web application source
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: web-application-repo
spec:
  type: git
  params:
    - name: url
      value: https://github.com/nodeshift-starters/react-pipeline-example
    - name: revision
      value: master

Qui PipelineResource è di tipo git. La chiave URL nella sezione params punta a un repository specifico e specifica il ramo master (questo è facoltativo, ma lo scriviamo per completezza).

Ora dobbiamo creare una risorsa per l'immagine in cui verranno salvati i risultati dell'attività s2i-web-app, in questo modo:

# This resource is the result of running "npm run build",  the resulting built files will be located in /opt/app-root/output
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: built-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-application:latest

Qui PipelineResource è di tipo image e il valore del parametro url punta al registro interno delle immagini OpenShift, in particolare quello situato nello spazio dei nomi webapp-pipeline. Non dimenticare di modificare questa impostazione se utilizzi uno spazio dei nomi diverso.

Ed infine, anche l'ultima risorsa di cui avremo bisogno sarà di tipo image e questa sarà l'immagine NGINX finale che verrà poi utilizzata durante il deploy:

# This resource is the image that will be just the static html, css, js files being run with nginx
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: runtime-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtime-web-application:latest

Ancora una volta, tieni presente che questa risorsa memorizza l'immagine nel registro OpenShift interno nello spazio dei nomi webapp-pipeline.

Per creare tutte queste risorse contemporaneamente, utilizziamo il comando create:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml

Puoi assicurarti che le risorse siano state create in questo modo:

$ tkn resource ls

Conduttura del trasportatore

Ora che abbiamo tutti i componenti necessari, assembliamo da essi una pipeline creandola con il seguente comando:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml

Ma prima di eseguire questo comando, diamo un'occhiata a questi componenti. Il primo è il nome:

apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: build-and-deploy-react

Quindi nella sezione specifiche vediamo l'indicazione delle risorse che abbiamo creato in precedenza:

spec:
  resources:
    - name: web-application-repo
      type: git
    - name: built-web-application-image
      type: image
    - name: runtime-web-application-image
      type: image

Creiamo quindi le attività che la nostra pipeline deve completare. Innanzitutto deve eseguire il task s2i-web-app che abbiamo già creato:

tasks:
    - name: build-web-application
      taskRef:
        name: s2i-web-app
        kind: ClusterTask

Questa attività accetta parametri di input (risorsa gir) e di output (risorsa immagine applicazione Web incorporata). Gli passiamo anche un parametro speciale in modo che non verifichi TLS poiché stiamo utilizzando certificati autofirmati:

resources:
        inputs:
          - name: source
            resource: web-application-repo
        outputs:
          - name: image
            resource: built-web-application-image
      params:
        - name: TLSVERIFY
          value: "false"

L'attività successiva è quasi la stessa, solo che qui l'attività del cluster webapp-build-runtime che abbiamo già creato si chiama:

name: build-runtime-image
    taskRef:
      name: webapp-build-runtime
      kind: ClusterTask

Come per l'attività precedente, passiamo una risorsa, ma ora è l'immagine dell'applicazione web incorporata (l'output della nostra attività precedente). E come output impostiamo nuovamente l'immagine. Poiché questa attività deve essere eseguita dopo la precedente, aggiungiamo il campo runAfter:

resources:
        inputs:
          - name: image
            resource: built-web-application-image
        outputs:
          - name: image
            resource: runtime-web-application-image
        params:
        - name: TLSVERIFY
          value: "false"
      runAfter:
        - build-web-application

Le due attività successive sono responsabili dell'utilizzo dei file YAML del servizio, del percorso e della distribuzione che risiedono nella directory k8s della nostra applicazione Web e anche dell'aggiornamento di questa distribuzione durante la creazione di nuove immagini. Abbiamo definito queste due attività del cluster all'inizio dell'articolo.

Avvio del trasportatore

Quindi, tutte le parti della nostra pipeline vengono create e la eseguiremo con il seguente comando:

$ tkn pipeline start build-and-deploy-react

In questa fase, la riga di comando viene utilizzata in modo interattivo ed è necessario selezionare le risorse appropriate in risposta a ciascuna delle sue richieste: per la risorsa git, selezionare web-application-repo, quindi per la prima risorsa immagine, built-web-application -image e, infine, per la seconda risorsa immagine –runtime-web-application-image:

? Choose the git resource to use for web-application-repo: web-application-repo (https://github.com/nodeshift-starters/react-pipeline-example)
? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-
application:latest)
? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtim
e-web-application:latest)
Pipelinerun started: build-and-deploy-react-run-4xwsr

Ora controlliamo lo stato della pipeline utilizzando il seguente comando:

$ tkn pipeline logs -f

Una volta avviata la pipeline e distribuito l'applicazione, possiamo richiedere la route pubblicata con il seguente comando:

$ oc get route react-pipeline-example --template='http://{{.spec.host}}'

Per una maggiore visualizzazione è possibile visionare la nostra pipeline nella modalità Sviluppatore della console web nella sezione Condotte, come mostrato in Fig. 1.

Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

Fig. 1. Revisione delle condutture in esecuzione.

Facendo clic su una pipeline in esecuzione vengono visualizzati ulteriori dettagli, come mostrato nella Figura 2.

Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

Riso. 2. Ulteriori informazioni sulla pipeline.

Dopo ulteriori informazioni, puoi vedere le applicazioni in esecuzione nella vista Topologia, come mostrato in Fig.3.

Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

Fig 3. Pod lanciato.

Facendo clic sul cerchio nell'angolo in alto a destra dell'icona si apre la nostra applicazione, come mostrato in Fig. 4.

Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e OpenShift Pipelines

Riso. 4. Esecuzione dell'applicazione React.

conclusione

Quindi, abbiamo mostrato come eseguire un server di sviluppo per la tua applicazione su OpenShift e sincronizzarlo con il file system locale. Abbiamo anche esaminato come simulare un modello di creazione concatenata utilizzando OpenShift Pipelines. È possibile trovare tutti i codici di esempio di questo articolo qui.

Risorse aggiuntive (EN)

Annunci dei prossimi webinar

Stiamo avviando una serie di webinar del venerdì sull'esperienza nativa utilizzando Red Hat OpenShift Container Platform e Kubernetes:

Fonte: habr.com

Aggiungi un commento