Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

Olá a todos deste blog! Este é o terceiro post de uma série em que mostramos como implantar aplicações web modernas no Red Hat OpenShift.

Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

Nas duas postagens anteriores, mostramos como implantar aplicações web modernas em apenas algumas etapas e como usar uma nova imagem S2I junto com uma imagem de servidor HTTP pronta para uso, como NGINX, usando construções encadeadas para orquestrar implantações de produção .

Hoje mostraremos como executar um servidor de desenvolvimento para sua aplicação na plataforma OpenShift e sincronizá-lo com o sistema de arquivos local, e também falar sobre o que são OpenShift Pipelines e como eles podem ser usados ​​como alternativa aos assemblies vinculados.

OpenShift como ambiente de desenvolvimento

Fluxo de trabalho de desenvolvimento

Como mencionado em primeiro post, o processo típico de desenvolvimento de aplicativos da Web modernos é simplesmente algum tipo de “servidor de desenvolvimento” que rastreia alterações em arquivos locais. Quando eles ocorrem, a construção do aplicativo é acionada e, em seguida, atualizada no navegador.

Na maioria das estruturas modernas, esse “servidor de desenvolvimento” é integrado às ferramentas de linha de comando correspondentes.

Exemplo local

Primeiro, vamos ver como isso funciona ao executar aplicativos localmente. Vamos pegar o aplicativo como exemplo Reagir de artigos anteriores, embora quase os mesmos conceitos de fluxo de trabalho se apliquem a todas as outras estruturas modernas.
Portanto, para iniciar o “servidor dev” em nosso exemplo React, inseriremos o seguinte comando:

$ npm run start

Então, na janela do terminal, veremos algo assim:

Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

E nosso aplicativo será aberto no navegador padrão:

Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

Agora, se fizermos alterações no arquivo, o aplicativo deverá ser atualizado no navegador.

OK, tudo fica claro com o desenvolvimento em modo local, mas como conseguir o mesmo no OpenShift?

Servidor de desenvolvimento em OpenShift

Se você se lembra, em postagem anterior, analisamos a chamada fase de execução da imagem S2I e vimos que, por padrão, o módulo serve é responsável por atender nossa aplicação web.

No entanto, se você olhar mais de perto executar script desse exemplo, ele contém a variável de ambiente $NPM_RUN, que permite executar seu comando.

Por exemplo, podemos usar o módulo nodeshift para implantar nosso aplicativo:

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

Nota: O exemplo acima é abreviado para ilustrar a ideia geral.

Aqui adicionamos a variável de ambiente NPM_RUN à nossa implantação, que informa ao tempo de execução para executar o comando yarn start, que inicia o servidor de desenvolvimento React dentro de nosso pod OpenShift.

Se você observar o log de um pod em execução, ele será parecido com isto:

Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

Claro, tudo isso não será nada até que possamos sincronizar o código local com o código, que também é monitorado em busca de alterações, mas reside em um servidor remoto.

Sincronizando código remoto e local

Felizmente, o nodeshift pode ajudar facilmente na sincronização e você pode usar o comando watch para rastrear alterações.

Portanto, depois de executarmos o comando para implantar o servidor de desenvolvimento para nosso aplicativo, podemos usar com segurança o seguinte comando:

$ npx nodeshift watch

Como resultado, será feita uma conexão com o pod em execução que criamos um pouco antes, a sincronização de nossos arquivos locais com o cluster remoto será ativada e os arquivos em nosso sistema local começarão a ser monitorados quanto a alterações.

Portanto, se atualizarmos agora o arquivo src/App.js, o sistema reagirá a essas alterações, copiará-as para o cluster remoto e iniciará o servidor de desenvolvimento, que então atualizará nossa aplicação no navegador.

Para completar a imagem, vamos mostrar como são esses comandos inteiros:

$ 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

O comando watch é uma abstração acima do comando oc rsync, você pode aprender mais sobre como ele funciona aqui.

Este foi um exemplo para React, mas exatamente o mesmo método pode ser usado com outros frameworks, basta definir a variável de ambiente NPM_RUN conforme necessário.

Pipelines Openshift

Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

A seguir falaremos sobre uma ferramenta como o OpenShift Pipelines e como ela pode ser usada como alternativa às compilações encadeadas.

O que são pipelines OpenShift

OpenShift Pipelines é um sistema de integração e entrega contínua de CI/CD nativo da nuvem projetado para organizar pipelines usando Tekton. Tekton é uma estrutura de CI/CD flexível e de código aberto nativa do Kubernetes que permite automatizar a implantação em várias plataformas (Kubernetes, sem servidor, máquinas virtuais, etc.) abstraindo da camada subjacente.

A compreensão deste artigo requer algum conhecimento sobre Pipelines, por isso recomendamos fortemente que você leia primeiro livro oficial.

Configurando seu ambiente de trabalho

Para brincar com os exemplos deste artigo, primeiro você precisa preparar seu ambiente de trabalho:

  1. Instale e configure um cluster OpenShift 4. Nossos exemplos usam CodeReady Containers (CRD) para isso, cujas instruções de instalação podem ser encontradas aqui.
  2. Depois que o cluster estiver pronto, você precisará instalar o Pipeline Operator nele. Não tenha medo, é fácil, instruções de instalação aqui.
  3. Baixar Tekton CLI (tk) aqui.
  4. Execute a ferramenta de linha de comando create-react-app para criar um aplicativo que você irá implantar (este é um aplicativo simples Reagir).
  5. (Opcional) Clone o repositório para executar o aplicativo de exemplo localmente com npm install e depois npm start.

O repositório do aplicativo também terá uma pasta k8s, que conterá os YAMLs do Kubernetes/OpenShift usados ​​para implantar o aplicativo. Haverá tarefas, ClusterTasks, recursos e pipelines que criaremos neste repositórios.

Descer

A primeira etapa do nosso exemplo é criar um novo projeto no cluster OpenShift. Vamos chamar este projeto de webapp-pipeline e criá-lo com o seguinte comando:

$ oc new-project webapp-pipeline

Este nome de projeto aparecerá no código mais tarde, portanto, se você decidir dar outro nome a ele, não se esqueça de editar o código de exemplo de acordo. A partir deste ponto, não iremos de cima para baixo, mas de baixo para cima: ou seja, criaremos primeiro todos os componentes do transportador e só depois o próprio transportador.

Então, antes de tudo...

Tarefas

Vamos criar algumas tarefas que ajudarão a implantar o aplicativo em nosso pipeline. A primeira tarefa - apply_manifests_task - é responsável por aplicar o YAML dos recursos do Kubernetes (serviço, implantação e rota) que estão localizados na pasta k8s da nossa aplicação. A segunda tarefa – update_deployment_task – é responsável por atualizar uma imagem já implantada para aquela criada pelo nosso pipeline.

Não se preocupe se ainda não estiver muito claro. Na verdade, essas tarefas são algo como utilitários, e as veremos com mais detalhes um pouco mais tarde. Por enquanto, vamos apenas criá-los:

$ 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

Então, usando o comando tkn CLI, verificaremos se as tarefas foram criadas:

$ tkn task ls

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

Nota: Estas são tarefas locais para o seu projeto atual.

Tarefas de cluster

As tarefas de cluster são basicamente iguais às tarefas simples. Ou seja, é um conjunto reutilizável de etapas que se combinam de uma forma ou de outra ao executar uma tarefa específica. A diferença é que uma tarefa de cluster está disponível em qualquer lugar do cluster. Para ver a lista de tarefas de cluster que são criadas automaticamente ao adicionar o Pipeline Operator, usaremos novamente o comando tkn CLI:

$ 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

Agora vamos criar duas tarefas de cluster. O primeiro irá gerar a imagem S2I e enviá-la para o registro interno do OpenShift; a segunda é construir nossa imagem baseada em NGINX, usando o aplicativo que já construímos como conteúdo.

Crie e envie a imagem

Ao criar a primeira tarefa, repetiremos o que já fizemos no artigo anterior sobre montagens vinculadas. Lembre-se de que usamos a imagem S2I (ubi8-s2i-web-app) para “construir” nossa aplicação e acabamos com uma imagem armazenada no registro interno do OpenShift. Agora usaremos esta imagem de aplicativo da web S2I para criar um DockerFile para nosso aplicativo e, em seguida, usaremos Buildah para fazer a construção real e enviar a imagem resultante para o registro interno do OpenShift, já que é exatamente isso que o OpenShift faz quando você implanta seus aplicativos usando NodeShift .

Como sabíamos de tudo isso, você pergunta? De versão oficial do Node.js oficial, nós apenas o copiamos e modificamos para nós mesmos.

Então, agora vamos criar a tarefa de cluster s2i-web-app:

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

Não analisaremos isso em detalhes, mas focaremos apenas no parâmetro OUTPUT_DIR:

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

Por padrão, esse parâmetro é igual a build, que é onde o React coloca o conteúdo montado. Outros frameworks usam caminhos diferentes, por exemplo, no Ember é dist. A saída da nossa primeira tarefa de cluster será uma imagem contendo o HTML, JavaScript e CSS que coletamos.

Construa uma imagem baseada em NGINX

Quanto à nossa segunda tarefa de cluster, ela deve construir uma imagem baseada em NGINX para nós, usando o conteúdo do aplicativo que já construímos. Essencialmente, esta é a parte da seção anterior onde examinamos as compilações encadeadas.

Para fazer isso, nós - exatamente como acima - criaremos uma tarefa de cluster webapp-build-runtime:

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

Se você observar o código dessas tarefas de cluster, verá que ele não especifica o repositório Git com o qual estamos trabalhando ou os nomes das imagens que estamos criando. Especificamos apenas o que exatamente estamos transferindo para o Git, ou uma determinada imagem onde a imagem final deve ser gerada. É por isso que essas tarefas de cluster podem ser reutilizadas ao trabalhar com outros aplicativos.

E aqui passamos graciosamente para o próximo ponto...

Recursos

Então, como acabamos de dizer, as tarefas do cluster devem ser o mais gerais possíveis, precisamos criar recursos que serão usados ​​como entrada (o repositório Git) e como saída (as imagens finais). O primeiro recurso que precisamos é o Git, onde reside nossa aplicação, mais ou menos assim:

# 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

Aqui PipelineResource é do tipo git. A chave url na seção params aponta para um repositório específico e especifica o branch master (isso é opcional, mas nós o escrevemos para completar).

Agora precisamos criar um recurso para a imagem onde serão salvos os resultados da tarefa s2i-web-app, isso é feito assim:

# 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

Aqui, PipelineResource é do tipo imagem e o valor do parâmetro url aponta para o registro de imagem interno do OpenShift, especificamente aquele localizado no namespace webapp-pipeline. Não se esqueça de alterar essa configuração se estiver usando um namespace diferente.

E por fim, o último recurso que precisamos também será do tipo imagem e esta será a imagem NGINX final que será usada durante a implantação:

# 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

Novamente, observe que este recurso armazena a imagem no registro interno do OpenShift no namespace webapp-pipeline.

Para criar todos esses recursos de uma vez, usamos o comando create:

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

Você pode ter certeza de que os recursos foram criados assim:

$ tkn resource ls

Pipeline transportador

Agora que temos todos os componentes necessários, vamos montar um pipeline a partir deles criando-o com o seguinte comando:

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

Mas antes de executarmos este comando, vamos dar uma olhada nesses componentes. O primeiro é o nome:

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

Então, na seção de especificações, vemos uma indicação dos recursos que criamos anteriormente:

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

Em seguida, criamos as tarefas que nosso pipeline precisa concluir. Primeiro de tudo, ele deve executar a tarefa s2i-web-app que já criamos:

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

Esta tarefa usa parâmetros de entrada (recurso gir) e saída (recurso de imagem de aplicativo da web integrado). Também lhe passamos um parâmetro especial para que não verifique o TLS, pois estamos usando certificados autoassinados:

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

A próxima tarefa é quase a mesma, só que aqui a tarefa de cluster webapp-build-runtime que já criamos é chamada:

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

Assim como na tarefa anterior, passamos um recurso, mas agora ele é uma imagem de aplicativo da web construída (a saída da nossa tarefa anterior). E como saída definimos novamente a imagem. Como esta tarefa deve ser executada após a anterior, adicionamos o 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

As próximas duas tarefas são responsáveis ​​por usar os arquivos YAML de serviço, rota e implantação que residem no diretório k8s de nossa aplicação web, e também por atualizar esta implantação ao criar novas imagens. Definimos essas duas tarefas de cluster no início do artigo.

Iniciando o transportador

Assim, todas as partes do nosso pipeline estão criadas e iremos executá-lo com o seguinte comando:

$ tkn pipeline start build-and-deploy-react

Neste estágio, a linha de comando é usada de forma interativa e você precisa selecionar os recursos apropriados em resposta a cada uma de suas solicitações: para o recurso git selecionamos web-application-repo, depois para o primeiro recurso de imagem - built-web-application -image e, finalmente, para o segundo recurso de imagem –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

Agora vamos verificar o status do pipeline usando o seguinte comando:

$ tkn pipeline logs -f

Depois que o pipeline for iniciado e o aplicativo implantado, podemos solicitar a rota publicada com o seguinte comando:

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

Para maior visualização, você pode visualizar nosso pipeline no modo Desenvolvedor do console web na seção Dutos, como mostrado na Fig. 1.

Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

Figura 1. Revisão de pipelines em execução.

Clicar em um pipeline em execução exibe detalhes adicionais, conforme mostrado na Figura 2.

Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

Arroz. 2. Informações adicionais sobre o pipeline.

Após mais informações, você pode ver os aplicativos em execução na visualização topologia, conforme mostrado na Fig.3.

Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

Fig 3. Pod lançado.

Clicar no círculo no canto superior direito do ícone abre nosso aplicativo, conforme mostrado na Fig.

Aplicativos modernos no OpenShift, parte 3: OpenShift como ambiente de desenvolvimento e OpenShift Pipelines

Arroz. 4. Executando o aplicativo React.

Conclusão

Assim, mostramos como executar um servidor de desenvolvimento para sua aplicação no OpenShift e sincronizá-lo com o sistema de arquivos local. Também vimos como simular um modelo de construção encadeada usando OpenShift Pipelines. Todos os códigos de exemplo deste artigo podem ser encontrados aqui.

Recursos adicionais (PT)

Anúncios dos próximos webinars

Estamos iniciando uma série de webinars nas sextas-feiras sobre a experiência nativa usando Red Hat OpenShift Container Platform e Kubernetes:

Fonte: habr.com

Adicionar um comentário