🐒
k8sのNetworkPolicyについて入門する
KubernetesのNetwork Policyを初めて使いたい人向けの入門記事です。
NetworkPolicyとは?
- Podに対して、Pod間の通信や外部のエンドポイントへの通信を制御する為のリソース
- labelを用いてPodを選択し、選択されたPodのtrafficのruleを設定する
- podSelectorの指定を空にすることでNetworkPolicyが属するNamespace上の全てのPodを対象にできる
- Namespace単位でtrafficの制御ができる
- podSelectorの指定を空にすることでNetworkPolicyが属するNamespace上の全てのPodを対象にできる
EKSにおけるNetworkPolicy
- CalicoをインストールすることでNetworkPolicyが使えるようになる
- Fargateではサポートされない
Calico
Ref:https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/calico.html
-
Calicoをインストールする為にapplyするマニフェスト
-
kube-system
namespaceにDaemonSetが生成される
-
k apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/release-1.5/config/v1.5/calico.yaml
k get daemonset calico-node --namespace kube-system
k get daemonset calico-node --namespace kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
calico-node 2 2 2 2 2 beta.kubernetes.io/os=linux 41s
- 使ってみるだけならこれだけで完了
NetworkPolicyを検証してみる
構成
- layer1,2,3の3種類のnamespaceを作成する
- nginx/busyboxのDeploymentとServiceを作成する
- 浅いlayerから深いlayerへの通信はできるが、その逆はできないようにNetworkPolicyを設定
NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np-layer1
namespace: layer1
spec:
# podSelecorに空の指定をすることで、NetworkPolicyが存在するnamespace内の全てのPodを対象とする
podSelector: {}
policyTypes:
- Ingress
- Egress
# namespace内の通信を許可する為に、layer1 namespaceからのtrafficをallow
ingress:
- from:
# layer1からのtraficをallow
- namespaceSelector:
matchLabels:
role: layer1
# egressに空の指定をすることで全てのtrafficをallow
egress:
- {}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np-layer2
namespace: layer2
spec:
# podSelecorに空の指定をすることで、NetworkPolicyが存在するnamespace内の全てのPodを対象とする
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
# layer1からのtraficをallow
- namespaceSelector:
matchExpressions:
- key: role
operator: In
values: [layer1,layer2]
# layer3へのtrafficをallow
egress:
- {}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np-layer3
namespace: layer3
spec:
# podSelecorに空の指定をすることで、NetworkPolicyが存在するnamespace内の全てのPodを対象とする
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
# layer1,2からのtraficをallow
- namespaceSelector:
matchExpressions:
- key: role
operator: In
values: [layer1,layer2]
# egressを指定しないことで、全てのtrafficをdeny
動作検証
wget --server-response http://nginx1.layer1 -q -O -
- layer1 -> layer1,2,3
wget --server-response http://nginx1.layer1 -q -O -
HTTP/1.1 200 OK
Server: nginx/1.17.9
wget --server-response http://nginx2.layer2 -q -O -
HTTP/1.1 200 OK
Server: nginx/1.17.9
wget --server-response http://nginx3.layer3 -q -O -
HTTP/1.1 200 OK
Server: nginx/1.17.9
- layer2 -> layer1,2,3
wget --server-response http://nginx1.layer1 -q -O -
# NG
wget --server-response http://nginx2.layer2 -q -O -
HTTP/1.1 200 OK
Server: nginx/1.17.9
wget --server-response http://nginx3.layer3 -q -O -
HTTP/1.1 200 OK
Server: nginx/1.17.9
- layer3-> layer1,2,3
wget --server-response http://nginx1.layer1 -q -O -
# NG
wget --server-response http://nginx2.layer2 -q -O -
HTTP/1.1 200 OK
Server: nginx/1.17.9
wget --server-response http://nginx3.layer3 -q -O -
HTTP/1.1 200 OK
Server: nginx/1.17.9
気づき
- calicoをinstallするだけならまぁ簡単
- Kubernetes Networkingの理解、manifestの理解、運用(calicoのmonitoringや障害時の対応など)、テストなどが必要
- egress厳密に絞るとkube-systemへの疎通ができなくなり名前解決ができなくなるよう
- egressまで厳密に絞るのは困難(ipで指定すると外部に出ることができなくなる)
- RDS/ElastiCacheなどCluster外へのアクセス制御ができない(IPアドレスでの指定になってしまう、どれだけ絞ってもサブネット単位での制御になる。NLBにSG付与できない問題と似ている)
- やはりSG per Podが求められる
Discussion