IBM Cloud Docs
Kubernetes ポリシーを使用したポッド間のトラフィックの制御

Kubernetes ポリシーを使用したポッド間のトラフィックの制御

Virtual Private Cloud

Kubernetes ポリシーを使用すると、クラスター内のポッド間のネットワーク・トラフィックを制御すること、また、1 つの名前空間または複数の名前空間でアプリのマイクロサービスを互いから分離することができます。

アプリケーションのレベル: ワーカー・ノードのホスト・エンドポイント

デフォルトの動作: Kubernetes ネットワーク・ポリシーは、デフォルトでクラスター内に存在しません。 デフォルトでは、すべてのポッドに、クラスター内の他のすべてのポッドへのアクセス権限があります。 さらに、ポッドは、ポッド・ネットワークによって公開されるサービス (メトリック・サービス、クラスター DNS、API サーバー、クラスター内で手動で作成するサービスなど) にアクセスできます。

ユース・ケース: Kubernetes ネットワーク・ポリシーにより、ポッドが他のポッドおよび外部エンドポイントと通信する方法を指定します。 着信ネットワーク・トラフィックと発信ネットワーク・トラフィックの両方を、プロトコル、ポート、およびソースまたは宛先 IP アドレスに基づいて許可またはブロックできます。 トラフィックは、ポッドおよび名前空間ラベルに基づいてフィルタリングすることもできます。 Kubernetes ネットワーク・ポリシーは、適用されると自動的に Calico ネットワーク・ポリシーに変換されます。 クラスター内の Calico ネットワーク・プラグインは、ワーカー・ノード上に Linux Iptables 規則をセットアップすることによって、これらのポリシーを適用します。 iptables 規則はワーカー・ノードのファイアウォールとして機能し、ネットワーク・トラフィックがターゲット・リソースに転送されるために満たさなければならない特性を定義します。

ほとんどまたはすべてのポッドが特定のポッドまたはサービスにアクセスする必要がなく、かつそれらのポッドまたはサービスにデフォルトでポッドがアクセスできないようにする場合は、Kubernetes ネットワーク・ポリシーを作成して、それらのポッドまたはサービスへの Ingress トラフィックをブロックできます。 例えば、すべてのポッドは CoreDNS ポッド上のメトリック・エンドポイントにアクセスできるようになっています。 不必要なアクセスをブロックするために、以下のようなポリシーを適用できます。まず、TCP と UDP のポート 53 へのすべての Ingress を許可して、ポッドが CoreDNS 機能にアクセスできるようにします。 ただし、他のすべての Ingress では CoreDNS ポッドからメトリックを収集する試みなどをブロックし、例外として、coredns-metrics-policy: allow ラベルの付いた名前空間にあるポッドやサービス、または kube-system ラベルの付いた coredns-metrics-policy: allow 名前空間にあるポッドからの要求を許可します。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: coredns-metrics
  namespace: kube-system
spec:
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          coredns-metrics-policy: allow
    - podSelector:
        matchLabels:
          coredns-metrics-policy: allow
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP
  podSelector:
    matchLabels:
      k8s-app: kube-dns
  policyTypes:
  - Ingress

Kubernetes ネットワークポリシーがポッド間のトラフィックをどのように制御するか、またポリシーの例についての詳細は 、 Kubernetes のドキュメントを参照してください。

1 つの名前空間でのアプリ・サービスの分離

以下のシナリオでは、1 つの名前空間でアプリのマイクロサービス間のトラフィックを管理する方法を説明します。

Accounts チームは、1 つの名前空間に複数のアプリ・サービスをデプロイしますが、パブリック・ネットワークによるマイクロサービス間の通信を、必要なものだけに制限するために分離を必要としています。 アプリ Srv1 については、チームにはフロントエンド・サービス、バックエンド・サービス、データベース・サービスがあります。 それぞれのサービスに app: Srv1 というラベルと tier: frontendtier: backendtier: db というラベルを付けています。

ネットワークポリシーを使用して、名前空間をまたいだトラフィックを管理します。
Use a network policy to manage namespace traffic

Accounts チームは、フロントエンドからバックエンド、およびバックエンドからデータベースへのトラフィックを許可する必要があります。 そこで、ネットワーク・ポリシーでラベルを使用し、マイクロサービス間でどのトラフィック・フローを許可するかを指定することにしました。

まずは、フロントエンドからバックエンドへのトラフィックを許可する Kubernetes ネットワーク・ポリシーを作成します。

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: backend-allow
spec:
  podSelector:
    matchLabels:
      app: Srv1
      tier: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: Srv1
          Tier: frontend

spec.podSelector.matchLabels セクションには、Srv1 バックエンド・サービスのラベルがリストされるため、このポリシーはそれらのポッド_に_のみ適用されます。 spec.ingress.from.podSelector.matchLabels セクションには、Srv1 フロントエンド・サービスのラベルがリストされるため、それらのポッド_から_の Ingress のみが許可されます。

次に、バックエンドからデータベースへのトラフィックを許可する同じような Kubernetes ネットワーク・ポリシーを作成します。

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: db-allow
spec:
  podSelector:
    matchLabels:
      app: Srv1
      tier: db
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: Srv1
          Tier: backend

spec.podSelector.matchLabels セクションには、 Srv1 データベース・サービスのラベルがリストされるため、このポリシーはそれらのポッド_に_ のみ適用されます。 spec.ingress.from.podSelector.matchLabels セクションには、Srv1 バックエンド・サービスのラベルがリストされるため、それらのポッド_から_の Ingress のみが許可されます。

これで、フロントエンドからバックエンドと、バックエンドからデータベースにトラフィックが流れるようになりました。 データベースはバックエンドに、バックエンドはフロントエンドに応答できますが、逆のトラフィック接続を確立することはできません。

複数の名前空間でのアプリ・サービスの分離

以下のシナリオでは、複数の名前空間でアプリのマイクロサービス間のトラフィックを管理する方法を説明します。

異なるサブチームが所有するサービスはコミュニケーションを取る必要があるが、サービスは同一のクラスタ内で異なるネームスペースに展開されている。 Accounts チームは、アプリ Srv1 のフロントエンド・サービス、バックエンド・サービス、データベース・サービスを accounts 名前空間にデプロイします。 Finance チームは、アプリ Srv2 のフロントエンド・サービス、バックエンド・サービス、データベース・サービスを finance 名前空間にデプロイします。 両方のチームは、それぞれのサービスに app: Srv1 または app: Srv2 というラベルと tier: frontendtier: backendtier: db というラベルを付けます。 また、名前空間に usage: accounts または usage: finance というラベルを付けます。

ネットワークポリシーを使用して、名前空間をまたいだトラフィックを管理します。
Use a network policy to manage cross-namespace traffic

Finance チームの Srv2 は、Accounts チームの Srv1 のバックエンドの情報を必要とします。 そのため、Accounts チームは、ラベルを使用して、finance 名前空間から accounts 名前空間の Srv1 バックエンドへのすべてのトラフィックを許可する Kubernetes ネットワーク・ポリシーを作成します。 また、ポート 3111 を指定して、そのポートを使用するアクセスのみを分離します。

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  Namespace: accounts
  name: accounts-allow
spec:
  podSelector:
    matchLabels:
      app: Srv1
      Tier: backend
  ingress:
  - from:
    - NamespaceSelector:
        matchLabels:
          usage: finance
      ports:
        port: 3111

spec.podSelector.matchLabels セクションには、Srv1 バックエンド・サービスのラベルがリストされるため、このポリシーはそれらのポッド_に_のみ適用されます。 spec.ingress.from.NamespaceSelector.matchLabels セクションには finance 名前空間のラベルがリストされ、その名前空間 _から_の Ingress のみが許可されます。

これで、finance マイクロサービスから accounts の Srv1 バックエンドにトラフィックが流れるようになりました。 accounts の Srv1 バックエンドは、finance マイクロサービスに応答できますが、逆のトラフィック接続を確立することはできません。

この例では、finance 名前空間のすべてのマイクロサービスからのトラフィックがすべて許可されます。 podSelectornamespaceSelector を組み合わせることはできないため、別の名前空間の特定のアプリ・ポッドからのトラフィックを許可することはできません。

バージョン 1.28 以降で稼働するクラスターを持つ VPC に必要なポリシー・ルール

バージョン1.27以前では、VPC クラスターはContainer Registryのプライベート・クラウド・サービス・エンドポイントを通じてIBM Cloud Container Registryからイメージを取得します。 バージョン1.28以降では、このネットワークパスが更新され、イメージはプライベートサービスのエンドポイントではなく、VPEゲートウェイを経由するようになりました。 この変更は、VPC内のすべてのクラスタに影響します。VPC内の1つのクラスタをバージョン1.28に作成または更新すると、そのVPC内のすべてのクラスタは、バージョンやタイプに関係なく、ネットワークパスが更新されます。 詳しくは、 VPC クラスターのネットワーキングの変更 を参照してください。

VPC 内にバージョン 1.28 以降を実行するクラスターがあり、 Calico ポリシーを使用してクラスター・ワーカーからのアウトバウンド接続を制限する場合は、以下のポリシー・ルールを追加して、レジストリー用の VPE ゲートウェイへの接続を許可する必要があります。 このポリシーは、VPC 内のゾーンごとに作成する必要があり、ゾーンの VPC アドレス接頭部範囲全体を宛先 CIDR として指定する必要があります。 VPC 内の各ゾーンの VPC アドレス接頭部の範囲を見つけるには、 ibmcloud is vpc-address-prefixes <vpc_name_or_id> を実行します。

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-vpe-gateway-registry
spec:
  egress:
  - action: Allow
    destination:
      nets:
      - <entire-vpc-address-prefix-range> # example: 10.245.0.0/16
      ports:
      - 443
      - 4443
    protocol: TCP
    source: {}
  order: 500
  selector: ibm.role == 'worker_private'
  types:
  - Egress