7.6. ネットワークポリシーの設定

クラスター管理者またはプロジェクト管理者として、プロジェクトのネットワークポリシーを設定できます。

7.6.1. ネットワークポリシーについて

Kubernetes ネットワークポリシーをサポートする Kubernetes Container Network Interface (CNI) プラグインを使用するクラスターでは、ネットワークの分離は NetworkPolicy オブジェクトによって完全に制御されます。

OpenShift Container Platform 4.10 では、OpenShift SDN はデフォルトのネットワーク分離モードでのネットワークポリシーの使用をサポートしています。

OpenShift SDN クラスターネットワークプロバイダーは、egress フィールドで指定された egress ネットワークポリシーをサポートするようになりました。

警告

ネットワークポリシーは、ホストのネットワーク namespace には適用されません。ホストネットワークが有効にされている Pod はネットワークポリシールールによる影響を受けません。ただし、ホストネットワークの Pod に接続する Pod はネットワークポリシールールの影響を受ける可能性があります。

ネットワークポリシーは、ローカルホストまたは常駐ノードからのトラフィックをブロックすることはできません。

デフォルトで、プロジェクトのすべての Pod は他の Pod およびネットワークのエンドポイントからアクセスできます。プロジェクトで 1 つ以上の Pod を分離するには、そのプロジェクトで NetworkPolicy オブジェクトを作成し、許可する着信接続を指定します。プロジェクト管理者は独自のプロジェクト内で NetworkPolicy オブジェクトの作成および削除を実行できます。

Pod が 1 つ以上の NetworkPolicy オブジェクトのセレクターで一致する場合、Pod はそれらの 1 つ以上の NetworkPolicy オブジェクトで許可される接続のみを受け入れます。NetworkPolicy オブジェクトによって選択されていない Pod は完全にアクセス可能です。

ネットワークポリシーは、TCP、UDP、および SCTP プロトコルにのみ適用されます。他のプロトコルは影響を受けません。

以下のサンプル NetworkPolicy オブジェクトは、複数の異なるシナリオをサポートすることを示しています。

  • すべてのトラフィックを拒否します。

    プロジェクトに deny by default (デフォルトで拒否) を実行させるには、すべての Pod に一致するが、トラフィックを一切許可しない NetworkPolicy オブジェクトを追加します。

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: deny-by-default
    spec:
      podSelector: {}
      ingress: []
  • OpenShift Container Platform Ingress コントローラーからの接続のみを許可します。

    プロジェクトで OpenShift Container Platform Ingress コントローラーからの接続のみを許可するには、以下の NetworkPolicy オブジェクトを追加します。

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-from-openshift-ingress
    spec:
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              network.openshift.io/policy-group: ingress
      podSelector: {}
      policyTypes:
      - Ingress
  • プロジェクト内の Pod からの接続のみを受け入れます。

    Pod が同じプロジェクト内の他の Pod からの接続を受け入れるが、他のプロジェクトの Pod からの接続を拒否するように設定するには、以下の NetworkPolicy オブジェクトを追加します。

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-same-namespace
    spec:
      podSelector: {}
      ingress:
      - from:
        - podSelector: {}
  • Pod ラベルに基づいて HTTP および HTTPS トラフィックのみを許可します。

    特定のラベル (以下の例の role=frontend) の付いた Pod への HTTP および HTTPS アクセスのみを有効にするには、以下と同様の NetworkPolicy オブジェクトを追加します。

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-http-and-https
    spec:
      podSelector:
        matchLabels:
          role: frontend
      ingress:
      - ports:
        - protocol: TCP
          port: 80
        - protocol: TCP
          port: 443
  • namespace および Pod セレクターの両方を使用して接続を受け入れます。

    namespace と Pod セレクターを組み合わせてネットワークトラフィックのマッチングをするには、以下と同様の NetworkPolicy オブジェクトを使用できます。

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-pod-and-namespace-both
    spec:
      podSelector:
        matchLabels:
          name: test-pods
      ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                project: project_name
            podSelector:
              matchLabels:
                name: test-pods

NetworkPolicy オブジェクトは加算されるものです。 つまり、複数の NetworkPolicy オブジェクトを組み合わせて複雑なネットワーク要件を満すことができます。

たとえば、先の例で定義された NetworkPolicy オブジェクトの場合、同じプロジェト内に allow-same-namespaceallow-http-and-https ポリシーの両方を定義することができます。これにより、ラベル role=frontend の付いた Pod は各ポリシーで許可されるすべての接続を受け入れます。つまり、同じ namespace の Pod からのすべてのポート、およびすべての namespace の Pod からのポート 80 および 443 での接続を受け入れます。

7.6.2. サンプル NetworkPolicy オブジェクト

以下は、サンプル NetworkPolicy オブジェクトにアノテーションを付けます。

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-27107 1
spec:
  podSelector: 2
    matchLabels:
      app: mongodb
  ingress:
  - from:
    - podSelector: 3
        matchLabels:
          app: app
    ports: 4
    - protocol: TCP
      port: 27017
1
NetworkPolicy オブジェクトの名前。
2
ポリシーが適用される Pod を説明するセレクター。ポリシーオブジェクトは NetworkPolicy オブジェクトが定義されるプロジェクトの Pod のみを選択できます。
3
ポリシーオブジェクトが入力トラフィックを許可する Pod に一致するセレクター。セレクターは、NetworkPolicy と同じ namaspace にある Pod を照合して検索します。
4
トラフィックを受け入れる 1 つ以上の宛先ポートのリスト。

7.6.3. ネットワークポリシーの作成

クラスターの namespace に許可される Ingress または egress ネットワークトラフィックを記述する詳細なルールを定義するには、ネットワークポリシーを作成できます。

注記

cluster-admin ロールを持つユーザーでログインしている場合、クラスター内の任意の namespace でネットワークポリシーを作成できます。

前提条件

  • クラスターは、NetworkPolicy オブジェクトをサポートするクラスターネットワークプロバイダーを使用している (例: mode: NetworkPolicy が設定された OpenShift SDN ネットワークプロバイダー)。このモードは OpenShiftSDN のデフォルトです。
  • OpenShift CLI (oc) がインストールされている。
  • admin 権限を持つユーザーとしてクラスターにログインしている。
  • ネットワークポリシーが適用される namespace で作業している。

手順

  1. ポリシールールを作成します。

    1. <policy_name>.yaml ファイルを作成します。

      $ touch <policy_name>.yaml

      ここでは、以下のようになります。

      <policy_name>
      ネットワークポリシーファイル名を指定します。
    2. 作成したばかりのファイルで、以下の例のようなネットワークポリシーを定義します。

      すべての namespace のすべての Pod から ingress を拒否します。

      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: deny-by-default
      spec:
        podSelector:
        ingress: []

    同じ namespace のすべての Pod から ingress を許可します。

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-same-namespace
    spec:
      podSelector:
      ingress:
      - from:
        - podSelector: {}
  2. ネットワークポリシーオブジェクトを作成するには、以下のコマンドを入力します。

    $ oc apply -f <policy_name>.yaml -n <namespace>

    ここでは、以下のようになります。

    <policy_name>
    ネットワークポリシーファイル名を指定します。
    <namespace>
    オプション: オブジェクトが現在の namespace 以外の namespace に定義されている場合は namespace を指定します。

    出力例

    networkpolicy.networking.k8s.io/default-deny created

注記

cluster-admin 権限で Web コンソールにログインする場合、YAML で、または Web コンソールのフォームから、クラスターの任意の namespace でネットワークポリシーを直接作成できます。

7.6.4. ネットワークポリシーを使用したマルチテナント分離の設定

他のプロジェクト namespace の Pod およびサービスから分離できるようにプロジェクトを設定できます。

前提条件

  • クラスターは、NetworkPolicy オブジェクトをサポートするクラスターネットワークプロバイダーを使用している (例: mode: NetworkPolicy が設定された OpenShift SDN ネットワークプロバイダー)。このモードは OpenShiftSDN のデフォルトです。
  • OpenShift CLI (oc) がインストールされている。
  • admin 権限を持つユーザーとしてクラスターにログインしている。

手順

  1. 以下の NetworkPolicy オブジェクトを作成します。

    1. allow-from-openshift-ingress という名前のポリシー:

      $ cat << EOF| oc create -f -
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-openshift-ingress
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                policy-group.network.openshift.io/ingress: ""
        podSelector: {}
        policyTypes:
        - Ingress
      EOF
      注記

      policy-group.network.openshift.io/ingress: ""は、OpenShift SDN の推奨の namespace セレクターラベルです。network.openshift.io/policy-group: ingress namespace セレクターラベルを使用できますが、これはレガシーラベルです。

    2. allow-from-openshift-monitoring という名前のポリシー。

      $ cat << EOF| oc create -f -
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-openshift-monitoring
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                network.openshift.io/policy-group: monitoring
        podSelector: {}
        policyTypes:
        - Ingress
      EOF
    3. allow-same-namespace という名前のポリシー:

      $ cat << EOF| oc create -f -
      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: allow-same-namespace
      spec:
        podSelector:
        ingress:
        - from:
          - podSelector: {}
      EOF
    4. allow-from-kube-apiserver-operator という名前のポリシー:

      $ cat << EOF| oc create -f -
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-kube-apiserver-operator
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: openshift-kube-apiserver-operator
            podSelector:
              matchLabels:
                app: kube-apiserver-operator
        policyTypes:
        - Ingress
      EOF

      詳細は、新規の New kube-apiserver-operator webhook controller validating health of webhook を参照してください。

  2. オプション: 以下のコマンドを実行し、ネットワークポリシーオブジェクトが現在のプロジェクトに存在することを確認します。

    $ oc describe networkpolicy

    出力例

    Name:         allow-from-openshift-ingress
    Namespace:    example1
    Created on:   2020-06-09 00:28:17 -0400 EDT
    Labels:       <none>
    Annotations:  <none>
    Spec:
      PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
      Allowing ingress traffic:
        To Port: <any> (traffic allowed to all ports)
        From:
          NamespaceSelector: network.openshift.io/policy-group: ingress
      Not affecting egress traffic
      Policy Types: Ingress
    
    
    Name:         allow-from-openshift-monitoring
    Namespace:    example1
    Created on:   2020-06-09 00:29:57 -0400 EDT
    Labels:       <none>
    Annotations:  <none>
    Spec:
      PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
      Allowing ingress traffic:
        To Port: <any> (traffic allowed to all ports)
        From:
          NamespaceSelector: network.openshift.io/policy-group: monitoring
      Not affecting egress traffic
      Policy Types: Ingress

7.6.5. 新規プロジェクトのデフォルトネットワークポリシーの作成

クラスター管理者は、新規プロジェクトの作成時に NetworkPolicy オブジェクトを自動的に含めるように新規プロジェクトテンプレートを変更できます。

7.6.6. 新規プロジェクトのテンプレートの変更

クラスター管理者は、デフォルトのプロジェクトテンプレートを変更し、新規プロジェクトをカスタム要件に基づいて作成することができます。

独自のカスタムプロジェクトテンプレートを作成するには、以下を実行します。

手順

  1. cluster-admin 権限を持つユーザーとしてログインしている。
  2. デフォルトのプロジェクトテンプレートを生成します。

    $ oc adm create-bootstrap-project-template -o yaml > template.yaml
  3. オブジェクトを追加するか、既存オブジェクトを変更することにより、テキストエディターで生成される template.yaml ファイルを変更します。
  4. プロジェクトテンプレートは、openshift-config namespace に作成される必要があります。変更したテンプレートを読み込みます。

    $ oc create -f template.yaml -n openshift-config
  5. Web コンソールまたは CLI を使用し、プロジェクト設定リソースを編集します。

    • Web コンソールの使用

      1. AdministrationCluster Settings ページに移動します。
      2. Configuration をクリックし、すべての設定リソースを表示します。
      3. Project のエントリーを見つけ、Edit YAML をクリックします。
    • CLI の使用

      1. project.config.openshift.io/cluster リソースを編集します。

        $ oc edit project.config.openshift.io/cluster
  6. spec セクションを、projectRequestTemplate および name パラメーターを組み込むように更新し、アップロードされたプロジェクトテンプレートの名前を設定します。デフォルト名は project-request です。

    カスタムプロジェクトテンプレートを含むプロジェクト設定リソース

    apiVersion: config.openshift.io/v1
    kind: Project
    metadata:
      ...
    spec:
      projectRequestTemplate:
        name: <template_name>

  7. 変更を保存した後、変更が正常に適用されたことを確認するために、新しいプロジェクトを作成します。

7.6.6.1. 新規プロジェクトへのネットワークポリシーの追加

クラスター管理者は、ネットワークポリシーを新規プロジェクトのデフォルトテンプレートに追加できます。OpenShift Container Platform は、プロジェクトのテンプレートに指定されたすべての NetworkPolicy オブジェクトを自動的に作成します。

前提条件

  • クラスターは、NetworkPolicy オブジェクトをサポートするデフォルトの CNI ネットワークプロバイダーを使用している (例: mode: NetworkPolicy が設定された OpenShift SDN ネットワークプロバイダー)。このモードは OpenShiftSDN のデフォルトです。
  • OpenShift CLI (oc) がインストールされている。
  • cluster-admin 権限を持つユーザーとしてクラスターにログインする。
  • 新規プロジェクトのカスタムデフォルトプロジェクトテンプレートを作成している。

手順

  1. 以下のコマンドを実行して、新規プロジェクトのデフォルトテンプレートを編集します。

    $ oc edit template <project_template> -n openshift-config

    <project_template> を、クラスターに設定したデフォルトテンプレートの名前に置き換えます。デフォルトのテンプレート名は project-request です。

  2. テンプレートでは、各 NetworkPolicy オブジェクトを要素として objects パラメーターに追加します。objects パラメーターは、1 つ以上のオブジェクトのコレクションを受け入れます。

    以下の例では、objects パラメーターのコレクションにいくつかの NetworkPolicy オブジェクトが含まれます。

    objects:
    - apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-same-namespace
      spec:
        podSelector: {}
        ingress:
        - from:
          - podSelector: {}
    - apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-openshift-ingress
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                network.openshift.io/policy-group: ingress
        podSelector: {}
        policyTypes:
        - Ingress
    - apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-kube-apiserver-operator
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: openshift-kube-apiserver-operator
            podSelector:
              matchLabels:
                app: kube-apiserver-operator
        policyTypes:
        - Ingress
    ...
  3. オプション: 以下のコマンドを実行して、新規プロジェクトを作成し、ネットワークポリシーオブジェクトが正常に作成されることを確認します。

    1. 新規プロジェクトを作成します。

      $ oc new-project <project> 1
      1
      <project> を、作成しているプロジェクトの名前に置き換えます。
    2. 新規プロジェクトテンプレートのネットワークポリシーオブジェクトが新規プロジェクトに存在することを確認します。

      $ oc get networkpolicy
      NAME                           POD-SELECTOR   AGE
      allow-from-openshift-ingress   <none>         7s
      allow-from-same-namespace      <none>         7s