Kubernetes ポリシーを使用したポッド間のトラフィックの制御
仮想プライベートクラウド
Kubernetes ポリシーを使用すると、クラスター内のポッド間のネットワーク・トラフィックを制御すること、また、1 つの名前空間または複数の名前空間でアプリのマイクロサービスを互いから分離することができます。
アプリケーションのレベル: ワーカー・ノードのホスト・エンドポイント
デフォルトの動作: Kubernetes ネットワーク・ポリシーは、デフォルトでクラスター内に存在しません。 デフォルトでは、すべてのポッドに、クラスター内の他のすべてのポッドへのアクセス権限があります。 さらに、ポッドは、ポッド・ネットワークによって公開されるサービス (メトリック・サービス、クラスター DNS、API サーバー、クラスター内で手動で作成するサービスなど) にアクセスできます。
ユース・ケース: Kubernetes ネットワーク・ポリシーにより、ポッドが他のポッドおよび外部エンドポイントと通信する方法を指定します。 着信ネットワーク・トラフィックと発信ネットワーク・トラフィックの両方を、プロトコル、ポート、およびソースまたは宛先 IP アドレスに基づいて許可またはブロックできます。 トラフィックは、ポッドおよび名前空間ラベルに基づいてフィルタリングすることもできます。 Kubernetes ネットワーク・ポリシーは、適用されると自動的に Calico ネットワーク・ポリシーに変換されます。 クラスター内の Calico ネットワーク・プラグインは、ワーカー・ノード上に Linux Iptables 規則をセットアップすることによって、これらのポリシーを適用します。 iptables 規則はワーカー・ノードのファイアウォールとして機能し、ネットワーク・トラフィックがターゲット・リソースに転送されるために満たさなければならない特性を定義します。
ほとんどまたはすべてのポッドが特定のポッドまたはサービスにアクセスする必要がなく、かつそれらのポッドまたはサービスにデフォルトでポッドがアクセスできないようにする場合は、Kubernetes ネットワーク・ポリシーを作成して、それらのポッドまたはサービスへの Ingress トラフィックをブロックできます。
ネットワークポリシーがポッド間 Kubernetes トラフィックを制御する方法の詳細や、その他のポリシー例については、 ドキュメント Kubernetes を参照してください。
1 つの名前空間でのアプリ・サービスの分離
以下のシナリオでは、1 つの名前空間でアプリのマイクロサービス間のトラフィックを管理する方法を説明します。
Accounts チームは、1 つの名前空間に複数のアプリ・サービスをデプロイしますが、パブリック・ネットワークによるマイクロサービス間の通信を、必要なものだけに制限するために分離を必要としています。 アプリ Srv1 については、チームにはフロントエンド・サービス、バックエンド・サービス、データベース・サービスがあります。 それぞれのサービスに app: Srv1 というラベルと tier: frontend、tier: backend、tier: db というラベルを付けています。
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: frontend、tier: backend、tier: db というラベルを付けます。 また、名前空間に usage: accounts または usage: finance というラベルを付けます。
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 名前空間のすべてのマイクロサービスからのトラフィックがすべて許可されます。 podSelector と namespaceSelector を組み合わせることはできないため、別の名前空間の特定のアプリ・ポッドからのトラフィックを許可することはできません。