Configurar namespaces e objetos no escopo do namespace

Nesta página, mostramos como usar o Config Sync para gerenciar namespaces e objetos com escopo de namespace.

Configurar um namespace

A configuração de um namespace funciona de maneira diferente para repositórios não estruturados e hierárquicos. Os exemplos a seguir destacam as diferenças.

Repositório não estruturado

As configurações de namespaces e objetos com escopo de namespace podem estar localizadas em qualquer lugar no diretório ou nos subdiretórios do repositório.

Conclua as etapas a seguir para configurar um namespace chamado gamestore em cada cluster registrado:

  1. Crie um arquivo namespace-gamestore.yaml com o seguinte conteúdo.

    apiVersion: v1
    kind: Namespace
    metadata:
      name: gamestore
    

    Você só precisa criar um arquivo YAML que contenha a configuração do namespace.

  2. Crie uma confirmação que inclua o config namespace-gamestore.yaml e a envie ao repositório remoto.

    git add multirepo/root/namespace-gamestore.yaml
    git commit -m "Created gamestore namespace config"
    git push REMOTE_NAME BRANCH_NAME
    

    Substitua:

    • REMOTE_NAME: o nome do repositório remoto.
    • BRANCH_NAME: a ramificação com que você quer se comprometer.

    Este exemplo adiciona o arquivo ao diretório raiz, mas é possível movê-lo para qualquer um dos subdiretórios do repositório.

Repositório hierárquico

Todas as configurações de namespaces e objetos com escopo de namespace estão localizados no diretório namespaces/ do repositório hierárquico e nos respectivos diretórios descendentes.

Siga estas etapas para configurar um namespace chamado gamestore em cada cluster inscrito:

  1. No clone local do seu repositório, crie um diretório de namespace. Um diretório de namespace que contém uma configuração de um namespace. O nome do diretório de namespace precisa ser igual ao do namespace. Neste exemplo, o diretório é chamado namespaces/gamestore:

    mkdir namespaces/gamestore
    
  2. No diretório de namespace, crie um arquivo gamestore.yaml, com o conteúdo a seguir.

    apiVersion: v1
    kind: Namespace
    metadata:
      name: gamestore
    

    O metadata.name precisa corresponder ao nome do diretório de namespace.

  3. Crie uma confirmação que inclua o config gamestore.yaml e a envie ao repositório remoto:

    git add namespaces/gamestore/gamestore.yaml
    git commit -m "Created gamestore namespace config"
    git push REMOTE_NAME BRANCH_NAME
    

    Substitua:

    • REMOTE_NAME: o nome do repositório remoto.
    • BRANCH_NAME: a ramificação com que você quer se comprometer.

Depois de alguns instantes, o namespace gamestore é criado em cada cluster inscrito. Para verificar a criação, descreva o namespace:

kubectl describe namespace gamestore

Para remover a configuração e excluir o namespace gamestore dos clusters registrados, crie uma nova confirmação que remova o arquivo e a envie ao repositório remoto. Não remova a configuração se você quiser configurar um namespace abstrato para um repositório hierárquico.

Configurar um objeto com escopo de namespace

Em repositórios não estruturados, é possível armazenar objetos com escopo de namespace em qualquer diretório ou subdiretório sem exigir uma configuração de namespace. Se um config de namespace estiver ausente, o Config Sync criará automaticamente um objeto de namespace implícito e aplicará todos os configs a esse namespace.

Esse comportamento pode ser modificado usando o campo namespaceStrategy. Se namespaceStrategy estiver definido como explicit, o Config Sync não criará automaticamente um objeto de namespace implícito. Para mais informações, consulte Estratégia de namespace.

Em repositórios hierárquicos, você precisa especificar explicitamente uma configuração de namespace no subdiretório namespaces/NAMESPACE, em que NAMESPACE precisa corresponder ao nome do namespace. Todos os outros configs com escopo de namespace também precisam ser armazenados no mesmo subdiretório. Se um config de namespace estiver ausente, o Config Sync retornará um erro KNV1044, indicando um config de namespace ausente.

Configurar um namespace abstrato

Esta seção se aplica somente a repositórios hierárquicos, porque namespaces abstratos não são compatíveis com repositórios não estruturados.

Este exemplo amplia as informações fornecidas na seção Como configurar um namespace. Isso é feito ao mover o diretório de namespace gamestore para um namespace abstrato que contém mais configs herdados pelo gamestore.

  1. No clone local do repo, crie um diretório de namespace abstrato chamado eng:

    mkdir namespaces/eng
    

    O diretório de namespace abstrato não contém um config de um namespace, mas sim os respectivos diretórios de namespace descendente.

  2. No diretório de namespace abstrato eng, crie um config de um papel chamado eng-viewer. Ele concede get e list a todos os recursos em qualquer namespace que herdar esse papel:

    # namespaces/eng/eng-role.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: eng-viewer
    rules:
    - apiGroups: [""]
      resources: ["*"]
      verbs: ["get", "list"]
    
  3. Crie um config de um RoleBinding chamado eng-admin. Ele vincula o papel eng-viewer ao grupo eng@example.com:

    # namespaces/eng/eng-rolebinding.yaml
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: eng-admin
    subjects:
    - kind: Group
      name: eng@example.com
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: eng-viewer
      apiGroup: rbac.authorization.k8s.io
    
  4. Mova o diretório de namespace gamestore de namespaces/ para namespaces/eng/:

    mv namespaces/gamestore /namespaces/eng/
    
  5. Confirme todas as alterações e as envie ao repositório remoto.

O Config Sync reconhece a alteração e aplica o novo papel e o RoleBinding ao namespace gamestore em todos os clusters inscritos.

Para remover os configs e excluir o namespace gamestore dos clusters inscritos, crie uma nova confirmação que remova todo o namespace abstrato eng e envie ao repositório remoto.

Como limitar quais clusters um config afeta

Normalmente, o Config Sync aplica um config a cada cluster inscrito. Se a configuração estiver dentro do subdiretório namespaces/ de um repositório hierárquico, o Config Sync criará primeiro o namespace em cada cluster. Depois, ele aplicará todos os configurações herdadas a esse namespace. Para limitar os clusters que um determinado config afeta com base nos rótulos de cada cluster, use um ClusterSelector. Para saber mais, consulte Usar ClusterSelectors.

Limitar quais namespaces um config afeta

Para limitar quais namespaces uma configuração afeta, use um NamespaceSelector. Um NamespaceSelector é um tipo especial de config que usa labelSelectors do Kubernetes. É possível declarar NamespaceSelectors junto com os configs de objetos com escopo de namespace em um repositório não estruturado ou um repositório hierárquico para limitar quais os namespaces podem herdar essa configuração. Os NamespaceSelectors são semelhantes, mas não idênticos, aos ClusterSelectors. Um NamespaceSelector restringe o pool de namespaces a que um config se aplica.

Para declarar um NamespaceSelector, adicione a anotação metadata.namespace ou NamespaceSelector. Declarar as duas anotações é inválido. Se os recursos com escopo de namespace não declararem a anotação metadata.namespace ou NamespaceSelector, o Config Sync usará o namespace "padrão" do cluster.

NamespaceSelectors em repositórios não estruturados

Um repositório não estruturado não precisa declarar todos os namespaces dos objetos com escopo de namespace no repositório. Um objeto pode definir um metadata.namespace sem ter um objeto de namespace correspondente em um repositório não estruturado. Se o namespace já existir no cluster, o Config Sync criará o objeto nesse namespace. Se o namespace ainda não existir no cluster, o Config Sync criará o namespace implicitamente.

Antes de criar um repositório não estruturado com objetos que foram usados anteriormente em um repositório hierárquico, verifique se os NamespaceSelectors não se aplicam a outros recursos.

Quando você remove objetos com escopo de namespace de um repositório não estruturado, o Config Sync exclui esses objetos, mas não remove nenhum namespace que possa ter sido criado implicitamente para esses objetos. Esse comportamento acontece porque o Config Sync não pode inferir quando é seguro excluir um namespace que foi criado implicitamente, portanto, ele sempre fica no cluster.

Modo NamespaceSeletor

Em um repositório não estruturado, os objetos que declaram a anotação NamespaceSelector são aplicados a todos os namespaces que atendem às condições de um NamespaceSelector. Nas versões do Config Sync anteriores à 1.17.0, a anotação NamespaceSelector só se aplica a namespaces correspondentes que são declarados estaticamente na fonte da verdade. Na versão 1.17.0 e mais recentes, o objeto NamespaceSelector oferece suporte ao modo dinâmico definindo spec.mode como dynamic. No modo dinâmico, a seleção se estende aos namespaces declarados estaticamente e aos presentes dinamicamente no cluster. Os namespaces escolhidos dinamicamente já existem no cluster e, portanto, não são gerenciados pelo Config Sync. O modo padrão é static.

NamespaceSelectors em repositórios hierárquicos

Em um repositório hierárquico, os objetos que declaram a anotação 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 namespaces/. O ClusterSeletor restringe o pool de clusters a que um config se aplica, seja o destino dele um objeto com escopo de cluster ou de namespace.

Local do NamespaceSelector

Em um repositório não estruturado, é possível colocar os NamespaceSelectors em qualquer diretório ou subdiretório.

Em um repositório hierárquico, é possível colocar NamespaceSelectors 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 se você estiver usando um repositório hierárquico:

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 NamespaceSelector neles.

Exemplos de NamespaceSeletor

É possível usar um NamespaceSelector com seletores de rótulos para incluir ou excluir namespaces. O Kubernetes é compatível com seletores baseados em igualdade e em conjuntos. É possível combinar os dois tipos de seletores para refinar ainda mais quais namespaces serão selecionados.

Seletor de rótulos baseado em igualdade

Com os configs a seguir, você cria um NamespaceSelector chamado gamestore-selector. Se outro config mencionar esse NamespaceSelector, ele só poderá ser aplicado a objetos em namespaces com o rótulo app: gamestore.

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

Para mencionar um NamespaceSelector em um config, defina a anotação configmanagement.gke.io/namespace-selector como o nome do NamespaceSelector.

Um NamespaceSelector não terá efeito até que você o referencie em outro config. Se o NamespaceSeletor gamestore-selector estiver na mesma hierarquia que o ResourceQuota a seguir, quota, o ResourceQuota será criado somente em namespaces que tenham o rótulo app: gamestore:

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

Para resumir, usar um NamespaceSelector é um processo de três etapas:

  1. Adicionar rótulos aos namespaces.
  2. Criar um config NamespaceSelector.
  3. Consultar o objeto NamespaceSelector em outro config.

Seletor de rótulos baseado em definição

Use seletores de namespace para isentar namespaces específicos de herdar um recurso na árvore usando seletores de rótulos baseados em set.

Neste exemplo, quando o ResourceQuota é anotado com NamespaceSelector definindo a anotação configmanagement.gke.io/namespace-selector: excludes-exempt-namespaces, o ResourceQuota é criado em todos os namespaces, exceto nos namespaces rotulados como quota-exempt: exempt:

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

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

Os namespaces da frota criados no Google Cloud têm automaticamente o rótulo fleet.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 o NamespaceSelector e selecionar namespaces da frota.

Desativar herança para um tipo de objeto

Os objetos do Kubernetes HierarchyConfig não são compatíveis com repositórios não estruturados. O exemplo a seguir se aplica apenas aos repositórios hierárquicos.

É possível desativar seletivamente a herança dos configs. Basta definir o campo hierarchyMode como none. Os HierarchyConfigs são armazenados no diretório system/ do repositório. Este exemplo desativa a herança para o RoleBindings.

# 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

A seguir