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