Cloud Computing

27 mai, 2026

Como criamos serviços em contêineres no GitHub usando o GitHub

Publicidade

A equipe de engenharia de experiência do desenvolvedor do GitHub trabalha para criar soluções seguras, agradáveis ​​e inclusivas para que os engenheiros do GitHub possam codificar, distribuir e operar software com eficiência, servindo de exemplo para o mundo sobre como construir software com o GitHub. Para isso, oferecemos aos nossos desenvolvedores um caminho facilitado — um conjunto abrangente de ferramentas e aplicativos automatizados para otimizar nossas plataformas de tempo de execução, implantação e hospedagem, que ajuda a impulsionar alguns dos microsserviços na plataforma GitHub.com e muitas ferramentas internas. Vamos analisar mais detalhadamente como funciona um dos nossos principais caminhos facilitados.

Nosso ecossistema de desenvolvimento

O principal caminho pavimentado do GitHub abrange tudo o que é necessário para executar software: criar, implantar, escalar, depurar e executar aplicativos. É um ecossistema de ferramentas como Kubernetes, Docker, balanceadores de carga e muitos aplicativos personalizados que trabalham juntos para criar uma experiência coesa para nossos engenheiros. Não se trata apenas de infraestrutura e não se trata apenas de Kubernetes. O Kubernetes é nossa camada base, e o caminho pavimentado é uma combinação de convenções, ferramentas e configurações construídas sobre ele.

Os tipos de serviços que normalmente executamos usando o caminho pavimentado incluem aplicativos da web, pipelines de computação, processadores em lote e sistemas de monitoramento.

O Kubernetes, que é a camada base do caminho pavimentado, é executado em uma topologia multi-cluster e multi-região.

Benefícios do caminho pavimentado

Existem centenas de serviços no GitHub — desde uma pequena ferramenta interna até uma API externa que suporta cargas de trabalho de produção. Por diversos motivos, seria ineficiente criar máquinas virtuais para cada serviço.

  • O planejamento e a utilização da capacidade em todos os serviços não seriam eficientes. Encontraríamos custos adicionais significativos na gestão contínua da infraestrutura física e do Kubernetes.
  • As equipes precisariam desenvolver profundo conhecimento na gestão de seus próprios clusters Kubernetes e teriam menos tempo para se concentrar nas necessidades específicas de seus aplicativos.
  • Teríamos menos visibilidade centralizada das aplicações.
  • Seria difícil padronizar e impor segurança e conformidade.

Com o caminho pavimentado baseado em Kubernetes e outros aplicativos de tempo de execução, somos capazes de:

  • Planeje a capacidade de forma centralizada e somente para os nós do Kubernetes, para que possamos usar a capacidade de maneira otimizada entre os nós, já que cargas de trabalho pequenas e grandes coexistem nas mesmas máquinas.
  • Aumente a escala rapidamente graças ao planejamento centralizado de capacidade.
  • Gerencie facilmente a configuração e as implantações em todos os serviços a partir de um plano de controle central.
  • Fornecer consistentemente informações sobre o desempenho de aplicativos e implantações para serviços individuais.

Integração de um serviço

A integração de um serviço com o código em seu próprio repositório tornou-se fácil com nosso serviço de comandos ChatOps, chamado Hubot , e o GitHub Apps. Os proprietários do serviço podem gerar facilmente a estrutura básica necessária para implantá-lo executando um comando como:

código.sh·concha

hubot gh-platform app scaffold monalisa-app

Um aplicativo GitHub personalizado instalado no repositório GitHub do serviço irá gerar automaticamente uma solicitação de pull para adicionar as configurações necessárias, incluindo:

  • Um deployment.yamlarquivo que define os ambientes de implantação do serviço.
  • Manifestos do Kubernetes que definem Deploymentos Serviceobjetos para a implantação do serviço.
  • Um Dockerfile Debian que executa um servidor web simples para começar, o qual será usado pelos manifestos do Kubernetes.
  • Configurar builds de CI como verificações do GitHub que criam as imagens Docker a cada push e as armazenam em um registro de contêineres, prontas para implantação.

Cada serviço integrado ao caminho pavimentado possui seu próprio namespace Kubernetes, definido por <app-name>-<environment>um ambiente de teste (staging) e um ambiente de produção (produce). Isso ajuda a separar as cargas de trabalho de múltiplos serviços, bem como múltiplos ambientes para o mesmo serviço, já que cada ambiente recebe seu próprio namespace Kubernetes.

Implantação de um serviço

No GitHub, implantamos branches e realizamos implantações por meio de comandos do Hubot ChatOps. Para implantar uma branch com o nome especificado bug-fixesno monalisa-apprepositório no stagingambiente, um desenvolvedor executaria um comando do ChatOps como:

código.sh·concha

hubot deploy monalisa-app/bug-fixes to staging

Isso aciona uma implantação que busca a imagem Docker associada ao commit mais recente no bug-fixesbranch, atualiza os manifestos do Kubernetes e aplica esses manifestos aos clusters na plataforma de tempo de execução relevante para esse ambiente.

Normalmente, a imagem Docker seria implantada em vários clusters Kubernetes em diversos locais geográficos dentro de uma região que faz parte da plataforma de execução.

Para automatizar a fusão de pull requests nos branches mais movimentados e orquestrar a implementação em todos os ambientes, também estamos usando filas de merge e pipelines de implantação , que nossos engenheiros podem observar e com os quais podem interagir durante a implantação.

Garantindo a segurança dos nossos serviços

Para qualquer empresa, a segurança da própria plataforma, juntamente com os serviços executados nela, é fundamental. Além de nossas práticas de engenharia, como exigir revisões por duas pessoas em cada solicitação de pull request, também contamos com equipes de Segurança e Plataforma que automatizam medidas de segurança, como:

  • Imagens Docker pré-construídas para serem usadas como imagens base para os Dockerfiles. Essas imagens base contêm apenas os pacotes/dependências necessários com atualizações de segurança, um conjunto de softwares instalados que é auditável e selecionado de acordo com as necessidades compartilhadas.
  • Análises periódicas e em tempo de compilação de todos os pacotes e imagens de contêineres em execução, em busca de vulnerabilidades ou dependências que necessitem de correção, são realizadas por meio de nossos próprios produtos de segurança da cadeia de suprimentos de software, como o Dependabot.
  • Compilação e varredura periódica de repositórios de serviços do GitHub em busca de segredos expostos e vulnerabilidades, utilizando os recursos de segurança nativos do GitHub para segurança avançada, como varredura de código e varredura de segredos .
  • Múltiplos mecanismos de autenticação e autorização que permitem que apenas os indivíduos relevantes acessem diretamente os recursos subjacentes do Kubernetes.
  • Telemetria abrangente para detecção de ameaças.
  • Os serviços executados na plataforma são acessíveis por padrão apenas dentro das redes internas do GitHub e não são expostos na internet pública.
  • As políticas de proteção de branches são aplicadas em todos os repositórios de produção. Essas políticas impedem a fusão de um pull request até que os testes automatizados designados sejam aprovados e a alteração tenha sido revisada por um desenvolvedor diferente daquele que a propôs.

Outro aspecto fundamental da segurança de uma aplicação é a forma como segredos, como chaves e tokens, são gerenciados. No GitHub, utilizamos um repositório de segredos centralizado para gerenciá-los. Cada serviço e cada ambiente dentro do serviço possui seu próprio cofre para armazenar segredos. Esses segredos são então injetados nos pods relevantes no Kubernetes, que, por sua vez, são expostos aos contêineres.

O fluxo de implantação, da fusão à implementação.

Todo o processo de implantação seria mais ou menos assim:

Diagrama do fluxo de implantação, da fusão à implementação.
  1. Um engenheiro do GitHub mescla uma solicitação de pull request em uma branch de um repositório. No exemplo acima, trata-se da bug-fixesbranch `master` do monalisa-apprepositório. Esse repositório também conteria os arquivos de modelo de manifesto do Kubernetes para a implantação da aplicação.
  2. A fusão do pull request aciona fluxos de trabalho de CI relevantes. Um deles é a criação da imagem Docker, que constrói a imagem do contêiner com base no Dockerfile especificado no repositório e envia a imagem para um registro de artefatos interno.
  3. Assim que todos os fluxos de trabalho de CI forem concluídos com sucesso, o engenheiro inicia uma implantação executando um comando ChatOps como hubot deploy monalisa-app/bug-fixes to staging. Isso aciona uma implantação em nossos ambientes, como Staging.
  4. Os sistemas de compilação obtêm os arquivos de manifesto do Kubernetes do branch do repositório, substituem a imagem mais recente a ser implantada a partir do registro de artefatos, injetam segredos do aplicativo a partir do armazenamento de segredos e executam algumas operações personalizadas. Ao final desta etapa, um manifesto do Kubernetes pronto para implantação está disponível.
  5. Nossos sistemas de implantação aplicam o manifesto do Kubernetes aos clusters relevantes e monitoram o status de implementação das novas alterações.

Conclusão

O caminho interno facilitado do GitHub ajuda os desenvolvedores a se concentrarem na criação de serviços e na entrega de valor aos nossos usuários, com foco mínimo na infraestrutura. Conseguimos isso fornecendo um caminho simplificado para nossos engenheiros do GitHub que utiliza o poder dos contêineres e do Kubernetes; mecanismos escaláveis ​​de segurança, autenticação e autorização; e a própria plataforma GitHub.com.

Quer experimentar algumas dessas dicas? Saiba mais sobre todos os recursos do GitHub em github.com/features . Se você adotou alguma de nossas práticas para o seu próprio desenvolvimento, conte para a gente no Twitter !