Visão geral da herança de namespaces

Esta página mostra como o Config Sync aplica configurações a namespaces nos clusters em uma hierarquia com base na estrutura do repositório hierárquico. Veja também mais detalhes sobre Como configurar namespaces e objetos com escopo de namespace. Para repositórios não estruturados, é possível usar o Controlador de hierarquias para ter uma funcionalidade semelhante.

Como funciona a herança de namespaces

Um dos aspectos mais avançados do Config Sync é a capacidade de aplicar automaticamente configurações a grupos de namespaces em todos os clusters onde existem (ou deveriam existir) esses namespaces. Isso é feito com base na localização das configurações. localizado em um repositório hierárquico.

O Config Sync apresenta o conceito de herança no diretório namespaces/ do repositório e em todos os respectivos subdiretórios. As configurações em outros diretórios no repositório, como cluster/, não estão sujeitos à herança.

No 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.

Se você esquecer de adicionar uma configuração para um namespace a um diretório de namespace, ou se você adicionar um diretório a um subdiretório de namespace ou adicionar uma configuração para um namespace a um diretório abstrato, o resultado será o erro KNV1003: IllegalNamespaceSubdirectoryError.

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.

Como a herança de uma configuração no diretório namespaces/ é baseada em grande parte na localização dentro da árvore de diretórios do repositório, é possível navegar pelo repositório para entender quais configurações estão sendo aplicadas a um determinado namespace em um cluster específico.

Veja no diagrama a seguir como as configurações são herdadas no diretório namespaces/ do exemplo de repositório de herança de namespaces. Os retângulos azuis representam os diretórios de namespaces abstratos e os de cor laranja representam namespaces reais no Kubernetes.

Diagrama mostrando a herança de config no repo de exemplo

Por exemplo, abra o arquivo viewers-rolebinding.yaml (em inglês) no seu navegador. Ele concede a qualquer pessoa no grupo system:serviceaccounts:foo o ClusterRole view em todos os namespaces, gerenciados pelo Config Sync de cada cluster registrado, já que ele mesmo existe no diretório namespaces.

Agora abra o diretório namespaces/eng/ (em inglês) no navegador. O eng é um diretório de namespace abstrato porque não tem uma configuração de um namespace. Ele contém os seguintes configs:

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

Cada um dos dois subdiretórios é um diretório de namespace, porque contém um config para um namespace. O nome do arquivo não é importante, mas ele é usado por esse repositório em todos as configurações do namespace, por convenção. Cada um desses namespaces 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 só se aplica ao namespace que corresponde ao NamespaceSelector correspondente.

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

Nomes não permitidos em namespaces/

Os nomes a seguir são reservados e não podem ser usados como namespaces ou como diretórios de namespace abstrato no diretório namespaces/ do repositório:

  • config-management-system

Configs de exemplo

Config ResourceQuota

Neste exemplo, você cria um ResourceQuota chamado quota, que define um limite absoluto de um pod, 0,1 CPU (100 mili-CPUs) e 100 MiB de memória.

kind: ResourceQuota
apiVersion: v1
metadata:
  name: quota
spec:
  hard:
    pods: "1"
    cpu: "100m"
    memory: 100Mi

Se você incluir essa configuração em um diretório que se aplica a determinado namespace (namespaces/[NAMESPACE_NAME]), ela se aplicará somente a esse namespace. Se você incluir essa configuração em um diretório de namespace abstrato (namespaces/) que tenha descendentes de namespace, um ResourceQuota separado será aplicado a cada namespace descendente. Se você criar um ResourceQuota com uma anotação NamespaceSelector, o config se aplicará somente aos namespaces que corresponderem ao NamespaceSelector.

Como excluir namespaces da herança

Os seletores de namespace podem ser usados 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 NamesspaceSelectors 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. Esta seção cobre 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 tem um conceito muito semelhante de herança de namespace com o conceito compatível com namespaces abstratos, como descrito na documentação do controlador de hierarquia. No entanto, eles são compatíveis com alguns recursos extras, como cotas de recursos hierárquicos e namespaces de autoatendimento.

Como selecionar namespaces relacionados

Há momentos em que convém aplicar políticas em conjuntos de namespaces relacionados por meio de um ancestral comum. O controlador de hierarquia é compatível com isso ao usar um conceito conhecido como rótulos de árvore, que também são compatíveis com namespaces abstratos, mesmo que o controlador de hierarquia não esteja 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 diagrama do repositório de exemplo (em inglês).

Diagrama mostrando a herança de configuração no repositório de exemplo

Como exemplo, o namespace gamestore tem estes rótulos de árvore:

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

É possível usar 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