Gerenciando o Dockerfile dinamicamente para diferentes inquilinos na implementação do pipeline de CI / CD

13

Estou tentando implementar o pipeline de CI / CD para o meu projeto usando Docker, Kubernetes e Jenkins. Meu aplicativo é um aplicativo multilocatário, no qual as variáveis ​​do aplicativo de banco de dados são diferentes para diferentes inquilinos.

Estratégia de Aplicação

Quando estou criando uma imagem do Docker, estou usando um Dockerfile. E eu mantenho meu Dockerfile dentro do meu repositório de código SVN. Para cada inquilino, o repositório de código é o mesmo. Quando estou construindo uma imagem, naquele momento preciso criar imagens diferentes para diferentes inquilinos.

Implementação de Dockerfile

No meu arquivo docker, estou adicionando um ponto de entrada como o seguinte,

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=tenant1config" , "TestProject.war"]

Se eu precisar criar uma imagem do Docker para outro inquilino, preciso adicionar
-Dspring.profiles.active=tenant2config

Portanto, o ponto de entrada no Dockerfile é dinâmico.

Minha confusão

  1. Para gerenciar o comando do ponto de entrada no Dockerfile é possível dinamicamente?
  2. Ou Preciso adicionar outro Dockerfile para outro inquilino? E precisa executar o comando docker build separadamente para inquilino separado?

Como posso encontrar uma boa maneira padrão de implementação desse problema?

Jacob
fonte
3
Você pode usar uma variável de ambiente no seu ENTRYPOINTie, em ... -Dspring.profiles.active=${TENANT}seguida, definir o ambiente correto durante suas implantações.
masseyb

Respostas:

13

Citando 12 Fator - Configuração

A configuração de um aplicativo é tudo o que provavelmente varia entre implantações (preparação, produção, ambientes de desenvolvedor etc.). Isso inclui:

  • Identificadores de recursos para o banco de dados, Memcached e outros serviços de apoio

  • Credenciais para serviços externos, como Amazon S3 ou Twitter

  • Valores por implantação, como o nome do host canônico da implantação

Você não deve criar imagens de janela de encaixe separadas para cada inquilino, pois o binário deve ser o mesmo e as configurações de tempo de execução devem ser injetadas no ambiente.

Existem diferentes opções para injetar a configuração do tempo de execução

  1. Variáveis ​​ambientais

Em vez de codificar o perfil no ponto de entrada, adicione uma variável de ambiente

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=$TENANT_PROFILE" , "TestProject.war"]

Em seguida, injete a variável de ambiente na configuração de implantação do kubernetes Consulte https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/

  1. Monte a configuração do perfil como uma configuração e faça referência a ela

Seu ponto de entrada será semelhante

ENTRYPOINT ["java", "-jar", --spring.config.location="file:/path/to/tenantconfig.yaml" , "TestProject.war"] Em seguida, monte o arquivo de configuração necessário como uma configuração do kubernetes.

De qualquer maneira, externalize a configuração de tempo de execução da imagem do docker e injete-a na configuração de implementação como uma variável de ambiente ou uma configuração.

Mohit Mutha
fonte
11
SPRING_PROFILES_ACTIVE como variável de ambiente deve funcionar imediatamente. Não há necessidade do parâmetro adicional java.
Manuel Polacek
3

Você pode usar o ARGS da janela de encaixe, que estará disponível apenas no momento da construção e no ponto de entrada.

docker build --build-arg CONFIG_FILE=<file_name> -t tag_name .

CONFIG_FILE manterá o local do arquivo de configuração e você poderá transmiti-lo dinamicamente. Substitua seu ponto de entrada por$CONFIG_FILE

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=$CONFIG_FILE" , "TestProject.war"]
Sivakumar
fonte
ARG CONFIG_FILE - deve ser declarado dentro do Dockerfile
Roman M
0

Consulte - Práticas recomendadas do Dockerfile

ENTRYPOINT ajuda a configurar um contêiner para ser executado como um executável que pode receber argumentos em tempo de execução

Qualquer propriedade dinâmica que você queira substituir pode ser executada em tempo de execução com a mesma imagem.

Você pode passar o argumento necessário em tempo de execução.

Satish Kumar Nadarajan
fonte