複数の Namespace にオブジェクトを同期する

このページでは、Config Sync を使用して Namespace を管理し、Config Sync が Namespace に同期するオブジェクトを選択する方法について説明します。

Kubernetes リソース オブジェクトは、リソースタイプに応じて、クラスタ スコープまたは Namespace スコープのいずれかになります。クラスタを選択するには、特定のクラスタと通信するようにクライアントを構成します。Namespace を選択するには、オブジェクト マニフェストで metadata.namespace フィールドを構成します。Config Sync には、クラスタ セレクタと Namespace セレクタという追加機能が用意されています。これにより、同期するオブジェクトをさらに絞り込むことができます。

このページを読む前に、Kubernetes の次のコンセプトを理解しておく必要があります。

Config Sync を使用したオブジェクトのスコープ設定について

デフォルトでは、Config Sync をクラスタ上に、またはフリートのデフォルトとしてインストールすると、Config Sync は信頼できる情報源内のすべての Kubernetes オブジェクトを、Config Sync がインストールされているクラスタまたはフリート内のすべてのクラスタと同期します。ただし、オブジェクトのスコープをクラスタまたは Namespace に設定することで、クラスタまたは Namespace に同期されるオブジェクトを制御できます。

Config Sync では、次の方法でオブジェクトのスコープを設定できます。

明示的な Namespace を使用する

Config Sync を構成する際は、明示的な Namespace 宣言を使用することをおすすめします。これにより、Namespace メタデータを管理し、必要に応じて後で Namespace を削除できます。

デフォルト設定は implicit ですが、namespaceStrategy フィールドを explicit に設定することで、RootSync オブジェクトまたは RepoSync オブジェクト内の Namespace 戦略を変更できます。詳細については、Namespace 戦略をご覧ください。

Namespace セレクタについて

Namespace セレクタは、同一のリソース オブジェクトを複数の Namespace にデプロイできる Config Sync の機能です。

Namespace セレクタの使用方法は、Kubernetes ラベルセレクタを使用して Service を一連の Pod にマッピングする方法と似ていますが、間接的な手順が追加されます。既存のリソースタイプにカスタム フィールドを追加できないため、代わりに NamespaceSelector オブジェクトでセレクタを定義します。次に、そのセレクタを使用するオブジェクトのアノテーションで、そのセレクタを名前で参照します。

Namespace セレクタを使用するには:

  1. デプロイする Namespace にラベルを追加するか、既存のラベルを選択します。
  2. 信頼できる情報源内の NamespaceSelector リソース オブジェクトを定義します。Config Sync は NamespaceSelector オブジェクトをクラスタに同期しません。
  3. 1 つ以上の Namespace に同期するオブジェクトごとに、オブジェクトの構成を変更して metadata.namespace フィールドを削除し、NamespaceSelectormetadata.name と一致する値を持つ configmanagement.gke.io/namespace-selector アノテーションを追加します。

以降のセクションの例では、NamespaceSelector オブジェクトを定義し、NamespaceSelector を使用するように他のオブジェクトにアノテーションを付ける方法について詳しく説明します。

始める前に

Namespace セレクタを使用する

Namespace セレクタは、等式ベースの要件またはセットベースの要件のいずれかで定義されます。複数の要件を組み合わせることができます。

等式ベースのラベルセレクタの例

次の例は、等式ベースのセレクタを使用して、構成が適用される Namespace を選択する方法を示しています。

  1. 1 つ以上の Namespace にラベルを追加します。

    kubectl label namespace NAMESPACE app=gamestore
    

    NAMESPACE を Namespace の名前に置き換えます。

    ラベルを付ける各 Namespace に対して、このコマンドを実行します。

  2. gamestore-selector という名前の Namespace セレクタを作成します。

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

    別のオブジェクトの構成でこの Namespace セレクタが参照されている場合、その構成は app: gamestore ラベルを持つ Namespace のオブジェクトにのみ適用できます。

  3. Namespace セレクタは、別の構成で参照しなければ効果はありません。Namespace セレクタを参照するオブジェクト割り当てのサンプルを作成します。

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

    リソース割り当ては、app: gamestore ラベルを持つ Namespace にのみ作成されます。

セットベースのラベルセレクタの例

次の例は、セットベースのセレクタを使用して、オブジェクトの継承から Namespace を除外する方法を示しています。

  1. 1 つ以上の Namespace にラベルを追加します。

    kubectl label namespace NAMESPACE quota-exempt=exempt
    

    NAMESPACE を Namespace の名前に置き換えます。

    ラベルを付ける各 Namespace に対して、このコマンドを実行します。

  2. exclude-exempt-namespaces という名前の Namespace セレクタを作成します。

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

    別のオブジェクトの構成でこの Namespace セレクタが参照されている場合、その構成は quota-exempt: exempt の Key-Value ペアを持つ Namespace 以外のすべての Namespace に適用されます。

  3. Namespace セレクタは、別の構成で参照しなければ効果はありません。Namespace セレクタを参照するオブジェクト割り当てのサンプルを作成します。

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

    リソース割り当ては、quota-exempt: exempt の Key-Value ペアを持つ Namespace 以外のすべての Namespace に作成されます。

チームスコープとフリート Namespace の統合

Google Cloud で作成されたフリート Namespace には、自動的に fleet.gke.io/fleet-scope: your-scope ラベルが付きます。すべての Namespace に、Kubernetes kubernetes.io/metadata.name: your-namespace ラベルも付いています。これらのデフォルトのラベルを使用して、フリート Namespace を選択するための Namespace セレクタを設定できます。

フリート テナンシーのチュートリアルでは、フリートとチームスコープで Namespace セレクタを使用して、さまざまなチームのオブジェクトを選択的に管理する方法について詳しく説明しています。

階層モードの Namespace スコープ オブジェクト

ほとんどのユースケースでは非構造化リポジトリが推奨されますが、Namespace セレクタを使用して、階層型リポジトリでオブジェクトのスコープを設定することもできます。Namespace セレクタの使用方法は同じですが、信頼できる情報源で Namespace 構成を整理する方法に関しては追加の制限事項と要件があります。

制限事項

階層型リポジトリで Namespace セレクタ構成を使用する場合は、次の制限事項と要件に注意してください。

  • Namespace と Namespace スコープ オブジェクトの構成ファイルはすべて、階層型リポジトリnamespaces/ ディレクトリとその下位ディレクトリに保存する必要があります。
  • namespaces/NAMESPACE サブディレクトリ内の Namespace 構成ファイルを明示的に指定する必要があります。ここで、NAMESPACE は Namespace の名前と一致します。また、他のすべての Namespace スコープ オブジェクトを同じサブディレクトリに保存する必要があります。Namespace 構成がない場合、Config Sync は KNV1044 エラーを返します。
  • Namespace セレクタを参照するリソースは、namespaces/ ディレクトリのディレクトリ構造に関係なく、抽象 Namespace から特定の構成を継承する Namespace に適用されます。

Namespace セレクタの場所

階層型リポジトリでは、Namespace セレクタ構成は任意の抽象 Namespace ディレクトリに配置できますが、Namespace ディレクトリに配置することはできません。

次のリポジトリ アーキテクチャの例は、Namespace セレクタの有効な場所と無効な場所を示しています。

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

namespacesengrnd ディレクトリは抽象 Namespace を表すため、セレクタを配置できます。一方、gamestore ディレクトリと incubator-1 ディレクトリは実際の Namespace を表すため、Namespace セレクタを配置できません。

抽象 Namespace を構成する

階層型リポジトリでは、必要に応じて抽象 Namespace を使用できます。

次の例は、Namespace によって継承される追加の構成を含む抽象 Namespace に Namespace ディレクトリを移動する方法を示しています。

  1. リポジトリに抽象 Namespace ディレクトリを作成します。抽象 Namespace ディレクトリには Namespace の構成は含まれませんが、その下位の Namespace ディレクトリには構成が含まれます。

  2. 作成した抽象 Namespace ディレクトリで、最終的にロールを継承する Namespace のすべてのオブジェクトに対する get 権限と list 権限を付与するロールの構成を作成します。

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: ROLE_NAME
    rules:
    - apiGroups: [""]
      resources: ["*"]
      verbs: ["get", "list"]
    

    ROLE_NAME は、ロールの名前に置き換えます。

  3. ロールをメールグループにバインドするロール バインディングの構成を作成します。

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: ROLE_NAME
    subjects:
    - kind: Group
      name: group@example.com
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name:  ROLEBINDING_NAME
      apiGroup: rbac.authorization.k8s.io
    

    ROLEBINDING_NAME は、ロールの名前に置き換えます。

  4. 前のセクションで作成した Namespace 構成を、namespaces/ ディレクトリからこのセクションで作成した抽象 Namespace ディレクトリに移動します。

オブジェクトの継承を無効にする

hierarchyMode フィールドを none に設定すると、任意の構成の継承を選択的に無効にできます。HierarchyConfig はリポジトリの system/ ディレクトリに保存されています。次の例では、ロール バインディングの継承を無効にします。

# 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