Namespace-Übernahme

Auf dieser Seite wird gezeigt, wie Config Sync Konfigurationen auf Namespaces in Ihren Clustern in einer Hierarchie anwendet. Grundlage ist dabei die Struktur des Repositorys. Weitere Informationen finden Sie unter Namespaces und Namespace-bezogene Objekte konfigurieren.

Funktionsweise der Namespace-Übernahme

Eines der wichtigsten Features von Config Sync ist die Möglichkeit, Konfigurationen automatisch auf Namespace-Gruppen anzuwenden, und zwar in allen Clustern, in denen diese Namespaces vorhanden sind bzw. vorhanden sein sollten. Dies hängt jeweils davon ab, wo sich die Konfigurationen im Repository befinden.

Config Sync führt ein Konzept der Übernahme im Verzeichnis namespaces/ des Repositorys und allen zugehörigen Unterverzeichnissen ein. Für Konfigurationen in anderen Verzeichnissen des Repositorys, z. B. cluster/, gelten die Übernahmeregeln nicht.

Im Repository kann das Verzeichnis namespaces/ zwei verschiedene Arten von Unterverzeichnissen enthalten:

  • Ein Namespace-Verzeichnis enthält eine Konfiguration für einen Namespace. Der Name der Datei mit der Konfiguration ist beliebig, die Konfiguration muss aber kind: Namespace beinhalten. Ein Namespace-Verzeichnis kann auch Konfigurationen für andere Arten von Kubernetes-Objekten enthalten. Ein Namespace-Verzeichnis darf keine Unterverzeichnisse haben. Eine Namespace-Konfiguration steht für einen tatsächlichen Namespace in einem Cluster.

  • Ein abstraktes Namespace-Verzeichnis enthält Namespace-Verzeichnisse. Es können darin auch Konfigurationsdateien für andere Kubernetes-Objekte vorhanden sein, aber keine direkten Konfigurationen für einen Namespace. Ein abstraktes Namespace-Verzeichnis stellt kein Objekt in einem Kubernetes-Cluster dar, die untergeordneten Namespace-Verzeichnisse jedoch schon.

Wurde einem Namespace-Verzeichnis keine Konfiguration für einen Namespace oder einem Namespace-Unterverzeichnis ein Verzeichnis oder einem abstrakten Namespace-Verzeichnis eine Konfiguration für einen Namespace hinzugefügt, wird der folgende Fehler ausgegeben: KNV1003: IllegalNamespaceSubdirectoryError.

Konfigurationen in einem Namespace-Verzeichnis gelten nur für diesen Namespace. Konfigurationen in einem abstrakten Namespace-Verzeichnis werden hingegen auf alle untergeordneten Namespace-Verzeichnisse des abstrakten Namespace oder auf solche untergeordneten Namespaces angewendet, die einem möglicherweise vorhandenen NamespaceSelector einer Konfiguration entsprechen.

Da die Übernahme einer Konfiguration im namespaces/-Verzeichnis hauptsächlich von ihrer Position innerhalb der Verzeichnisstruktur im Repository abhängt, lässt sich anhand des Repositorys nachvollziehen, welche Konfigurationen auf einen bestimmten Namespace in einem bestimmten Cluster angewendet werden.

Im folgenden Diagramm sehen Sie, wie Konfigurationen im Verzeichnis namespaces/ des Beispiel-Repositorys übernommen werden. Die blauen Rechtecke stehen für abstrakte Namespace-Verzeichnisse und die orangen Rechtecke für tatsächliche Namespaces in Kubernetes.

Diagramm zur Konfigurationsübernahme in einem Beispiel-Repository

Öffnen Sie zum Beispiel die Datei viewers-rolebinding.yaml in Ihrem Browser. Sie gewährt jedem Nutzer der Gruppe system:serviceaccounts:audit die ClusterRole view in jedem Namespace, der von Config Sync verwaltet wird und in einem aktivierten Cluster vorhanden ist, da sie selbst im Verzeichnis namespaces enthalten ist.

Öffnen Sie jetzt in Ihrem Browser das Verzeichnis namespaces/online/. Das Verzeichnis online ist ein abstraktes Namespace-Verzeichnis, da es keine Konfiguration für einen Namespace enthält. Klicken Sie auf das Verzeichnis shipping-app-backend. Dieses ist ebenso ein abstraktes Namespace-Verzeichnis, in dem zwei Konfigurationen (pod-creator-rolebinding.yaml und quota.yaml) vorhanden sind. Jedes seiner drei Unterverzeichnisse ist ein Namespace-Verzeichnis, da es jeweils eine Konfiguration für einen Namespace enthält. Der Name der Datei ist beliebig. Das Repository verwendet aber diesen Dateinamen standardmäßig für alle Namespace-Konfigurationen. Jeder dieser Namespaces übernimmt die Konfigurationen pod-creator-rolebinding.yaml und quota.yaml im abstrakten Namespace-Verzeichnis shipping-app-backend.

Das Namespace-Verzeichnis shipping-dev enthält eine zusätzliche Konfiguration für das RoleBinding job-creators. In den beiden anderen Namespace-Verzeichnissen ist diese Konfiguration jedoch nicht vorhanden, weshalb sie auch nicht dieses RoleBinding enthalten, außer, es wird manuell erstellt.

Nicht zulässige Namen in namespaces/

Der folgende Name ist reserviert und kann weder für einen Namespace noch für ein abstraktes Namespace-Verzeichnis im Verzeichnis namespaces/ des Repositorys verwendet werden:

  • config-management-system

Beispielkonfigurationen

Namespace-Konfigurationen

Mit dieser Konfiguration wird ein Namespace namens audit erstellt.

apiVersion: v1
kind: Namespace
metadata:
  name: audit

Beim Erstellen einer Namespace-Konfiguration können Sie dem Namespace auch ein Label hinzufügen. Dies ist möglicherweise für die Verwendung von NamespaceSelector hilfreich.

Mit der folgenden Konfiguration wird der Namespace shipping-prod erstellt, falls er noch nicht oder ohne das Label configmanagement.gke.io/managed vorhanden ist. Diesem Namespace wird env: prod zugewiesen. Außerdem wird für die Annotation audit der Wert true für den Namespace festgelegt. Wenn ein Nutzer diese Annotation manuell ändert oder entfernt, wird sie durch Config Sync sofort auf den Wert in der Konfiguration zurückgesetzt.

apiVersion: v1
kind: Namespace
metadata:
  name: shipping-prod
  labels:
    env: prod
  annotations:
    audit: "true"

ResourceQuota-Konfiguration

In diesem Beispiel wird ein ResourceQuota namens quota erstellt, das ein festes Limit von 1 Pod, 0,1 CPU (100 Milli-CPUs) und 100 MiB Arbeitsspeicher festlegt.

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

Wenn Sie diese Konfiguration in ein Verzeichnis einfügen, das für einen bestimmten Namespace (namespaces/[NAMESPACE_NAME]) gilt, wird die Konfiguration nur für diesen Namespace angewendet. Wenn Sie diese Konfiguration in ein abstraktes Namespace-Verzeichnis (namespaces/) mit untergeordneten Namespaces einfügen, wird ein separates ResourceQuota auf jeden nachfolgenden Namespace angewendet.

Namespaces von Übernahmen ausschließen

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

Im folgenden Beispiel kann ein korrekt annotiertes ResourceQuota-Objekt im Stammverzeichnis /namespaces von jedem Namespace mit Ausnahme des Labels quota-exempt: exempt übernommen werden:

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

Weitere Informationen zu NamesspaceSelectors in Config Sync finden Sie unter Beschränken, welche Namespaces von einer Konfiguration betroffen sind.

Auswirkungen von Git-Vorgängen auf Namespaces

Git-Vorgänge, mit denen Namespace-Verzeichnisse im Verzeichnis namespaces/ erstellt oder gelöscht werden, können andere Auswirkungen haben als ursprünglich erwartet. Diese Interaktionen werden im folgenden Abschnitt erläutert.

Verzeichnis in namespaces/ erstellen

Wenn dem Repository eine gültige namespaces/-Hierarchie zugewiesen wurde, erstellt Config Sync Namespaces und in diesen Namespaces Kubernetes-Objekte für jede Konfiguration, die das Namespace-Verzeichnis enthält oder übernimmt.

Verzeichnis aus namespaces/ löschen

Das Löschen eines Namespace-Verzeichnisses ist ein destruktiver Vorgang. Dabei werden der Namespace und sein gesamter Inhalt in jedem von Config Sync verwalteten Cluster gelöscht, in dem sich der Namespace befindet.

Wenn Sie ein abstraktes Namespace-Verzeichnis mit untergeordneten Namespace-Verzeichnissen löschen, werden alle diese Namespaces und ihre Inhalte in jedem von Config Sync verwalteten Cluster gelöscht.

Verzeichnis in namespaces/ umbenennen

Das Umbenennen eines Namespace-Verzeichnisses besteht aus einem Löschvorgang, auf den ein Erstellvorgang folgt. Damit handelt es sich ebenfalls um einen destruktiven Vorgang.

Wenn Sie ein abstraktes Namespace-Verzeichnis umbenennen, hat dies keine extern sichtbaren Auswirkungen.

Verzeichnis in namespaces/ verschieben

Durch das Verschieben eines Namespace oder eines abstrakten Namespace-Verzeichnisses innerhalb von namespaces/ werden der Namespace bzw. die darin enthaltenen Objekte nicht gelöscht – es sei denn, der Vorgang wirkt sich durch eine Änderung in der Hierarchie auf die Übernahme einer Konfiguration von einem abstrakten Namespace-Verzeichnis aus.

Integration in den Hierarchie-Controller

Der Hierarchie-Controller hat ein ähnliches Konzept der Namespace-Übernahme, das von abstrakten Namespaces unterstützt wird, wie in der Dokumentation für den Hierarchie-Controller beschrieben. Sie unterstützen jedoch einige zusätzliche Features wie hierarchische Ressourcenkontingente und Selfservice-Namespaces.

Zugehörige Namespaces auswählen

Es kann vorkommen, dass Sie Richtlinien auf Gruppen von Namespaces anwenden möchten, die über einen gemeinsamen Ancestor verbunden sind. Der Hierarchie-Controller unterstützt dies mithilfe eines Konzepts, das als Baumlabels bezeichnet wird. Diese werden auch von abstrakten Namespaces unterstützt, auch wenn der Hierarchie-Controller nicht aktiviert ist.

Strukturlabels sind Kubernetes-Labels im folgenden Format:

<namespace-name>.tree.hnc.x-k8s.io/depth: <depth>

Mit diesen Labels können Sie Namespace-Selektoren schreiben, die beispielsweise als Teil einer Netzwerkrichtlinie verwendet werden können, um Traffic innerhalb einer Unterstruktur verwandter Namespaces zuzulassen, aber Traffic von außerhalb dieser Unterstruktur.

Wir können dieses Konzept veranschaulichen, indem wir zum Beispiel des Beispiel-Repositorys zurückkehren.

Diagramm zur Konfigurationsübernahme in einem Beispiel-Repository

Der Namespace shipping-prod hat beispielsweise die folgenden Baumlabels:

shipping-prod.tree.hnc.x-k8s.io/depth: 0
shipping-app-backend.tree.hnc.x-k8s.io/depth: 1
online.tree.hnc.x-k8s.io/depth: 2
root.tree.hnc.x-k8s.io/depth: 3

Mit kubectl können Sie diese Beziehungen direkt im Cluster untersuchen, ohne Zugriff auf das Git-Repository zu haben:

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

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

Der Hierarchie-Controller leitet außerdem alle Baumlabels aus den abstrakten Namespaces an alle untergeordneten Namespaces weiter. Wenn Sie beispielsweise einen untergeordneten Namespace wie shipping-prod erstellen, gehen Sie so vor:

kubectl hns create shipping-prod-v1 -n shipping-prod

In diesem Fall würde der shipping-prod-v1-Namespace alle Labels des übergeordneten Elements zusammen mit eigenem Label enthalten, wobei die Tiefe entsprechend angepasst wird:

shipping-prod-v1.tree.hnc.x-k8s.io/depth: 0
shipping-prod.tree.hnc.x-k8s.io/depth: 1
shipping-app-backend.tree.hnc.x-k8s.io/depth: 2
online.tree.hnc.x-k8s.io/depth: 3
root.tree.hnc.x-k8s.io/depth: 4

Nächste Schritte