Sincronizar objetos com vários namespaces

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

Os objetos de recurso do Kubernetes podem ter escopo de cluster ou de namespace, dependendo do tipo de recurso. Para selecionar o cluster, configure seu 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 mais recursos: seletores de cluster e de namespace, que permitem refinar ainda mais os objetos 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 da frota, ele sincroniza todos os objetos Kubernetes na sua fonte de verdade com clusters com o Config Sync instalado ou todos os clusters em uma frota. No entanto, ao definir o escopo de 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 seu 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 recurso idênticos em vários namespaces.

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

Para usar os NamespaceSelectors:

  1. Adicione ou escolha um rótulo nos namespaces que você quer implantar.
  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 corresponde ao metadata.name do 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 conjuntos. É possível combinar vários requisitos.

Exemplo de seletor de rótulos baseado em igualdade

O exemplo a seguir mostra como usar os seletores baseados em igualdade para selecionar 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 referenciar esse seletor de namespace, ela só poderá ser aplicada a objetos em namespaces com o rótulo app: gamestore.

  3. Um seletor de namespace não terá efeito até que você o mencione em outra configuração. Crie uma cota de exemplo de objeto que faz 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ótulo baseado em conjunto

O exemplo a seguir mostra como usar seletores baseados em conjunto para isentar namespaces da herança de 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 referenciar esse seletor de namespace, essa configuração 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 mencione em outra configuração. Crie uma cota de exemplo de objeto que faz 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 frotas

Os namespaces de frota criados em Google Cloud têm o rótulo fleet.gke.io/fleet-scope: your-scope automaticamente. 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 para selecionar namespaces da frota.

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

Objetos com escopo de namespace no modo hierárquico

Embora os repositórios não estruturados sejam recomendados para a maioria dos casos de uso, é possível usar os 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 sua fonte de verdade.

Limitações

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

  • É necessário 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.
  • É necessário 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 fazem referência a um NamespaceSelector são aplicados a namespaces que herdam uma determinada configuração de um namespace abstrato, seja qual for a estrutura de diretórios do diretório 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 NamespaceSelectors:

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, você pode 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 nenhuma configuração para namespaces, mas os diretórios de namespaces descendentes contêm configurações.

  2. No diretório de namespace abstrato que você criou, crie uma configuração de um papel que conceda permissões get e list a todos os objetos em 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 do papel.

  3. Crie uma configuração para uma vinculação de função que vincula a função a um grupo de e-mails:

    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