Sincronizar objetos com vários namespaces

Nesta página, explicamos como usar o Config Sync para gerenciar namespaces e escolher quais objetos o Config Sync sincroniza com seus namespaces.

Os objetos de recursos do Kubernetes podem ter escopo de cluster ou de namespace, dependendo do tipo de recurso. Para selecionar o cluster, configure o cliente para se comunicar com um cluster específico. Para selecionar o namespace, configure o campo metadata.namespace no manifesto do objeto. O Config Sync adiciona outros recursos: seletores de cluster e de namespace, que permitem refinar ainda mais quais objetos são sincronizados.

Antes de ler esta página, você precisa conhecer os seguintes conceitos do Kubernetes:

Sobre o escopo de objetos com o Config Sync

Por padrão, quando você instala o Config Sync em um cluster ou como padrão de uma frota, o Config Sync sincroniza todos os objetos do Kubernetes na sua fonte de verdade com os clusters em que o Config Sync está instalado ou com todos os clusters de uma frota. No entanto, ao definir o escopo dos objetos para um cluster ou namespace, é possível controlar quais objetos são sincronizados com um cluster ou namespace.

O Config Sync oferece os seguintes métodos para definir o escopo dos objetos:

Usar namespaces explícitos

Recomendamos que você use a declaração explícita de namespace ao configurar o Config Sync porque ela permite gerenciar metadados de namespace e excluir namespaces mais tarde, se necessário.

A configuração padrão é implicit, mas você pode mudar a estratégia de namespace no objeto RootSync ou RepoSync definindo o campo namespaceStrategy como explicit. Para mais informações, consulte estratégia de namespace.

Sobre os seletores de namespace

Os seletores de namespace são um recurso do Config Sync que permite implantar objetos de recursos idênticos em vários namespaces.

Usar seletores de namespace é semelhante a usar seletores de rótulo do Kubernetes para mapear um serviço a um conjunto de pods, mas com uma camada extra de indireção. Como não é possível adicionar campos personalizados a tipos de recursos atuais, defina o seletor em um objeto NamespaceSelector. Em seguida, faça referência a esse seletor por nome em uma anotação nos objetos que você quer usar.

Para usar seletores de namespace:

  1. Adicione ou escolha um rótulo nos namespaces em que você quer fazer a implantação.
  2. Defina um objeto de recurso NamespaceSelector na sua fonte da verdade. O Config Sync não sincroniza objetos NamespaceSelector com o cluster.
  3. Para cada objeto que você quer sincronizar com um ou mais namespaces, modifique a configuração do objeto para remover o campo metadata.namespace e adicione a anotação configmanagement.gke.io/namespace-selector com um valor que corresponda ao metadata.name do seu NamespaceSelector.

Os exemplos na seção a seguir fornecem mais detalhes sobre como definir objetos NamespaceSelector e anotar outros objetos para usar o NamespaceSelector.

Antes de começar

Usar seletores de namespace

Os seletores de namespace são definidos com requisitos baseados em igualdade ou requisitos baseados em conjunto. É possível combinar vários requisitos.

Exemplo de seletor de rótulo baseado em igualdade

O exemplo a seguir mostra como usar seletores baseados em igualdade para escolher a quais namespaces uma configuração se aplica:

  1. Adicione um rótulo a um ou mais namespaces:

    kubectl label namespace NAMESPACE app=gamestore
    

    Substitua NAMESPACE pelo nome do namespace.

    Execute esse comando para cada namespace que você quer rotular.

  2. Crie um seletor de namespace chamado gamestore-selector.

    kind: NamespaceSelector
    apiVersion: configmanagement.gke.io/v1
    metadata:
      name: gamestore-selector
    spec:
      selector:
        matchLabels:
          app: gamestore
    

    Se a configuração de outro objeto fizer referência a esse seletor de namespace, ela só poderá ser aplicada a objetos em namespaces que tenham o rótulo app: gamestore.

  3. Um seletor de namespace não terá efeito até que você o referencie em outra configuração. Crie uma cota de objeto de exemplo que faça referência ao seletor de namespace:

    kind: ResourceQuota
    apiVersion: v1
    metadata:
      name: quota
      annotations:
        configmanagement.gke.io/namespace-selector: gamestore-selector
    spec:
      hard:
        pods: "1"
        cpu: "200m"
        memory: "200Mi"
    

    A cota de recursos é criada apenas em namespaces com o rótulo app: gamestore.

Exemplo de seletor de rótulos baseado em conjunto

O exemplo a seguir mostra como usar seletores baseados em conjuntos para isentar namespaces de herdar objetos:

  1. Adicione um rótulo a um ou mais namespaces:

    kubectl label namespace NAMESPACE quota-exempt=exempt
    

    Substitua NAMESPACE pelo nome do namespace.

    Execute esse comando para cada namespace que você quer rotular.

  2. Crie um seletor de namespace chamado exclude-exempt-namespaces:

    kind: NamespaceSelector
    apiVersion: configmanagement.gke.io/v1
    metadata:
      name: excludes-exempt-namespaces
    spec:
      selector:
        matchExpressions:
          - key: quota-exempt
            operator: NotIn
              values:
                - exempt
    

    Se a configuração de outro objeto fizer referência a esse seletor de namespace, ela será aplicada a todos os namespaces, exceto aqueles com o par de chave-valor quota-exempt: exempt.

  3. Um seletor de namespace não terá efeito até que você o referencie em outra configuração. Crie uma cota de objeto de exemplo que faça referência ao seletor de namespace:

    kind: ResourceQuota
    apiVersion: v1
    metadata:
      name: quota
      annotations:
        configmanagement.gke.io/namespace-selector: exclude-exempt-namespaces
    spec:
      hard:
        pods: "1"
        cpu: "200m"
        memory: "200Mi"
    

    A cota de recursos é criada em todos os namespaces, exceto aqueles que têm o par de chave-valor quota-exempt: exempt.

Integração com escopos de equipe e namespaces de frota

Os namespaces da frota criados em Google Cloud recebem automaticamente o rótulofleet.gke.io/fleet-scope: your-scope. Todos os namespaces também têm o rótulo kubernetes.io/metadata.name: your-namespace do Kubernetes. É possível usar esses rótulos padrão para configurar um seletor de namespace e selecionar namespaces da frota.

O tutorial de locação de frota explica em mais detalhes como usar seletores de namespace com frotas e escopos de equipe para gerenciar objetos de maneira seletiva para diferentes equipes.

Objetos com escopo no namespace com modo hierárquico

Embora os repositórios não estruturados sejam recomendados para a maioria dos casos de uso, é possível usar seletores de namespace para definir o escopo dos objetos com um repositório hierárquico. O uso de seletores de namespace é o mesmo, mas há outras limitações e requisitos para organizar a configuração de namespace na fonte da verdade.

Limitações

Ao usar uma configuração de seletor de namespace com um repositório hierárquico, fique atento às seguintes limitações e requisitos:

  • É preciso armazenar todos os arquivos de configuração de namespaces e objetos com escopo de namespace no diretório namespaces/ do repositório hierárquico e nos respectivos diretórios descendentes.
  • Você precisa especificar explicitamente uma configuração de namespace no subdiretório namespaces/NAMESPACE, em que NAMESPACE corresponde ao nome do namespace. Todos os outros objetos com escopo de namespace precisam ser armazenados no mesmo subdiretório. Se uma configuração de namespace estiver ausente, o Config Sync vai retornar um erro KNV1044.
  • Os recursos que referenciam um seletor de namespace são aplicados a namespaces que herdam uma determinada configuração de um namespace abstrato, seja qual for a estrutura de diretórios de namespaces/.

Local do seletor de namespace

Em um repositório hierárquico, é possível colocar uma configuração de seletor de namespace em qualquer diretório de namespace abstrato, mas não em um diretório de namespace.

O exemplo de arquitetura de repositório a seguir mostra locais válidos e inválidos para seletores de namespace:

namespace-inheritance
...
├── namespaces
│   ├── eng
│   │   ├── gamestore
│   │   │   ├── namespace.yaml
│   │   │   └── ns_selector.yaml  # invalid
│   │   └── ns_selector.yaml  # valid
│   ├── ns_selector.yaml  # valid
│   ├── rnd
│   │   ├── incubator-1
│   │   │   ├── namespace.yaml
│   │   │   └── ns_selector.yaml  # invalid
│   │   └── ns_selector.yaml  # valid

Como os diretórios namespaces, eng e rnd representam namespaces abstratos, é possível colocar um seletor neles. No entanto, como os diretórios gamestore e incubator-1 representam namespaces reais, não é possível colocar um seletor de namespace neles.

Configurar um namespace abstrato

Com um repositório hierárquico, é possível usar namespaces abstratos.

O exemplo a seguir mostra como mover o diretório de namespace para um namespace abstrato que contém outras configurações herdadas pelo namespace:

  1. No repositório, crie um diretório de namespace abstrato. O diretório de namespace abstrato não contém configurações de namespaces, mas os diretórios de namespace descendentes contêm.

  2. No diretório de namespace abstrato que você criou, crie uma configuração para um papel que conceda permissões get e list em todos os objetos de qualquer namespace que herdar esse papel:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: ROLE_NAME
    rules:
    - apiGroups: [""]
      resources: ["*"]
      verbs: ["get", "list"]
    

    Substitua ROLE_NAME pelo nome da função.

  3. Crie uma configuração para uma vinculação de papel que vincule o papel a um grupo de e-mail:

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: ROLE_NAME
    subjects:
    - kind: Group
      name: group@example.com
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name:  ROLEBINDING_NAME
      apiGroup: rbac.authorization.k8s.io
    

    Substitua ROLEBINDING_NAME pelo nome da função.

  4. Mova a configuração de namespace que você criou na seção anterior do diretório namespaces/ para o diretório de namespace abstrato criado nesta seção.

Desativar a herança para objetos

É possível desativar seletivamente a herança de qualquer configuração definindo o campo hierarchyMode como none. Os HierarchyConfigs são armazenados no diretório system/ do repositório. Este exemplo desativa a herança para vinculações de função:

# system/hierarchy-config.yaml
kind: HierarchyConfig
apiVersion: configmanagement.gke.io/v1
metadata:
  name: rbac
spec:
  resources:
  # Configure role to only be allowed in leaf namespaces.
  - group: rbac.authorization.k8s.io
    kinds: [ "RoleBinding" ]
    hierarchyMode: none