名前空間の継承と抽象名前空間

このページでは、Config Sync 階層リポジトリでの名前空間継承のコンセプトとその使用方法について説明します。

Config Sync は、名前空間が存在する(または存在するはずの)すべてのクラスタ内の名前空間のグループに、リポジトリの構造に基づいて構成ファイルを自動的に適用します。これらの名前空間のグループは「抽象名前空間」と呼ばれます。

名前空間の継承と抽象名前空間は、非構造化リポジトリではサポートされません。非構造化リポジトリを使用していて、同様の機能が必要な場合は、Hierarchy Controller を使用します。

名前空間の継承の仕組み

名前空間の継承は、階層リポジトリとそのすべてのサブディレクトリ内の namespaces/ ディレクトリに適用されます。リポジトリの他のディレクトリ(cluster/ など)の構成ファイルは継承の対象ではありません。

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

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

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

名前空間と抽象名前空間リポジトリに正しいタイプの構成ファイルと構造が適用されるように、エラーが発生すると、KNV1003: legalNamespaceSubdirectoryError エラーが報告されます。

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

名前空間の継承例

namespaces/ ディレクトリ内の構成ファイルの継承は、その構成ファイルがリポジトリ内のディレクトリ ツリーのどこに位置しているかに基づいて行われます。特定のクラスタ内の特定の名前空間に適用されている構成ファイルを確認するには、名前空間の継承に関するサンプル リポジトリをご覧ください。

名前空間継承のサンプル リポジトリ内の namespaces/ ディレクトリは次の構造になっています。

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

このサンプル リポジトリの仕組みについて詳しく理解するには、まず 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

この RoleBinding は namespaces/ ディレクトリのルートにあるため、system:serviceaccounts:foo グループ内のすべてのユーザーに、Config Sync が管理するすべての名前空間の view ClusterRole が付与されます。

次に、namespaces/eng/ ディレクトリをブラウザで開きます。eng ディレクトリには、名前空間の構成ファイルがないため、抽象名前空間ディレクトリです。eng ディレクトリには、次の構成ファイルが存在します。

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

eng ディレクトリには、analyticsgamestore という 2 つのサブディレクトリがあります。このサブディレクトリには名前空間の構成ファイルが含まれているため、これらは名前空間ディレクトリになります。この例では、名前空間構成ファイルの名前は namespace.yaml ですが、任意の名前で呼び出すことができます。analyticsgamestore の各名前空間は、eng 抽象名前空間ディレクトリの eng-role.yamleng-rolebinding.yamlnetwork-policy-allow-gamestore-ingress.yaml 構成ファイルを継承します。

quota.yaml で定義された ResourceQuota オブジェクトは NamespaceSelector を使用するため、この ResourceQuota オブジェクトは analytics 名前空間と gamestore 名前空間でのみ作成されます。

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

名前空間継承リポジトリには、名前空間の継承の仕組みを示す README.md ファイルがあります。

制限付きの名前空間

config-management-system は制限付きの名前空間です。抽象名前空間ディレクトリとしては使用できません。バージョン 1.11.0 以降では、config-management-system 名前空間を定義できます。ただし、config-management-system 名前空間で許可されるリソースタイプは RootSync のみです。

名前空間を継承の対象外にする

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

次の例では、ルート /namespaces ディレクトリでアノテーションが正しく設定された ResourceQuota オブジェクトは、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

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

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

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

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

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

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

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

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

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

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

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

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

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

Hierarchy Controller との統合

Hierarchy Controller を使用すると、抽象名前空間に似た階層型名前空間を使用できます。Hierarchy Controller は、階層型リソース割り当てセルフサービス名前空間などの追加機能もサポートしています。

関連する名前空間を選択する

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

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

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

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

このコンセプトについて、サンプル リポジトリに戻って説明しましょう。

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

この例では、gamestore 抽象名前空間ディレクトリの namespace.yaml に次のツリーラベルがあります。

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

次のステップ