Namespaces und Namespace-bezogene Objekte konfigurieren

Auf dieser Seite wird beschrieben, wie Sie mit Config Sync Namespaces und namespace-bezogene Objekte verwalten können.

Namespace konfigurieren

Die Konfiguration eines Namespace funktioniert für unstrukturierte und hierarchische Repositories unterschiedlich. In den folgenden Beispielen werden die Unterschiede hervorgehoben.

Unstrukturiertes Repository

Konfigurationen für Namespaces und namespace-bezogene Objekte können sich im Verzeichnis oder in Unterverzeichnissen des Repositorys befinden.

Führen Sie die folgenden Schritte aus, um in jedem registrierten Cluster einen Namespace namens gamestore zu konfigurieren:

  1. Erstellen Sie eine namespace-gamestore.yaml-Datei mit folgendem Inhalt:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: gamestore
    

    Sie müssen nur eine YAML-Datei mit der Namespace-Konfiguration erstellen.

  2. Erstellen Sie einen Commit, der die namespace-gamestore.yaml-Konfiguration enthält, und übertragen Sie den Commit per Push an das Remote-Repository.

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

    Dabei gilt:

    • REMOTE_NAME: der Name Ihres Remote-Repositorys
    • BRANCH_NAME: der Zweig, zu dem Sie einen Commit durchführen möchten

    In diesem Beispiel wird die Datei dem Stammverzeichnis hinzugefügt, Sie können diese Datei jedoch in jedes der Unterverzeichnisse des Repositorys verschieben.

Hierarchisches Repository

Alle Konfigurationen für Namespaces und namespace-bezogene Objekte befinden sich im Verzeichnis namespaces/ des hierarchischen Repositorys und in den untergeordneten Verzeichnissen.

So konfigurieren Sie einen Namespace namens gamestore in jedem registrierten Cluster:

  1. Erstellen Sie im lokalen Klon Ihres Repository ein Namespace-Verzeichnis. Ein Namespace-Verzeichnis enthält eine Konfiguration für einen Namespace. Der Name des Namespace-Verzeichnisses muss mit dem Namen des Namespace übereinstimmen. In diesem Beispiel heißt das Verzeichnis namespaces/gamestore:

    mkdir namespaces/gamestore
    
  2. Erstellen Sie im Namespace-Verzeichnis eine Datei gamestore.yaml mit folgendem Inhalt:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: gamestore
    

    metadata.name muss dem Namen des Namespace-Verzeichnisses entsprechen.

  3. Erstellen Sie einen Commit, der die gamestore.yaml-Konfiguration enthält, und übertragen Sie den Commit per Push an das Remote-Repository.

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

    Dabei gilt:

    • REMOTE_NAME: der Name Ihres Remote-Repositorys
    • BRANCH_NAME: der Zweig, zu dem Sie einen Commit durchführen möchten

Nach kurzer Zeit wird der gamestore-Namespace in jedem registrierten Cluster erstellt. Führen Sie zur Bestätigung ein "describe" auf den Namespace aus:

kubectl describe namespace gamestore

Wenn Sie die Konfiguration entfernen und den gamestore-Namespace aus registrierten Clustern löschen möchten, erstellen Sie einen neuen Commit, der die Datei entfernt, und übertragen Sie ihn per Push an das Remote-Repository. Entfernen Sie die Konfiguration nicht, wenn Sie einen abstrakten Namespace für ein hierarchisches Repository konfigurieren möchten.

Namespace-bezogenes Objekt konfigurieren

In unstrukturierten Repositories können Sie Namespace-bezogene Objekte in jedem Verzeichnis oder Unterverzeichnis speichern, ohne dass eine Namespace-Konfiguration erforderlich ist. Wenn eine Namespace-Konfiguration fehlt, erstellt Config Sync automatisch ein implizites Namespace-Objekt und wendet alle Konfigurationen auf diesen Namespace an.

Dieses Verhalten kann mit dem Feld namespaceStrategy geändert werden. Wenn namespaceStrategy auf explicit gesetzt ist, erstellt Config Sync nicht automatisch ein implizites Namespace-Objekt. Weitere Informationen finden Sie unter Namespace-Strategie.

In hierarchischen Repositories müssen Sie explizit eine Namespace-Konfiguration im Unterverzeichnis namespaces/NAMESPACE angeben, wobei NAMESPACE mit dem Namen des Namespace übereinstimmen muss. Alle anderen Namespace-bezogenen Konfigurationen müssen ebenfalls im selben Unterverzeichnis gespeichert werden. Wenn eine Namespace-Konfiguration fehlt, gibt Config Sync den Fehler KNV1044 zurück, der auf eine fehlende Namespace-Konfiguration hinweist.

Abstrakten Namespace konfigurieren

Dieser Abschnitt gilt nur für hierarchische Repositories, da abstrakte Namespaces in unstrukturierten Repositories nicht unterstützt werden.

Dieses Beispiel erweitert das Beispiel aus Namespace konfigurieren um das Verschieben des Namespace-Verzeichnisses gamestore in einen abstrakten Namespace, der zusätzliche, vom gamestore-Namespace übernommene Konfigurationen enthält.

  1. Erstellen Sie im lokalen Klon des Repository ein abstraktes Namespace-Verzeichnis namens eng:

    mkdir namespaces/eng
    

    Ein abstraktes Namespace-Verzeichnis enthält keine Konfiguration für einen Namespace, die untergeordneten Namespace-Verzeichnisse jedoch schon.

  2. Erstellen Sie im abstrakten Namespace-Verzeichnis eng eine Konfiguration für eine Rolle mit dem Namen eng-viewer, die get und list für alle Ressourcen in einem Namespace gewährt, der schließlich die Rolle übernimmt:

    # namespaces/eng/eng-role.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: eng-viewer
    rules:
    - apiGroups: [""]
      resources: ["*"]
      verbs: ["get", "list"]
    
  3. Erstellen Sie eine Konfiguration für ein RoleBinding mit dem Namen eng-admin, das die Rolle eng-viewer an die Gruppe eng@example.com bindet:

    # 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. Verschieben Sie das Namespace-Verzeichnis gamestore von namespaces/ nach namespaces/eng/:

    mv namespaces/gamestore /namespaces/eng/
    
  5. Übernehmen Sie all Ihre Änderungen und übertragen Sie sie per Push an das Remote-Repository.

Config Sync merkt sich die Änderung und wendet die neue Role und RoleBinding auf allen registrierten Clustern auf den gamestore-Namespace an.

Wenn Sie die Konfigurationen entfernen und den gamestore-Namespace aus registrierten Clustern löschen möchten, können Sie einen neuen Commit erstellen, bei dem der gesamte abstrakte Namespace eng entfernt wird, und ihn per Push an das Remote-Repository übertragen.

Konfiguration auf bestimmte Cluster begrenzen

Im Normalfall wendet Config Sync eine Konfiguration auf jeden registrierten Cluster an. Befindet sich die Konfiguration jedoch innerhalb des Unterverzeichnisses namespaces/ eines hierarchischen Repositorys, erstellt Config Sync zuerst den Namespace in jedem Cluster und wendet dann alle übernommenen Konfigurationen auf diesen Namespace an. Verwenden Sie einen ClusterSelector, wenn Sie anhand der Labels jedes Clusters begrenzen möchten, welche Cluster durch eine bestimmte Konfiguration beeinflusst werden. Weitere Informationen finden Sie unter ClusterSelectors verwenden.

Begrenzen, auf welche Namespaces sich eine Konfiguration auswirkt

Verwenden Sie einen NamespaceSelector, um zu begrenzen, auf welche Namespaces sich eine Konfiguration auswirkt. Ein NamespaceSelector ist ein spezieller Konfigurationstyp, der Kubernetes-labelSelectors verwendet. Sie können NamespaceSelectors in Kombination mit Konfigurationen für namespace-bezogene Objekte in einem unstrukturierten Repository oder einem hierarchischen Repository deklarieren, um einzuschränken, welche Namespaces diese Konfiguration übernehmen können. NamespaceSelectors sind ClusterSelectors ähnlich, sind aber nicht damit identisch. Ein NamespaceSelector begrenzt den Pool der Namespaces, auf die eine Konfiguration angewendet wird.

Um einen NamespaceSelector zu deklarieren, fügen Sie entweder die Annotation metadata.namespace oder die Annotation NamespaceSelector hinzu. Die Angabe beider Annotationen ist ungültig. Wenn in namespace-bezogenen Ressourcen metadata.namespace oder die Annotation NamespaceSelector nicht deklariert wird, verwendet Config Sync den „Standard“-Namespace des Clusters.

NamespaceSelectors in unstrukturierten Repositories

Ein unstrukturiertes Repository muss nicht alle Namespaces für die namespace-bezogenen Objekte im Repository deklarieren. Ein Objekt kann einen metadata.namespace definieren, ohne ein übereinstimmendes Namespace-Objekt in einem unstrukturierten Repository zu haben. Wenn der Namespace bereits im Cluster vorhanden ist, erstellt Config Sync das Objekt in diesem Namespace. Wenn der Namespace noch nicht im Cluster vorhanden ist, erstellt Config Sync den Namespace implizit.

Bevor Sie ein unstrukturiertes Repository mit Objekten erstellen, die zuvor in einem hierarchischen Repository verwendet wurden, sollten Sie kontrollieren, dass Ihre NamespaceSelectors nicht auf zusätzliche Ressourcen angewendet werden.

Wenn Sie Namespace-bezogene Objekte aus einem unstrukturierten Repository entfernen, löscht Config Sync diese Objekte, jedoch keine Namespaces, die möglicherweise implizit für diese Objekte erstellt wurden. Dies liegt daran, dass Config Sync nicht ermitteln kann, wann sich ein Namespace, der implizit erstellt wurde, ohne Folgen löschen lässt. Deshalb verbleibt er dauerhaft im Cluster.

NamespaceSelector-Modus

In einem unstrukturierten Repository werden Objekte, die die Annotation NamespaceSelector deklarieren, auf alle Namespaces angewendet, die die Bedingungen eines NamespaceSelector erfüllen. In Config Sync-Versionen vor 1.17.0 gilt die Annotation NamespaceSelector nur für übereinstimmende Namespaces, die in der "Source of Truth" statisch deklariert sind. In Version 1.17.0 und höher unterstützt das Objekt NamespaceSelector den dynamischen Modus, indem es spec.mode auf dynamic setzt. Im dynamischen Modus erstreckt sich die Auswahl sowohl auf statisch deklarierte Namespaces als auch auf solche, die dynamisch im Cluster vorhanden sind. Dynamisch ausgewählte Namespaces sind bereits auf dem Cluster vorhanden und werden daher nicht von Config Sync verwaltet. Der Standardmodus ist static.

NamespaceSelectors in hierarchischen Repositories

In einem hierarchischen Repository werden Objekte, die die Annotation NamespaceSelector deklarieren, auf Namespaces angewendet, die eine bestimmte Konfiguration von einem abstrakten Namespace übernehmen, unabhängig von der Verzeichnisstruktur des Verzeichnisses namespaces/. Ein ClusterSelector begrenzt den Pool von Clustern, auf die eine Konfiguration angewendet wird, unabhängig davon, ob sich die Konfiguration auf ein cluster- oder namespace-bezogenes Objekt bezieht.

NamespaceSelector-Speicherort

In einem unstrukturierten Repository können Sie die NamespaceSelectors in jedem beliebigen Verzeichnis oder in Unterverzeichnissen platzieren.

In einem hierarchischen Repository können Sie NamespaceSelectors in jedem Verzeichnis für abstrakte Namespaces ablegen, jedoch nicht in einem Namespace-Verzeichnis.

Die folgende Beispiel-Repository-Architektur zeigt gültige und ungültige Speicherorte für NamespaceSelectors, wenn Sie ein hierarchisches Repository verwenden:

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

Da die Verzeichnisse namespaces, eng und rnd abstrakte Namespaces darstellen, können Sie in diese einen Selektor einfügen. Da die Verzeichnisse gamestore und incubator-1 jedoch tatsächliche Namespaces darstellen, können Sie darin keinen NamespaceSelector platzieren.

NamespaceSelector-Beispiele

Sie können eine NamespaceSelector mit Label-Selektoren verwenden, um Namespaces ein- oder auszuschließen. Kubernetes unterstützt gleichheitsbasierte und satzbasierte Selektoren. Sie können beide Selektortypen kombinieren, um die Auswahl der Namespaces weiter zu verfeinern.

Gleichheitsbasierter Label-Selektor

Mit der folgenden Konfiguration wird ein NamespaceSelector mit dem Namen gamestore-selector erstellt. Wenn eine andere Konfiguration auf diesen NamespaceSelector verweist, kann diese Konfiguration nur auf Objekte in Namespaces mit dem Label app: gamestore angewendet werden.

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

Wenn Sie in einer Konfiguration auf einen NamespaceSelector verweisen möchten, geben Sie in der Annotation configmanagement.gke.io/namespace-selector den Namen des NamespaceSelectors an.

Ein NamespaceSelector hat keine Auswirkungen, bis Sie ihn in einer anderen Konfiguration referenzieren. Wenn der NamespaceSelector gamestore-selector sich in derselben Hierarchie befindet wie das ResourceQuota quota, wird das ResourceQuota nur in Namespaces mit dem Label app: gamestore erstellt:

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

Die Verwendung eines NamespaceSelector umfasst also drei Schritte:

  1. Labels zu Namespaces hinzufügen
  2. NamespaceSelector-Konfiguration erstellen
  3. NamespaceSelector-Objekt in einer anderen Konfiguration referenzieren

Satz-basierter Label-Selektor

Mit Namespace-Selektoren können bestimmte Namespaces von der Übernahme einer Ressource in der Struktur ausgenommen werden. Dazu verwenden Sie satzbasierte Labelselektoren.

Wenn in diesem Beispiel ResourceQuota durch Festlegen der Annotation configmanagement.gke.io/namespace-selector: excludes-exempt-namespaces mit NamespaceSelector annotiert ist, wird ResourceQuota in jedem Namespace mit Ausnahme von Namespaces erstellt, die mit dem Label quota-exempt: exempt versehen sind:

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

Einbindung in Teambereiche und Flotten-Namespaces

In Google Cloud erstellte Flotten-Namespaces haben automatisch das Label fleet.gke.io/fleet-scope: your-scope. Alle Namespaces haben auch das Kubernetes-Label kubernetes.io/metadata.name: your-namespace. Sie können diese Standardlabels verwenden, um NamespaceSelector für die Auswahl von Flotten-Namespaces einzurichten.

Übernahme für einen Objekttyp deaktivieren

HierarchyConfig-Kubernetes-Objekte werden in unstrukturierten Repositories nicht unterstützt. Das folgende Beispiel gilt nur für die hierarchischen Repositories.

Sie können die Übernahme für jede Konfiguration selektiv deaktivieren, indem Sie das Feld hierarchyMode auf none setzen. HierarchyConfigs werden im Verzeichnis system/ des Repositorys gespeichert. In diesem Beispiel wird die Übernahme für RoleBindings deaktiviert.

# 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

Nächste Schritte