ポッドネットワークポリシーによるKubernetesクラスターのトラフィックのセキュリティ確保
Kubernetesのポッドはデフォルトで自由に互いに通信できます。これは、クラスターが複数のアプリケーションやチームで使用される場合、セキュリティリスクをもたらします。一つのポッドでの誤った動作や悪意のあるアクセスが、クラスター内の他のポッドへのトラフィックを誘導する可能性があります。
この記事では、ネットワークポリシーを設定することによって、このシナリオを回避する方法を教えます。これらのルールにより、IPアドレスレベル(OSI層3または4)でPod間のトラフィックフローを制御できます。各Podに許可されるインバウンドおよびアウトバウンドのソースを正確に定義できます。
ネットワークポリシーの作成
ネットワークポリシーは追加することによって作成されます
NetworkPolicyクラスターへのオブジェクト。各ポリシーは、それが適用されるポッドと1つ以上のインバウンドおよびアウトバウンドルールを定義します。基本的なポリシーのマニフェストは次のとおりです:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy
namespace: app
spec:
podSelector:
matchLabels:
component: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
component: api
egress:
- to:
- podSelector:
matchLabels:
component: api
このネットワークポリシーは、component: database ラベルを持つ任意の Pod に適用されます。
app名前空間。これは、Ingress(受信)およびEgress(送信)トラフィックがポッドに対してのみ許可されることを示しています。
component: apiラベル。別のポッドから発生するリクエスト、例えば
component: web-frontendブロックされます。
ネットワークポリシーは、Kubectlを使用して他のオブジェクトと同様に適用できます。作成後すぐに効果を発揮します。選択したポッドを開始する前に、ネットワークポリシーを追加できます。
kubectl apply -f policy.yaml
networkingpolicy.networking.k8s.io/network-policy created
ネットワークポリシーの仕組み
ネットワークポリシーは、クラスターのアクティブなネットワークプラグインによって実装されます。プラグインがその機能をサポートしていない場合、ポリシーは効果を持ちません。CalicoやCiliumなどの人気のあるオプションは、ネットワークポリシーサポートが有効な状態で提供されています。
ネットワークポリシーがPodに適用されると、プラグインはそのトラフィックを検査して、ポリシーの要件に準拠しているかどうかを確認します。基準を満たさない接続は許可されません。接続を試みたPodは、リモートホストに到達できないことがわかります。これは、出口ルールによってブロックされたリソースにアクセスしようとしたためか、リモートPodが入口ルールを使用して受信接続を拒否したためです。
2つのポッド間の成功した接続は、両方のネットワークポリシーがそれを許可する場合にのみ確立されます。接続は、発信元ポッドのエグレスルールや、ターゲットのインバウンドルールによって禁止される可能性があります。
ネットワークポリシーは常に加算的な性質を持っています。複数のポリシーが同じPodを選択する場合、許可されるingressおよびegressのソースのリストは、すべてのポリシーの組み合わせになります。
例ネットワークポリシー
ネットワークポリシーは、対象となるポッドのカスタマイズや許可される接続の種類に関して、多くの異なるオプションをサポートしています。以下の例は、いくつかの一般的なユースケースを示しています。
名前空間内のすべてのPodにポリシーを適用し、特定のIPアドレスブロックからのIngressトラフィックのみを許可します。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy
namespace: app
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
空のpodSelectorブロックは、すべての名前空間のPodがポリシーの対象であることを意味します。ipBlockルールは、指定された範囲内のIPアドレスを持つPodへの着信トラフィックを制限します。出信トラフィックはブロックされません。
IPアドレスブロックからのインバウンドトラフィックを許可しますが、特定のIPを除外します。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy
namespace: app
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.0.1/24
- 172.17.0.2/24
- 172.17.0.3/24
ipBlock ルールは、特定の IP から発信される、または特定の IP へ向けられるトラフィックを除外するための except フィールドをサポートしています。
名前空間内のすべてのポッドからのIngressトラフィックを許可しますが、特定のポートからのみです。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy
namespace: app
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
ports:
- protocol: TCP
port: 443
portsフィールドは、インバウンドおよびアウトバウンドのルールで使用可能です。これは、トラフィックが受信または送信されるポートを定義します。任意で、endPortフィールド(3500)を設定することで、3000 - 3500のようにポートの範囲を指定することができます。port(3000)に加えて指定します。
異なる名前空間に存在する特定のラベルを持つポッドからのトラフィックを許可する
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy
namespace: database
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
application: demo-app
podSelector:
matchLabels:
component: database
ポリシーでは、demo-appというラベルが付けられた自分のネームスペースを持つ場合、component: databaseとラベル付けされた任意のポッドがdatabaseネームスペース内のすべてのポッドにアクセスできると述べられています。
外部ネームスペース内のすべてのポッドからのトラフィックを許可するには、namespaceSelector フィールドのみを含むルールを作成します。
すべてのトラフィックを明示的に許可する
時々、特定のタイプのすべてのトラフィックを名前空間内で明示的に許可したい場合があります。ポリシーにそのタイプを含めますが、空のPodセレクターとルールを提供します。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy
namespace: app
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- {}
egress:
- {}
名前空間内のすべてのポッドは、ポリシーが存在しないかのように自由に通信できます。それでもポリシーを作成することは、他のクラスターユーザーに対して自分の意図を示すことができます。彼らは、他の部分がセキュリティで保護されているクラスター内で制限のないネットワークを持つ名前空間の存在について疑問を持つかもしれません。
ネットワークポリシーを使用する時
ネットワークポリシーは、クラスター内の各ネームスペースとポッドに対して作成する必要があります。これにより、ポッドがよりよく隔離され、トラフィックフローを制御できるようになります。
ポリシーをできるだけ詳細にするようにしてください。名前空間内のすべてのポッド間でのアクセスを許可するなど、アクセスを広げすぎると、コンテナの一つが侵害された場合にリスクにさらされます。認証サービス、データベース、決済処理者などのセンシティブなポッドのために、個別のイングレスおよびイングレスリモートを特定するために、正確なセレクターの使用を検討してください。
Kubernetesはデフォルトでネットワークポリシーを有効にしないため、すべてのPodがポリシーで保護されることを意図していても、見落としが発生する可能性があります。このリスクを軽減するために、名前空間にキャッチオールポリシーを追加することができます。このポリシーは、名前空間内のすべてのPodを選択し、すべてのネットワーク通信を禁止するルールを適用します。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: app
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ネットワークポリシーは常に名前空間にスコープされるため、それぞれの名前空間ごとに別のキャッチオールを作成する必要があります。
要約
Kubernetesは、クラスタ内のすべてのPodが相互に通信できるようにします。これは、マルチパーパスクラスタで実行される実世界のアプリケーションには過剰な許可です。ネットワークポリシーは、各Podが受け入れるインバウンドソースとアウトバウンドターゲットを管理するためのファイアウォールのようなシステムを提供することで、この問題に対処します。
すべてのPodにネットワークポリシーを設定することは良い習慣です。これにより、クラスタが保護され、正当なトラフィックのみが許可されるようになります。ただし、ネットワークポリシーはKubernetesのセキュリティの一部に過ぎません。他の保護メカニズム、例えばRBACやPodセキュリティコンテキストも、環境を強化するための重要なツールです。
