見出し画像

Kubernetes の NetworkPolicy を活用してラベルでアクセスをさらに細かく制御する方法

Kubernetes を運用していると、「特定の Pod だけデータベースにアクセスできるようにしたい」と思う場面がありますよね。例えば、「backend」という名前の namespace の一部の Pod だけが、「db」という名前の namespace の MySQL に接続できるようにするケースです。

このような細かいアクセス制御を実現するには NetworkPolicy を活用できます。NetworkPolicy を適用すると、対象の Pod に対する通信がデフォルトでブロックされ、明示的に許可した通信のみを受け付ける仕組みになります。
今回は 「backend」という名前の namespace の特定の Pod だけが、「db」という名前の namespace の MySQL にアクセスできるようにする NetworkPolicy の設定方法を紹介します。

また、NetworkPolicy の適用による動作の変化や、デフォルトの Kubernetes の通信挙動 についても触れていきます。


NetworkPolicy を適用するとどうなる?

Kubernetes のデフォルトでは、すべての Pod 間の通信は許可されています。
つまり、NetworkPolicy を適用しなければ、Pod は namespace に関係なく自由に通信できます。

しかし、一度 NetworkPolicy を適用すると、対象の Pod への通信はデフォルトでブロックされ、明示的に許可した通信のみ受け付ける動作になります

今回の設定では、以下の動作を実現します。

許可される通信

  • 「backend」という名前の namespace 内のラベル db: access_ok を持つ Pod からの通信

  • 「db」という名前の namespace 内の MySQL Pod への通信

  • TCP ポート 3306(MySQL のデフォルトポート) のみ

拒否される通信

  • 「backend」という名前の namespace 内でも、ラベル db: access_ok を持たない Pod

  • 他の namespace からの通信

  • ポート 3306 以外の通信


NetworkPolicy の設定例

以下は、「db」という名前の namespace 内の MySQL Pod へのアクセスを制限するための NetworkPolicy の設定例です。

apiVersion: networking.k8s.io/v1  # 使用する API のバージョン
kind: NetworkPolicy  # 作成するリソースの種類(NetworkPolicy)
metadata:
  name: allow-specific-backend-to-db  # NetworkPolicy の名前
  namespace: db  # この NetworkPolicy を適用する namespace(MySQL がある db namespace)

spec:
  podSelector:
    matchLabels:
      app: mysql  # "app=mysql" のラベルを持つ Pod(MySQL Pod)への通信を制御

  policyTypes:
  - Ingress  # 受信(Ingress)通信を制御

  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: backend  # namespace が "backend" の Pod からの通信を許可
      podSelector:
        matchLabels:
          db: access_ok  # "db=access_ok" のラベルを持つ Pod からの通信を許可

    ports:
    - protocol: TCP  # 許可するプロトコル(TCP)
      port: 3306  # 許可するポート(MySQL のデフォルトポート 3306)


NetworkPolicy のルール

この設定によって、以下のルールが適用されます。

(1) 対象の Pod

db」という名前の namespace 内の app: mysql というラベルを持つ Pod(MySQL Pod)に対して、このポリシーが適用されます。

(2) 許可される通信元

アクセスが許可されるのは、以下の条件を満たす Pod からの通信のみです:

  • namespace が「backend」(namespace に name=backend のラベルが必要)

  • ラベル db: access_ok を持つ Pod

(3) 許可されるポート

  • TCP 3306(MySQL のデフォルトポート)のみ

  • それ以外のポートはすべて拒否


設定に必要な前提条件

NetworkPolicy を適用する前に、以下の設定を行う必要があります。

(1) 「backend」という名前の namespace にラベルを付与する

「backend」という名前の namespace にラベルを付与します。

kubectl label namespace backend name=backend

このラベルが、ポリシー内の namespaceSelector の条件として使われます。
デフォルトでは namespace にラベルが設定されていないため、必ずこのコマンドを実行してください。

(2) 「backend」という名前の namespace 内の Pod にラベルを付与する

許可したい Pod に db: access_ok というラベルを付けます。

kubectl label pod <対象のPod名> -n backend db=access_ok

このラベルが、podSelector の条件として使われます。

(3) 「db」という名前の namespace の MySQL Pod にラベルを設定する

MySQL Pod に app: mysql というラベルを設定してください。
もし MySQL を Deployment で管理している場合は、以下のように spec.template.metadata.labels に app: mysql を追加します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: db
spec:
  template:
    metadata:
      labels:
        app: mysql

このラベルが、NetworkPolicy の podSelector によって識別されます。


NetworkPolicy を適用するとどうなる?

NetworkPolicy を適用すると、以下のような動作になります。

許可される通信

  • 「db」という名前の namespace 内の MySQL Pod への通信

  • 「backend」という名前の namespace 内の db: access_ok を持つ Pod からの通信

  • TCP 3306 のみ

拒否される通信

  • 「backend」という名前の namespace 内でも、ラベル db: access_ok を持たない Pod

  • 他の namespace からの通信

  • ポート 3306 以外の通信


まとめ

この NetworkPolicy を活用することで、以下のメリットが得られます。

細かいアクセス制御が可能
namespace だけでなく、Pod のラベルによって、特定の Pod だけにアクセス権を絞り込めます。

NetworkPolicy を適用すると、対象 Pod への通信がデフォルトでブロックされる
明示的に許可された通信のみを受け付けるため、意図しないアクセスを防げます。

MySQL Pod へのアクセスを厳密に制限できる
特定の namespace 内の特定の Pod からのアクセスのみ許可し、それ以外はすべてブロックできます。

Kubernetes クラスタのネットワークセキュリティを強化するために、ぜひ活用してみてください!

いいなと思ったら応援しよう!