Namespace の継承の概要

このページでは、Config Sync が階層リポジトリの構造に基づいてクラスタ内の Namespace に構成ファイルを適用する方法について説明します。Namespace オブジェクトと Namespace スコープ オブジェクトの構成についても説明します。非構造化リポジトリの場合は、Hierarchy Controller を使用して同様の機能を実現できます。

Namespace の継承の仕組み

Config Sync の最も強力な機能の 1 つは、構成ファイルが存在する階層リポジトリ内の場所に基づいて、Namespace が存在するすべてのクラスタ内の Namespace グループに自動的に構成を適用する機能です。

Config Sync では、リポジトリの namespaces/ ディレクトリとそのサブディレクトリに継承の概念が導入されています。リポジトリの他のディレクトリ(cluster/ など)の構成ファイルは継承の対象ではありません。

階層リポジトリでは、namespaces/ ディレクトリに次の 2 種類のサブディレクトリを含めることができます。

  • 1 つの Namespace の構成ファイルを含む Namespace ディレクトリ。構成ファイルを含むファイルの名前は重要ではありませんが、構成ファイルには kind: Namespace が含まれている必要があります。名前空間ディレクトリには、他の種類の Kubernetes オブジェクトのコンフィグも含めることができます。名前空間ディレクトリにサブディレクトリを含めることはできません。名前空間構成ファイルは、クラスタ内の実際の名前空間を表します。

  • 複数の名前空間ディレクトリを含む抽象名前空間ディレクトリ。他の Kubernetes オブジェクトの構成ファイルも含めることができますが、名前空間の構成ファイルを直下に含めることはできません。Kubernetes クラスタ内のオブジェクトを表すのは抽象名前空間ディレクトリではなく、その下位の名前空間ディレクトリです。

名前空間の構成ファイルを名前空間ディレクトリに追加し忘れた場合、名前空間サブディレクトリにディレクトリを追加した場合、または名前空間の構成ファイルを抽象名前空間ディレクトリに追加した場合は、エラー KNV1003: IllegalNamespaceSubdirectoryError が発生します。

名前空間ディレクトリ内の構成ファイルはその名前空間にのみ適用され、抽象名前空間ディレクトリ内の構成ファイルは抽象名前空間の下位にある名前空間ディレクトリすべてに適用されます(NamespaceSelector が存在する場合は構成ファイルの NamespaceSelector に一致する下位の名前空間)。

namespaces/ ディレクトリ内の構成ファイルの継承は主に、その構成ファイルがリポジトリのディレクトリ ツリーのどこに位置しているかに基づくため、リポジトリの構造を見ることで、特定のクラスタ内の特定の Namespace にどの構成ファイルが適用されるかがわかります。

次の図は、Namespace 継承のサンプル リポジトリnamespaces/ ディレクトリ内で構成ファイルが継承される様子を表しています。青い四角形は抽象 Namespace ディレクトリを表し、オレンジ色の四角形は Kubernetes の実際の Namespace を表します。

サンプルリポでの構成ファイルの継承を示す図

たとえば、viewers-rolebinding.yaml ファイルをブラウザで開きます。このファイルは namespaces ディレクトリ自体に存在するため、Config Sync で管理され登録されているすべてのクラスタの全 Namespace の system:serviceaccounts:foo グループのすべてのメンバーに view ClusterRole が付与されます。

次に、namespaces/eng/ ディレクトリをブラウザで開きます。eng ディレクトリには、Namespace の構成ファイルがないため、抽象 Namespace ディレクトリです。ここには次の構成ファイルが含まれています。

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

2 つのサブディレクトリにはそれぞれ Namespace の構成ファイルが含まれているため、これらのサブディレクトリは Namespace ディレクトリです。ファイルの名前は重要ではありませんが、このリポジトリでは慣例により、すべての Namespace の構成ファイルにこのファイル名を使用しています。これらの Namespace には、eng 抽象 Namespace ディレクトリにある eng-role.yamleng-rolebinding.yamlnetwork-policy-allow-gamestore-ingress.yaml の構成ファイルが継承されます。quota.yaml で定義された ResourceQuota オブジェクトは、対応する NamespaceSelector に一致する Namespace にのみ適用されます。

gamestore Namespace ディレクトリには bob-rolebinding RoleBinding に対する別の構成ファイルがありますが、analytics Namespace ディレクトリにはこの構成ファイルがないため、その RoleBinding は存在しません(誰かが手動で作成した場合を除く)。

namespaces/ で禁止の名前

次の名前は予約されており、リポの namespaces/ ディレクトリ内で名前空間または抽象名前空間ディレクトリとして使用することはできません。

  • config-management-system

構成ファイルの例

ResourceQuota 構成ファイル

次の例は quota という ResourceQuota を作成します。これは、1 Pod、0.1 CPU(100 ミリ CPU)、メモリ 100 MiB というハードリミットを設定します。

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

この構成ファイルを、特定の Namespace に適用されるディレクトリ(namespaces/[NAMESPACE_NAME])に置く場合、構成ファイルはその Namespace にのみ適用されます。この構成ファイルを、Namespace の下位ディレクトリを含む抽象 Namespace ディレクトリnamespaces/)に置く場合は、別の ResourceQuota が下位の Namespace のそれぞれに適用されます。NamespaceSelector アノテーションを使用して ResourceQuota を作成した場合、構成は NamespaceSelector に一致する Namespace にのみ適用されます。

継承からの Namespace の除外

名前空間セレクタを使用して、ツリー内のリソースの継承から特定の名前空間を除外できます。

次の例では、ルート /namespaces ディレクトリでアノテーションが正しく設定された ResourceQuota オブジェクトは、quota-exempt: exempt 以外のすべての Namespace で継承できます。

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

Config Sync での NamesspaceSelectors の詳細については、構成が影響を与える Namespace の制限をご覧ください。

Git 操作が名前空間に及ぼす影響

Git 操作によって namespaces/ ディレクトリ内に名前空間ディレクトリを作成または削除すると、当初期待したものとは異なる結果になる場合があります。このセクションでは、それらの相互作用について説明します。

namespaces/ にディレクトリを作成する

有効な namespaces/ 階層がリポに commit されると、Config Sync は名前空間を作成してから、名前空間ディレクトリに含まれる構成ファイルまたは継承された構成ファイルに対応する Kubernetes オブジェクトをそれらの名前空間に作成します。

namespaces/ のディレクトリを削除する

名前空間ディレクトリを削除することは破壊的な操作です。Config Sync によって管理されているクラスタのうち、その名前空間が存在するすべてのクラスタから、名前空間とそのすべての内容が削除されます。

下位の名前空間ディレクトリを含む抽象名前空間ディレクトリを削除すると、Config Sync によって管理されているすべてのクラスタから、それらすべての名前空間とその内容が削除されます。

namespaces/ 内のディレクトリの名前を変更する

名前空間ディレクトリの名前を変更すると、いったん削除した後再び作成されるため、これも破壊的な操作です。

抽象名前空間ディレクトリの名前を変更しても、外部から見える影響はありません。

namespaces/ 内のディレクトリを移動する

namespaces/ 内で名前空間または抽象名前空間ディレクトリを移動しても、その名前空間やその中のオブジェクトは削除されません。ただし、その階層が変更された結果、抽象名前空間ディレクトリからの構成ファイルの継承が開始または停止される場合は除きます。

Hierarchy Controller との統合

Hierarchy Controller の Namespace の継承のコンセプトは、Hierarchy Controller に関するドキュメントで説明しているとおり、抽象 Namespace でサポートされている Namespace の継承とよく似ています。ただし、階層的なリソース割り当てセルフサービスの Namespace など、いくつかの追加機能がサポートされています。

関連する Namespace を選択する

共通の祖先を介して関連付けられている一連の名前空間にポリシーを適用したい場合があります。Hierarchy Controller は、ツリーラベルと呼ばれるコンセプトに従いこれをサポートします。Hierarchy Controller が有効になっていない場合でも、ツリーラベルは、抽象名前空間によってもサポートされます。

ツリーラベルは、次の形式の Kubernetes ラベルです。

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

これらのラベルを使用すると、たとえば、関連する Namespace のサブツリー内のトラフィックを許可する一方で、そのサブツリー外のトラフィックを許可しないよう、ネットワーク ポリシーの一部として使用できる Namespace セレクタを作成できます。

このコンセプトを説明するために、サンプルリポの図に戻ります。

サンプルリポでの構成ファイルの継承を示す図

たとえば、gamestore 名前空間には次のツリーラベルがあります。

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

Git リポジトリにアクセスしなくても、kubectl を使用してこれらの関係をクラスタで直接検査できます。

# 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'

Hierarchy Controller はまた、抽象名前空間から任意の下位の名前空間にツリーラベルを伝達します。たとえば、次のように gamestore の下位名前空間を作成するとします。

kubectl hns create gamestore-v1 -n gamestore

この場合、gamestore-v1 名前空間には、親からのすべてのラベルとその独自のラベルが含まれ、深度が以下のとおり適切に調整されます。

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

次のステップ