Montagem e implantação dos mesmos microsserviços com o werf e o GitLab CI



Há dois anos, publicamos o artigo " Criando projetos com o GitLab CI: um .gitlab-ci.yml para centenas de aplicativos ", e agora falaremos sobre a solução de um problema semelhante hoje. O novo material é sobre como você pode criar processos de CI / CD para um grande número de aplicativos semelhantes com o advento de include no .gitlab-ci.yml e o advento do werf para substituir o dapp.

Introdutório


Nas instruções adicionais fornecidas no artigo, a seguinte situação é considerada:

  • Há um aplicativo cliente grande, dividido em vários repositórios.
  • Cada repositório é um aplicativo separado que deve ser executado em um cluster Kubernetes.
  • Como um sistema de IC, o GitLab CI é usado.
  • A implantação (a infraestrutura na qual o código é implantado) é descrita pelos gráficos Helm.
  • Crie imagens e implante no Kubernetes usando o werf .

Por simplicidade e conveniência (e como uma homenagem à moda), continuaremos chamando esses microsserviços de aplicativos. Todos esses microsserviços são montados, implementados e lançados da mesma maneira , e configurações específicas são definidas usando variáveis ​​de ambiente.

Claramente, copiar .gitlab-ci.yml , werf.yaml e .helm traz muitos problemas. Afinal, qualquer edição no IC, o processo de montagem ou a descrição do Helm-chart devem ser adicionados a outros repositórios ...

Conectando modelos em .gitlab-ci.yml


Com o advento da diretiva include:file no GitLab CE ( desde a versão 11.7 ), tornou-se possível criar um IC comum. include próprio include apareceu um pouco antes (na 11.4), mas permitiu conectar modelos apenas a partir de URLs públicas , o que limitou um pouco sua funcionalidade. A documentação do GitLab descreve perfeitamente todos os recursos e exemplos de uso.

Assim, foi possível se recusar a copiar .gitlab-ci.yml entre repositórios e dar suporte à sua relevância. Aqui está um exemplo .gitlab-ci.yml com include :

 include: - project: 'infra/gitlab-ci' ref: 1.0.0 file: base-gitlab-ci.yaml - project: 'infra/gitlab-ci' ref: 1.0.0 file: cleanup.yaml 

É altamente recomendável que você use nomes de filiais em ref com cuidado . As inclusões são calculadas no momento em que o pipeline foi criado, para que as alterações no IC possam cair automaticamente no pipeline de produção no momento mais inoportuno. Mas o uso de tags em ref facilita a versão da descrição dos processos de CI / CD. Ao atualizar, tudo parece o mais transparente possível e você pode acompanhar facilmente o histórico de alterações nas versões de pipeline se usar o controle de versão semântico para tags.

Conecte .helm a partir de um repositório separado


Como esses microsserviços são implantados e executados da mesma maneira, é necessário o mesmo conjunto de modelos do Helm. Para evitar a cópia do diretório .helm entre repositórios, .helm o repositório no qual os modelos do Helm foram armazenados e verificados na tag desejada. Parecia algo assim:

  - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/infra/helm.git .helm - cd .helm && git checkout tags/1.0.0 - type multiwerf && source <(multiwerf use 1.0 beta) - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose) - werf deploy --stages-storage :local 

Também houve variações usando os submódulos git, mas tudo parece mais uma solução alternativa ...

E agora, com o recente lançamento do werf, ele tem a oportunidade de conectar gráficos de repositórios externos. O suporte total para as funções do gerenciador de pacotes, por sua vez, tornou possível descrever de forma transparente as dependências para a implantação do aplicativo.

Sequência de ações


Vamos voltar a resolver nosso problema com microsserviços. Vamos aumentar nosso repositório para armazenar gráficos Helm - por exemplo, ChartMuseum . Ele é implantado facilmente em um cluster Kubernetes:

 helm repo add stable https://kubernetes-charts.storage.googleapis.com helm install stable/chartmuseum --name flant-chartmuseum 

Adicionar entrada:

 apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/force-ssl-redirect: "false" nginx.ingress.kubernetes.io/proxy-body-size: 10m nginx.ingress.kubernetes.io/ssl-redirect: "false" name: chart-museum spec: rules: - host: flant-chartmuseum.example.net http: paths: - backend: serviceName: flant-chartmuseum servicePort: 8080 path: / status: loadBalancer: {} 

A implantação flant-chartmuseum precisa alterar a variável de ambiente DISABLE_API para false . Caso contrário (por padrão), as solicitações da API do ChartMuseum não funcionarão e não será possível criar novos gráficos.

Agora, descrevemos o repositório no qual os gráficos Helm compartilhados serão armazenados. A estrutura de seus diretórios é a seguinte:

 . ├── charts │ └── yii2-microservice │ ├── Chart.yaml │ └── templates │ ├── app.yaml └── README.md 

Chart.yaml pode ficar assim:

 name: yii2-microservice version: 1.0.4 

O diretório de templates deve conter todas as primitivas necessárias do Kubernetes necessárias para implantar o aplicativo no cluster. Como você já deve ter adivinhado, neste caso, o microsserviço é um aplicativo PHP baseado na estrutura yii2. Vamos descrever sua implantação mínima com dois contêineres nginx e php-fpm que são criados usando o werf:

 --- apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Values.global.werf.name }} spec: replicas: 1 revisionHistoryLimit: 3 template: metadata: labels: service: {{ .Values.global.werf.name }} spec: imagePullSecrets: - name: registrysecret containers: - name: backend {{ tuple "backend" . | include "werf_container_image" | indent 8 }} command: [ '/usr/sbin/php-fpm7', "-F" ] ports: - containerPort: 9000 protocol: TCP name: http env: {{ tuple "backend" . | include "werf_container_env" | indent 8 }} - name: frontend command: ['/usr/sbin/nginx'] {{ tuple "frontend" . | include "werf_container_image" | indent 8 }} ports: - containerPort: 80 name: http lifecycle: preStop: exec: command: ["/usr/sbin/nginx", "-s", "quit"] env: {{ tuple "frontend" . | include "werf_container_env" | indent 8 }} --- apiVersion: v1 kind: Service metadata: name: {{ .Values.global.werf.name }} spec: selector: service: {{ .Values.global.werf.name }} ports: - name: http port: 80 protocol: TCP 

A variável .Values.global.werf.name contém o nome do projeto no arquivo werf.yaml , que permite obter os nomes necessários de serviços e Implantações.

Vamos fazer a automação mais simples para enviar push no ChartMuseum de nossos gráficos ao confirmar na ramificação mestre. Para fazer isso, descrevemos .gitlab-ci.yml :

 Build and push to chartmuseum: script: - for i in $(ls charts); do helm package "charts/$i"; done; - for i in $(find . -type f -name "*.tgz" -printf "%f\n"); do curl --data-binary "@$i" http://flant-chartmuseum.example.net/api/charts; done; stage: build environment: name: infra only: - master tags: - my-shell-runner-tag 

Os gráficos são versionados alterando a version no Chart.yaml . Todos os novos gráficos serão adicionados automaticamente ao ChartMuseum.

Vamos para a linha de chegada! No repositório do projeto em .helm/requirements.yaml escrevemos as dependências para o gráfico:

 dependencies: - name: yii2-microservice version: "1.0.4" repository: "@flant" 

... e execute no diretório com o repositório:

 werf helm repo init werf helm repo add flant http://flant-chartmuseum.example.net werf helm dependency update 

Entramos nele .helm/requirements.lock . Agora, para implantar o aplicativo no cluster, basta executar o werf helm dependency build do werf helm dependency build antes de executar o werf deploy .

Para atualizar a descrição da implementação do aplicativo, agora você precisa percorrer os repositórios com microsserviços e aplicar pequenos patches com alterações nos hashes e tags em requirements.yaml e requirements.lock . Se desejar, essa operação também pode ser automatizada por meio do IC: já descrevemos como fazer isso no artigo mencionado .

Conclusão


Espero que a sequência descrita de ações para atender a aplicativos semelhantes seja útil para engenheiros que enfrentam problemas semelhantes. E teremos o maior prazer em compartilhar outras receitas práticas para usar o werf . Portanto, se você tiver dificuldades que parecem intransponíveis ou simplesmente incompreensíveis de implementar, sinta-se à vontade para entrar em contato com o Telegram ou deixar solicitações de materiais futuros aqui nos comentários.

PS


Leia também em nosso blog:

Source: https://habr.com/ru/post/pt469541/


All Articles