KubernetesのNetworkPolicy Resource

(2018-07-30)

Network Policies - Kubernetes

PodのトラフィックをラベルやIPアドレスで許可するためのResource。AWSのセキュリティグループやGCPのファイアウォールルールのようなもの。 GKEでは今のところデフォルトでオフになっているので--enable-network-policyを付けてクラスタを作成する必要がある。

以前作成したmulti podのアプリケーションで挙動を確認する。

GKEでのService(ClusterIP/NodePort/LoadBalancer)とIngress - sambaiz-net

$ kubectl get service
NAME               TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
clusterip-app      ClusterIP      10.23.247.54    <none>           80/TCP         48m
loadbalancer-app   LoadBalancer   10.23.244.137   35.224.130.196   80:31508/TCP   48m
nodeport-app       NodePort       10.23.246.215   <none>           80:32181/TCP   48m
...

$ curl -d '{"url": "http://nodeport-app"}' http://35.224.130.196/
200

作成するNetworkPolicyは以下の二つで、いずれも対象はapp: nodeport-appのラベルが付いたPod。 一つ目は対象Podへのリクエストを一旦全て拒否する。 二つ目はnodeport-access: "true"のラベルが付いたPodから対象Podへの8080ポートのリクエストを許可するもの。 今回は設定しないがegressも設定できる。

$ cat networkPolicies.yaml 
---
# Default deny all ingress traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector:
    matchLabels:
      app: nodeport-app
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
spec:
  podSelector:
    matchLabels:
      app: nodeport-app
  ingress:
  - from:
    - podSelector:
        matchLabels:
          nodeport-access: "true"
    ports:
    - port: 8080

$ kubectl apply -f networkPolicies.yaml 
$ kubectl get networkpolicy
NAME                  POD-SELECTOR       AGE
default-deny          app=nodeport-app   5s
test-network-policy   app=nodeport-app   5s

作成後、ラベルが付いていないPodからアクセスできなくなり、ラベルを付けるとアクセスできるようになった。

$ curl -d '{"url": "http://nodeport-app"}' http://35.224.130.196/
Get http://nodeport-app: dial tcp 10.23.246.215:80: i/o timeout

$ kubectl label pods loadbalancer-app-6bd554874-**** nodeport-access=true
$ curl -d '{"url": "http://nodeport-app"}' http://35.224.130.196/
200

fromにはipBlockやnamespaceSelectorも設定することもでき、複数指定した場合はいずれかの条件を満たすと通る。

$ kubectl delete pod loadbalancer-app-***
$  curl -d '{"url": "http://nodeport-app"}' http://35.224.130.196/
Get http://nodeport-app: dial tcp 10.23.246.215:80: i/o timeout

$ kubectl label namespaces default aaa=bbb
$ cat networkPolicies.yaml 
...
- from:
    - podSelector:
        matchLabels:
          nodeport-access: "true"
    - namespaceSelector:
        matchLabels:
          aaa: bbb
...

$ kubectl apply -f networkPolicies.yaml 
$ curl -d '{"url": "http://nodeport-app"}' http://35.224.130.196/
200