Herança de namespace e namespaces abstratos

Nesta página, descrevemos como usar o conceito de herança de namespace em um repositório hierárquico do Config Sync.

Com base na estrutura do repositório, o Config Sync pode aplicar automaticamente configurações a grupos de namespaces em todos os clusters em que esses namespaces existem (ou deveriam existir). Esses grupos de namespaces são chamados de namespaces abstratos.

A herança de namespace e os namespaces abstratos não são compatíveis com repositórios não estruturados. Se você estiver usando um repositório não estruturado e quiser uma funcionalidade semelhante, use o Hierarchy Controller.

Como funciona a herança de namespaces

A herança de namespace se aplica ao diretório namespaces/ do repositório hierárquico e a todos os subdiretórios dele. As configurações em outros diretórios no repositório, como cluster/, não estão sujeitas à herança.

Em um repositório hierárquico, o diretório namespaces/ pode conter dois tipos diferentes de subdiretórios:

  • Um diretório de namespace contém uma configuração de um namespace. O nome do arquivo que contém a configuração não é importante, mas essa configuração precisa conter kind: Namespace. Um diretório de namespace também pode conter configs para outros tipos de objetos do Kubernetes. Um diretório de namespace não pode conter subdiretórios. Uma configuração de namespace representa um namespace real em um cluster.

  • Um diretório de namespace abstrato que contém diretórios de namespace. Ele também pode conter configurações para outros objetos do Kubernetes, mas não pode conter diretamente uma configuração para um namespace. Um diretório de namespace abstrato não representa um objeto em um cluster do Kubernetes. Já os diretórios de namespace descendente, sim.

Para ajudar a garantir que o namespace e os repositórios de namespaces abstratos tenham o tipo correto de configurações e estrutura, informe o erro KNV1003: IllegalNamespaceSubdirectoryError quando houver um problema.

As configurações em um diretório de namespace aplicam-se apenas a esse namespace. Já as configurações em um diretório de namespace abstrato são aplicadas a todos os diretórios de namespaces descendentes do namespace abstrato ou aos descendentes que correspondem ao NamespaceSelector da configuração, se houver.

Exemplo de herança de namespaces

A herança de uma configuração no diretório namespaces/ é baseada em grande parte na localização dela na árvore de diretórios do repositório. Para entender quais configurações estão sendo aplicadas a um determinado namespace em um determinado cluster, procure o repositório de exemplos de herança de namespace.

O diretório namespaces/ no repositório de exemplo de herança de namespace tem a seguinte arquitetura:

├── namespaces # Abstract namespace directory
│   ├── eng # Abstract namespace directory
│   │   ├── analytics # Namespace directory
│   │   └── gamestore # Namespace directory
│   ├── rnd # Abstract namespace directory
│   │   ├── incubator-1 # Namespace directory
│   │   └── incubator-2 # Namespace directory
|   |── network-policy-default-deny-all.yaml
|   |── viewers-rolebinding.yaml

Para entender mais sobre como este repositório de exemplo funciona, primeiro conheça viewers-rolebinding.yaml:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: viewers
subjects:
- kind: Group
  name: system:serviceaccounts:foo
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io

Como esse RoleBinding está na raiz do diretório namespaces/, ele concede a todos os usuários do grupo system:serviceaccounts:foo o ClusterRole view em todos os namespaces gerenciados pelo Config Sync.

Depois, abra o diretório namespaces/eng/ no navegador. O eng é um diretório de namespace abstrato porque não tem uma configuração de um namespace. O diretório eng contém as seguintes configs:

  • eng-role.yaml
  • eng-rolebinding.yaml
  • network-policy-allow-gamestore-ingress.yaml
  • quota.yaml
  • selectors.yaml

O diretório eng também tem dois subdiretórios: analytics e gamestore. Esses subdiretórios são diretórios de namespace porque cada um contém uma configuração de um namespace. Neste exemplo, as configurações de namespace são chamadas de namespace.yaml, mas é possível chamá-las do que você quiser. Cada um dos namespaces em analytics e gamestore herda as configurações eng-role.yaml, eng-rolebinding.yaml e network-policy-allow-gamestore-ingress.yaml no diretório de namespace abstrato eng.

O objeto ResourceQuota definido em quota.yaml usa um NamespaceSelector. Portanto, esse objeto ResourceQuota é criado somente nos namespaces analytics e gamestore.

O do diretório de namespace gamestore tem uma configuração extra para o RoleBinding bob-rolebinding, mas o diretório do namespace analytics não tem essa configuração, portanto, o namespace analytics não tem esse RoleBinding, a menos que alguém o crie manualmente.

O repositório de herança de namespace também tem um arquivo README.md, que tem outros exemplos de como a herança de namespaces funciona.

Namespace restrito

config-management-system é um namespace restrito. Não é possível usá-lo como um diretório de namespace abstrato. A partir da versão 1.11.0, é possível definir um namespace config-management-system. No entanto, o único tipo de recurso permitido para o namespace config-management-system é RootSync.

Excluir namespaces da herança

É possível usar seletores de namespace para isentar namespaces específicos de herdar um recurso na árvore.

O exemplo a seguir permite que um objeto ResourceQuota anotado corretamente no diretório raiz /namespaces seja herdado por todos os namespaces, exceto aqueles 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

Para saber mais sobre NamespaceSelectors no Config Sync, consulte Como limitar os namespaces afetados por um config.

Efeitos das operações do Git nos namespaces

As operações do Git que criam ou excluem diretórios de namespace no diretório namespaces/ podem causar efeitos diferentes daqueles esperados inicialmente. As seções a seguir abrangem essas interações.

Como criar um diretório em namespaces/

Quando uma hierarquia namespaces/ válida é confirmada no repositório, o Config Sync cria namespaces e, em seguida, gera objetos do Kubernetes neles para cada configuração que o diretório de namespace contém ou herda.

Como excluir um diretório de namespaces/

A exclusão de um diretório de namespace é uma operação destrutiva. O namespace e todo o conteúdo dele são excluídos em todos os clusters gerenciados pelo Config Sync onde o namespace existe.

Se você excluir um diretório de namespace abstrato com diretórios de namespaces descendentes, todos esses namespaces e seus respectivos conteúdos serão removidos de todos os clusters gerenciados pelo Config Sync.

Como renomear um diretório em namespaces/

Renomear um diretório de namespace é uma exclusão seguida de uma criação. Ou seja, é também uma operação destrutiva.

Renomear um diretório de namespace abstrato não tem efeito visível externamente.

Como mover um diretório em namespaces/

Mover um namespace ou um diretório de namespace abstrato em namespaces/ não exclui o namespace ou os objetos nele. No entanto, isso não é aplicável quando ele começa ou para de herdar uma configuração de um diretório de namespace abstrato devido a uma alteração na hierarquia.

Integração com controlador de hierarquia

O controlador de hierarquia permite usar namespaces hierárquicos, que são semelhantes aos namespaces abstratos. O Controlador de hierarquias também é compatível com recursos extras, como cotas de recursos hierárquicos e namespaces de autoatendimento.

Selecionar namespaces relacionados

Às vezes, pode ser necessário aplicar políticas a conjuntos de namespaces relacionados por meio de um ancestral comum. O Controlador de hierarquias é compatível com esse recurso usando um conceito conhecido como rótulos de árvore. Os rótulos de árvore também são compatíveis com namespaces abstratos, mesmo se o controlador de hierarquia não estiver ativado.

Os rótulos de árvore são rótulos do Kubernetes com o formato a seguir:

NAMESPACE_NAME.tree.hnc.x-k8s.io/depth: DEPTH

Com esses rótulos, você grava seletores de namespace que podem, por exemplo, ser usados como parte de uma política de rede para permitir o tráfego dentro de uma subárvore de namespaces relacionados, mas não permitir o tráfego fora dela.

Podemos ilustrar esse conceito retornando ao repositório de exemplo.

├── namespaces # Abstract namespace directory
│   ├── eng # Abstract namespace directory
│   │   ├── analytics # Namespace directory
│   │   └── gamestore # Namespace directory
│   ├── rnd # Abstract namespace directory
│   │   ├── incubator-1 # Namespace directory
│   │   └── incubator-2 # Namespace directory
|   |── network-policy-default-deny-all.yaml
|   |── viewers-rolebinding.yaml

Imagine que, neste exemplo, o namespace.yaml no diretório de namespace abstrato gamestore tenha as seguintes etiquetas de árvore:

eng.tree.hnc.x-k8s.io/depth: "1"
gamestore.tree.hnc.x-k8s.io/depth: "0"

É possível usar comandos kubectl para inspecionar essas relações diretamente no cluster, sem ter acesso ao repositório Git:

# View all descendants of 'eng'
kubectl get namespaces -l 'eng.tree.hnc.x-k8s.io/depth'

# View any immediate children of 'eng'
kubectl get namespaces -l 'eng.tree.hnc.x-k8s.io/depth=1'

O controlador de hierarquia também propaga qualquer rótulo de árvore dos namespaces abstratos para os namespaces descendentes. Por exemplo, se você criar um namespace filho de gamestore da seguinte maneira:

kubectl hns create gamestore-v1 -n gamestore

Nesse caso, o namespace gamestore-v1 incluiria todos os rótulos do pai, além do próprio, com a profundidade ajustada adequadamente:

eng.tree.hnc.x-k8s.io/depth: 2
gamestore-v1.tree.hnc.x-k8s.io/depth: 0
gamestore.tree.hnc.x-k8s.io/depth: 1

A seguir