Estratégia para implantar / hospedar sites estáticos baseados em javascript em contêineres


7

De tempos em tempos, isso ocorre em várias de nossas equipes de desenvolvimento, sem que tenhamos descoberto o caminho "certo":

Usamos muitos aplicativos da Web baseados em reação que "compilam" em sites estáticos que são apenas alguns arquivos html, js e css.

No entanto, a "construção" desses aplicativos utiliza várias variáveis ​​que ativam / desativam sinalizadores de recursos, configuram URLs de back-end etc. Isso significa que não podemos "construir" um binário no sentido tradicional e apenas aplicar um arquivo de configuração no deploy- time - o "build" em si precisa ter essas variáveis ​​específicas do ambiente definidas e, portanto, o único momento em que podemos "build" é no momento da implantação.

Por enquanto, resolvemos isso injetando as variáveis ​​de ambiente necessárias no contêiner do Docker e executamos um cmd inicial ao longo das linhas de

npm build && nginx run

Isso tem algumas desvantagens:

  1. O processo de compilação requer muita CPU / memória em relação aos requisitos de tempo de execução do contêiner. Isso significa que precisamos escalar o contêiner para o processo de compilação em vez dos requisitos de tempo de execução - o que parece errado
  2. Falhas de construção são difíceis de "rastrear". Podemos usar verificações de saúde no Kubernetes, mas se uma compilação levar 2 minutos, ainda temos que esperar 3 minutos (1 extra por segurança) antes de começarmos a testar o ponto de extremidade de verificação de saúde do contêiner para ver se está vivo.
  3. As implantações podem demorar muito: se configurarmos o Kubernetes para fazer uma implantação "serial", ele iniciará cada pod e aguardará o período "initialDelay" de 2 a 3 minutos antes de iniciar o próximo. Isso significa que observamos facilmente um tempo de implantação de 10 minutos se a implantação for dimensionada para 3-4 pods.

Tudo isso me parece muito abaixo do ideal. Eu ficaria muito interessado em saber como a comunidade resolve o dilema "compilar no momento da implantação" com os modernos aplicativos javascript.

Percebo que, para o Kubernetes, poderíamos usar "init-containers" que executam a construção, colocar os artiacts em armazenamento persistente e fazer com que os contêineres de aplicativos simplesmente retirassem do armazenamento persistente durante a inicialização, mas isso ainda parece mais "contornar" o problema do que resolvendo o problema raiz.


Desculpe, eu não entendo - por que você está executando npm buildem tempo de execução e não durante a construção do contêiner?
— Xiong Chiamiov 02/02

@XiongChiamiov Suponho que a configuração do frontend seja feita durante a compilação e não seja modificável sem a reconstrução (eu diria que ela deve ser separada em um arquivo incluído que, na pior das hipóteses, pode ser 'sed' na inicialização do contêiner)
— Tensibai

exatamente. npm buildé apenas um comando arbitrário. Pode ser react buildou o sanity buildque a estrutura JS espera. Somos forçados a fazê-lo na implantação de contêineres, porque é quando conhecemos o ambiente build.
— Trondh

Respostas:


5

Do meu ponto de vista, a melhor abordagem seria:

  1. Processo de construção separado usando Jenkins que criaria o projeto NodeJS na distribuição e o envolveria na imagem do Docker
  2. Gire o registro do Docker que acumulará imagens do Docker do Jenkins (esse registro deve estar acessível no cluster Kubernetes)
  3. Mova as variáveis ​​de ambiente para os segredos do Jenkins ou use uma ferramenta separada para coletar e combinar configurações do repositório Git externo (usamos o Spring Cloud Config por meio da API REST para coletar definições de json / yml para cada aplicativo em qualquer ambiente)

Usando o Jenkins, você pode configurar o sistema de entrega contínua com base em pipelines genéricos. O fluxo possível seria:

  1. Os desenvolvedores finalizam seu trabalho em correspondência com o GitFlow (a última solicitação de solicitação mesclada no ramo Release)
  2. O Webhook aciona o pipeline Jenkins:
    • Etapa 1: coletar a definição do ambiente
    • Etapa 2: criar o aplicativo NodeJS usando o npm
    • Etapa 3: criar a imagem do Nginx Docker com distribuição
    • Etapa 4: enviar a imagem do Docker para o registro do Docker
    • Etapa 5: implantar / atualizar o serviço no Kubernetes usando definições padrão
  3. Notificações enviadas em relação aos resultados

Esse processo pode ser visualizado usando o Rancher. Eu posso responder suas perguntas no chat.


Então você está propondo ter uma imagem por ambiente? Essa é uma solução alternativa consumindo um monte de espaço para apenas algumas variáveis ...
— Tensibai

@Tensibai ur falando sobre imagens de ~ 15mb por cada ambiente. Com rotação e serviço de zelador adicional, 1 Gb seria suficiente para lidar com todos os projetos.
— Maksim

Com base nessa solução, como você produziria várias "configurações" de um aplicativo, por exemplo, uma para "teste" e outra para "prod"? (vamos fingir que existe uma configuração chamada "BackendApi" que difere, por exemplo.
— Trondh

@ Trondh como eu disse, usamos o Spring Cloud Config. O que ele faz é para cada aplicativo que obtém a configuração básica e aplica configurações adicionais profiles. Por exemplo, se você solicitar, https://config/backend.ymlreceberá configuração application.ymle propriedades adicionais de backend.yml. Pois https://config/backend-stage.ymlele responderá com propriedades aplicadas por application.yml<- backend.yml<- backend-stage.yml.
— Maksim

O @Maksim 15MB para alguns bytes de texto é um desperdício, em algum momento com centenas de microsserviços em vários ambientes com várias versões, ele se tornará TB de dados para os mesmos poucos bytes na origem. Esse é um caminho errado na minha opinião, se eu entendi direito o que você está propondo, pois você não pode garantir que a imagem no controle de qualidade e no produto seja realmente a mesma de duas versões (mesmo com o mesmo código, elas não serão o mesmo ID e validação se tornam uma bagunça). Mas talvez eu tenha entendido errado e você tenha apenas uma imagem e configuração ao girar o pod, se é que não entendi corretamente sua postagem.
— Tensibai
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.