Organizar arquivos de configuração em uma fonte de verdade

Nesta página, explicamos como organizar configurações em uma fonte de verdade.

À medida que sua organização cresce, é provável que você precise gerenciar configurações em uma frota de clusters e oferecer suporte a várias equipes que trabalham nos mesmos repositórios. Uma parte fundamental de uma estratégia GitOps bem-sucedida é garantir que as configurações sejam aplicadas aos clusters corretos e que as equipes possam trabalhar sem interferir umas nas outras.

Sobre arquivos de configuração

O Config Sync foi projetado para operadores de cluster que gerenciam muitos clusters. É possível garantir que os clusters atendam aos padrões de negócios e conformidade permitindo que o Config Sync gerencie namespaces, papéis, RoleBindings, ResourceQuotas e outros objetos importantes do Kubernetes na sua frota.

Quando o Config Sync gerencia esses recursos, ele mantém seus clusters registrados em sincronia usando configs. Uma configuração é um arquivo YAML ou JSON em uma fonte de verdade. O Config Sync é compatível com repositórios Git, imagens OCI e gráficos Helm como fontes de verdade. As configurações contêm o mesmo tipo de detalhes de configuração que você pode aplicar manualmente a um cluster usando o comando kubectl apply. É possível criar um config para qualquer objeto do Kubernetes que possa existir em um cluster. No entanto, alguns objetos do Kubernetes, como secrets, contêm informações sensíveis que podem ser inadequadas para armazenamento em uma fonte de verdade. Considere com cuidado se quer gerenciar esses tipos de objetos usando o Config Sync.

Requisitos e limitações

  • Alguns recursos do Kubernetes contêm campos imutáveis, como seletores de pod em um objeto de implantação. Não é possível mudar nenhum campo imutável em uma configuração mudando o valor na fonte da verdade. Tentar fazer essa mudança causa um erro KNV2009. Se você precisar mudar um campo imutável, exclua o objeto da sua fonte de verdade, aguarde o Config Sync excluir o objeto do cluster e recrie o objeto na sua fonte de verdade com as atualizações.

  • Se você usar submódulos do Git, será necessário conceder acesso do Config Sync a todos os repositórios, incluindo submódulos.

  • Não é possível usar o Config Sync para gerenciar diretamente ClusterRoles integrados do Kubernetes. O GKE vem com alguns papéis voltados ao usuário integrados, como cluster-admin, admin, edit e view. Não é possível gerenciar diretamente esses ClusterRoles com o Config Sync. Caso contrário, o Config Sync entra em conflito com o GKE. Para adicionar permissões aos ClusterRoles integrados, use a agregação de papéis para modificá-los indiretamente. Para modificar as funções, crie um ClusterRole com um nome exclusivo na sua fonte da verdade com as anotações adequadas.

Organizar sua fonte da verdade

É possível configurar o Config Sync para sincronizar um repositório inteiro ou pastas ou ramificações específicas. Devido a essa flexibilidade, organize os arquivos de configuração com base nas necessidades da sua equipe ou organização.

Recomendamos que, ao configurar o Config Sync, você defina sourceFormat como unstructured. O tipo de origem estruturada (hierárquica) exige uma estrutura de pastas muito específica para sincronizar corretamente as configurações e adiciona complexidade desnecessária na maioria dos casos.

A maior parte da documentação do Config Sync, incluindo esta página, usa o formato não estruturado por padrão. No entanto, é possível encontrar informações sobre o formato hierárquico, se necessário, em Usar um repositório hierárquico.

Ao usar uma fonte não estruturada, você tem a flexibilidade de organizar suas configurações para se adequar ao fluxo de trabalho da sua equipe. Esta seção apresenta alguns padrões comuns para estruturar seu repositório.

Layout baseado no ambiente

Uma abordagem comum é organizar o repositório por ambiente.

├── cluster-essentials/
│   ├── crds/
│   └── namespace.yaml
├── environments/
│   ├── dev/
│   │   ├── backend/
│   │   └── frontend/
│   ├── staging/
│   │   ├── backend/
│   │   └── frontend/
│   └── prod/
│       ├── backend/
│       └── frontend/
└── system/
    └── monitoring/

Neste exemplo, a fonte de verdade é organizada da seguinte maneira:

  • cluster-essentials/: contém a configuração que se aplica a todos os clusters, independente do ambiente. Isso pode incluir recursos como definições de recursos personalizados (CRDs) e namespaces essenciais.
  • environments/: o diretório principal de todas as configurações específicas do ambiente.
  • system/: contém configurações para serviços no nível do sistema, como monitoramento.

Essa abordagem é fácil de entender e navegar, além de fornecer um caminho de promoção claro para mudanças de um ambiente para outro.

Ao configurar o Config Sync nesse cenário, você cria vários objetos RootSync em cada cluster. Por exemplo, um cluster de desenvolvimento tem objetos RootSync sincronizados de cluster-essentials/, system/ e environments/dev/.

Layout baseado em cluster

Se o foco for gerenciar uma frota de clusters individuais com configurações distintas, um layout baseado em cluster pode ser mais adequado.

├── clusters/
│   ├── cluster-a/
│   │   ├── apps/
│   │   └── networking/
│   ├── cluster-b/
│   │   ├── apps/
│   │   └── networking/
│   └── cluster-c/
│       ├── apps/
│       └── networking/
└── shared/
    ├── roles/
    └── policies/

Neste exemplo, a fonte de verdade é organizada da seguinte maneira:

  • clusters/: contém um diretório para cada cluster que você está gerenciando.
  • shared/: contém configurações comuns a todos os clusters, como papéis do RBAC e políticas de segurança.

Essa abordagem é eficaz para gerenciar muitos clusters se todos eles tiverem configurações exclusivas, já que fornece propriedade e isolamento claros das configurações. Essa abordagem pode ser mais complexa de gerenciar se você tiver muitas configurações de cluster compartilhadas.

Ao configurar o Config Sync nesse cenário, é possível usar um RepoSync para configurar cada cluster para sincronizar de shared e do diretório específico do cluster.

Layout baseado em equipe

Para organizações em que equipes diferentes gerenciam aplicativos ou serviços diferentes, um layout baseado em equipe pode ser eficaz. Essa abordagem alinha a estrutura da fonte da verdade com a estrutura organizacional.

├── teams/
│   ├── team-alpha/
│   │   ├── app-one/
│   │   └── app-two/
│   ├── team-beta/
│   │   ├── service-a/
│   │   └── service-b/
│   └── team-gamma/
│       ├── data-pipeline/
│       └── dashboard/
└── platform/
    ├── cluster-roles/
    └── storage-classes/

Neste exemplo, a fonte da verdade é organizada da seguinte maneira:

  • teams/: organiza a configuração por equipe, e cada uma gerencia as próprias configurações de aplicativo e serviço.
  • platform/: contém configurações em todo o cluster que uma equipe central de plataforma gerencia e que todas as equipes usam.

Essa abordagem permite que as equipes gerenciem os próprios ciclos de configuração e lançamento e reduz a chance de que as mudanças de uma equipe afetem acidentalmente outra. No entanto, essa abordagem exige um gerenciamento cuidadoso das dependências entre as equipes de apps e de plataforma.

Ao configurar o Config Sync para esse cenário, cada equipe usa um objeto RootSync para sincronizar configurações. Por exemplo, team-alpha sincroniza de teams/team-alpha/.

Como validar arquivos de configuração

Depois de criar, organizar e adicionar arquivos de configuração a uma fonte de verdade, use o comando nomos vet --source-format=unstructured para verificar a sintaxe e a validade das suas configurações. Isso ajuda a evitar erros durante ou após uma sincronização.

Ignorar mutações de objeto

Se você não quiser que o Config Sync mantenha o estado do objeto no cluster após ele existir, adicione a anotação client.lifecycle.config.k8s.io/mutation: ignore ao objeto em que o Config Sync deve ignorar as mutações.

O exemplo a seguir mostra como adicionar a anotação a um objeto:

metadata:
  annotations:
    client.lifecycle.config.k8s.io/mutation: ignore 

Não é possível modificar manualmente essa anotação em objetos gerenciados no cluster.

Converter um repositório hierárquico em um repositório não estruturado

Se você usa um repositório hierárquico e quer convertê-lo em um repositório não estruturado, execute o seguinte comando:

nomos hydrate PATH

Substitua PATH pelo caminho para o diretório.

Esse comando cria um diretório compiled/ no diretório de trabalho atual. Nesse diretório, um subdiretório é criado para cada cluster registrado. Esses subdiretórios contêm as configurações totalmente resolvidas e podem ser usados em um repositório não estruturado.

Para mais detalhes, consulte comandos nomos.

Se você preferir converter o repositório manualmente, siga estas instruções:

  1. Remova as configurações Repo do diretório system/ do repositório do Git. O recurso Repo não é necessário para o repositório não estruturado.

  2. O diretório de namespace abstrato não é compatível com o repositório não estruturado. Portanto, declare o namespace de todos os recursos originalmente incluídos no diretório namespaces/ e nos subdiretórios dele.

  3. A herança de namespaces não é compatível com o repositório não estruturado. Portanto, declare todos os recursos herdados originalmente em namespaces descendentes (os que estão originalmente no diretório namespaces/).

A seguir