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 namespace abstrato

Esta seção só se aplica a repositórios hierárquicos. Os namespaces abstratos não são compatíveis em repositórios não estruturados. Se você estiver usando um repositório não estruturado e quiser uma funcionalidade semelhante, use namespaces hierárquicos.

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 Management Operator 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 Configurar um subconjunto de clusters.

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.

Em um repositório não estruturado, os objetos que declaram a anotação NamespaceSelector são aplicados a todos os namespaces que satisfazem as condições NamespaceSelector. Antes de criar um repositório não estruturado com objetos que foram usados anteriormente em um repositório hierárquico, verifique se o NamespaceSelectors não se aplica a recursos adicionais.

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.

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 um determinado config de um namespace abstrato, seja qual for a estrutura de diretórios de namespaces/. O ClusterSelector restringe o pool de clusters a que um config é aplicado, 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.

Exemplo de NamespaceSelector

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 NamespaceSelector gamestore-selector estiver na mesma hierarquia que o ResourceQuota quota a seguir, o ResourceQuota será criado somente nos namespaces que tiverem 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.

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