【Kubernetes】NetworkPolicyについてざっくり理解して試してみる
はじめに
KubernetesのNetwork Policyについて、ざっくり理解して、実際に動かしてみたいと思います。
NetworkPolicy
NetworkPolicyは、IPアドレスもしくはポートレベルでトラフィックを制御するリソースです。
利用するためには、networkプラグインが必要になります。
トラフィックの制御は下記3つの組み合わせで設定できます。
- Pod
- Namespace
- IPアドレス
これらとポート番号によって、トラフィックを制御します。
マニフェスト
kubectl expalin
でマニフェストの内容を確認してみます。
1❯ kubectl explain netpol --recursive
2KIND: NetworkPolicy
3VERSION: networking.k8s.io/v1
4
5DESCRIPTION:
6 NetworkPolicy describes what network traffic is allowed for a set of Pods
7
8FIELDS:
9 apiVersion <string>
10 kind <string>
11 :
12 :
13 spec <Object>
14 egress <[]Object>
15 ports <[]Object>
16 endPort <integer>
17 port <string>
18 protocol <string>
19 to <[]Object>
20 ipBlock <Object>
21 cidr <string>
22 except <[]string>
23 namespaceSelector <Object>
24 matchExpressions <[]Object>
25 key <string>
26 operator <string>
27 values <[]string>
28 matchLabels <map[string]string>
29 podSelector <Object>
30 matchExpressions <[]Object>
31 key <string>
32 operator <string>
33 values <[]string>
34 matchLabels <map[string]string>
35 ingress <[]Object>
36 from <[]Object>
37 ipBlock <Object>
38 cidr <string>
39 except <[]string>
40 namespaceSelector <Object>
41 matchExpressions <[]Object>
42 key <string>
43 operator <string>
44 values <[]string>
45 matchLabels <map[string]string>
46 podSelector <Object>
47 matchExpressions <[]Object>
48 key <string>
49 operator <string>
50 values <[]string>
51 matchLabels <map[string]string>
52 ports <[]Object>
53 endPort <integer>
54 port <string>
55 protocol <string>
56 podSelector <Object>
57 matchExpressions <[]Object>
58 key <string>
59 operator <string>
60 values <[]string>
61 matchLabels <map[string]string>
62 policyTypes <[]string>
下記はサンプルのNetworkPolicyです。
1apiVersion: networking.k8s.io/v1
2kind: NetworkPolicy
3metadata:
4 name: test-network-policy
5 namespace: default
6spec:
7 podSelector: # NetworkPolicyを適用するPod
8 matchLabels:
9 netpol-myproject: allow
10 policyTypes: # NetworkPolicyが外向きか内向きか
11 - Ingress
12 - Egress
13 ingress: # 内向きのトラフィック(fromとportsに一致するトラフィックを許可)
14 - from:
15 - ipBlock: # IPアドレスでの制御
16 cidr: 192.168.1.0/24
17 except:
18 - 192.168.1.1/32
19 - namespaceSelector: # Namespaceでの制御
20 matchLabels:
21 project: myproject
22 - podSelector: # Podでの制御
23 matchExpressions:
24 - key: role
25 operator: In
26 values: [app]
27 ports:
28 - protocol: TCP
29 port: 8080
30 egress: # 外向きのトラフィック(toとportsに一致するトラフィックを許可)
31 - to:
32 - ipBlock:
33 cidr: 192.168.2.0/24
34 - namespaceSelector: # NamespaceとPodでの制御(書き方に注意)
35 matchLabels:
36 project: yourproject
37 podSelector:
38 matchExpressions:
39 - key: role
40 operator: In
41 values: [app]
42 ports:
43 - protocol: TCP
44 port: 8080
ingressとegressの設定
ingress
とegress
では下記4つのセレクターでトラフィックを制御します。
podSelector
namespaceSelector
podSelector
とnamespaceSelector
ipBlock
podSelector
とnamespaceSelector
の組み合わせのパターンはyamlの書き方に気をつける必要があります。
実際に試してみる
実際にNetworkPolicyを設定して、トラフィックが制御されているのを確認してみたいと思います。
minikubeの準備
下記のコマンドでminikubeを起動して、NetworkPolicyを使えるようにします。
1minikube start --network-plugin=cni --cni=calico
リソースの準備
準備するのは2つのPodと2つのNetworkPolicyです。
1.
2├── to-dns.yml
3├── deny-to-all.yml
4├── pod-allow.yml
5└── pod-deny.yml
- Google Public DNS(
8.8.8.8
)のポート53
へのトラフィックを許可するNetworkPolicy - デフォルトで外向き全てを拒否するNetworkPolicy
- Google Public DNSのポート
53
へのトラフィックを許可するラベルがついたPod - ラベルがついていないPod
8.8.8.8:53
だけに通信できるPod(pod-allow
)と外向きの通信が全て制限されているPod(pod-deny
)を作成して、トラフィックを比較してみます。
to-dns.yml
は下記の通りです。
1apiVersion: networking.k8s.io/v1
2kind: NetworkPolicy
3metadata:
4 name: to-dns
5 namespace: default
6spec:
7 podSelector:
8 matchLabels:
9 to-dns: allow
10 policyTypes:
11 - Egress
12 egress:
13 - to:
14 - ipBlock:
15 cidr: 8.8.8.8/32
16 ports:
17 - protocol: TCP
18 port: 53
deny-to-all.yml
は下記の通りです。
1apiVersion: networking.k8s.io/v1
2kind: NetworkPolicy
3metadata:
4 name: default-deny-egress
5spec:
6 podSelector: {}
7 policyTypes:
8 - Egress
pod-deny.yml
は下記の通りです。
1apiVersion: v1
2kind: Pod
3metadata:
4 name: pod-deny
5spec:
6 containers:
7 - name: net
8 image: dersimn/netutils
9 command:
10 - sleep
11 - "9999"
pod-allow.yml
は下記の通りです。
1apiVersion: v1
2kind: Pod
3metadata:
4 name: pod-allow
5 labels:
6 to-dns: allow
7spec:
8 containers:
9 - name: net
10 image: dersimn/netutils
11 command:
12 - sleep
13 - "9999"
リソースを作成します。
1kubectl apply -f to-dns.yml
2kubectl apply -f deny-to-all.yml
3kubectl apply -f pod-deny.yml
4kubectl apply -f pod-allow.yml
疎通確認
pod-allow
とpod-deny
からそれぞれ疎通確認してみたいと思います。
8.8.8.8
にポート指定で疎通確認してみると、pod-allow
のみ成功していることがわかります。
1❯ kubectl exec pod-allow -- nc -vz 8.8.8.8 53
2Connection to 8.8.8.8 53 port [tcp/domain] succeeded!
3
4❯ kubectl exec pod-deny -- nc -vz 8.8.8.8 53
5nc: connect to 8.8.8.8 port 53 (tcp) failed: Connection timed out
6command terminated with exit code 1
curl
を使ってポート指定しても、pod-deny
はタイムアウトになっています。pod-allow
はEmpty replyになっていますが、8.8.8.8
にはたどり着けているのかと思います。
1❯ kubectl exec pod-allow -- curl -l 8.8.8.8:53
2curl: (52) Empty reply from server
3command terminated with exit code 52
4
5❯ kubectl exec pod-deny -- curl -l 8.8.8.8:53
6curl: (28) Failed to connect to 8.8.8.8 port 53: Connection timed out
7command terminated with exit code 28
ポート指定していないping
で疎通確認すると、どちらもパケットが届いていないことがわかります。
1❯ kubectl exec pod-allow -- ping -c 10 8.8.8.8
2PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
3
4--- 8.8.8.8 ping statistics ---
510 packets transmitted, 0 received, 100% packet loss, time 9281ms
6
7command terminated with exit code 1
8
9❯ kubectl exec pod-deny -- ping -c 10 8.8.8.8
10PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
11
12--- 8.8.8.8 ping statistics ---
1310 packets transmitted, 0 received, 100% packet loss, time 9236ms
14
15command terminated with exit code 1
traceroute
でも、どちらもたどり着けていません。
1❯ kubectl exec pod-allow -- traceroute 8.8.8.8
2traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
3 1 192.168.64.3 (192.168.64.3) 0.114 ms 0.026 ms 0.013 ms
4 2 * * *
5 :
629 * * *
730 * * *
8
9❯ kubectl exec pod-deny -- traceroute 8.8.8.8
10traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
11 1 192.168.64.3 (192.168.64.3) 0.159 ms 0.015 ms 0.015 ms
12 2 * * *
13 :
1429 * * *
1530 * * *
疎通確認については、こちらを参考にしてください。
【Linux】ネットワークのトラブルシューティング手順とコマンドまとめ
:::affiliate-message 本ページはAmazonアフィリエイトのリンクを含みます。
まとめ
- NetworkPolicyでトラフィックの制御ができる
- PodとNamespaceとIPアドレスで制御可能
下記もサンプルとして、NetworkPolicyを理解する助けになります。
GitHub - ahmetb/kubernetes-network-policy-recipes: Example recipes for Kubernetes Network Policies that you can just copy paste
Example recipes for Kubernetes Network Policies that you can just copy paste - ahmetb/kubernetes-network-policy-recipes
参考
- ネットワークポリシー | Kubernetes
- Network Plugins | Kubernetes
- Network Policy | minikube
- Quickstart for Calico on minikube
- ahmetb/kubernetes-network-policy-recipes: Example recipes for Kubernetes Network Policies that you can just copy paste