今日覚えて帰ること
NetworkPolicy
- クラスター内部におけるトラフィックを制御するためのリソース
- namespace 単位で作成する
- AND 条件と OR 条件に要注意
NetworkPolicy Create Default Deny
NetworkPolicy Create Default Deny
There are existing Pods in Namespace
app
.We need a new default-deny NetworkPolicy named
deny-out
for all outgoing traffic from Namespaceapp
.It should still allow DNS traffic on port
53
TCP and UDP.
app という namespace に存在する pod からは TCP/UDP の53番ポート以外のアウトバウンド通信を制限せよ、と言っています。
ということで、networkpolicy を作成していきます。
以下のページを参考にします。
上記のページの「デフォルトで外向きのすべてのトラフィックを拒否する」という箇所を参考にします。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
こちらは policyTypes が Egress である通信、つまりアウトバウンド通信についてのルールを設定しています。
どのような通信も許可していないので外向きの全てのトラフィックが拒否される、という結果になります。
networkpolicy を設定しなければ通信は全て許可されるので、インバウンド通信は全て許可されます。
さて、このテンプレートに設定を追加していきます。
追加した箇所は赤文字で記しています。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-out
namespace: app
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
まず、metadata に namespace を指定します。
ここで、この networkpolicy が適用される namespace を指定します。
クラスター全体に適用されるリソースではないことに注意が必要です。
次に、spec.egressを設定していきます。
詳しくは先ほどのリンクに書いています。
重要なのは、各要素が AND 条件なのか OR 条件なのかを理解することです。
yaml の書き方がわかっていれば理解しやすいと思います。
今回で言うと、egress ルールが1つ存在していて、そのルールでは TCP または UDP の53ポートへのアウトバウンド通信が許可されています。
あとはこれを apply すればOKです。
ここまでは準備運動ですね。
NetworkPolicy Metadata Protection
Create a new NP to restrict access to IP
Cloud providers can have Metadata Servers which expose critical information, for example GCP or AWS.
For this task we assume that there is a Metadata Server at
1.1.1.1
.You can test connection to that IP using
nc -v 1.1.1.1 53
.Create a NetworkPolicy named
metadata-server
In Namespacedefault
which restricts all egress traffic to that IP.The NetworkPolicy should only affect Pods with label
trust=nope
.
メタデータサーバへのアクセスを制限する networkpolicy を作れ、と言っています。
networkpolicy を NP と略していますね。
今後 NP と表記します。
先ほどのページからサンプルを取ってきます。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
ここから必要なものだけを取り出したものが以下です。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
これに修正を加えます。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: metadata-server
namespace: default
spec:
podSelector:
matchLabels:
trust: nope
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except: 1.1.1.1/32
ポイントは一番下の egress 周りですね。
特定の IP へのアウトバウンドを拒否したい場合は、except フィールドを使うとよいです。
後はこれを apply すればOKです。
NetworkPolicy Namespace Selector
Create new NPs
There are existing Pods in Namespace
space1
andspace2
.We need a new NetworkPolicy named
np
that restricts all Pods in Namespacespace1
to only have outgoing traffic to Pods in Namespacespace2
. Incoming traffic not affected.We also need a new NetworkPolicy named
np
that restricts all Pods in Namespacespace2
to only have incoming traffic from Pods in Namespacespace1
. Outgoing traffic not affected.The NetworkPolicies should still allow outgoing DNS traffic on port
53
TCP and UDP.
要求がいくつかあります。
- space1からのアウトバウンドはspace2のみ
- space2へのインバウンドはspace1のみ
- ただし、TCP/UDPの53番ポートへは常に許可
という条件でNPをつくれ、と言っています。
NPは namespace 単位で作成するリソースなので、各 namespace に作成します。
やはり公式サイトのサンプルをもとに作成します。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
ここから必要なものだけを取り出し、必要なものを追加します。
まずは space1 のNPです。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np
namespace: space1
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: space2
- ports:
- port: 53
protocol: TCP
- port: 53
protocol: UDP
いくつか解説します。
spec.podSelectorの値の{}は namespace 内のすべての pod に適応されることを意味します。
kubernetes.io/metadata.name: space2 は namespace に付与されているラベルです。
k get ns –show-labels で確認できます。
controlplane $ k get ns --show-labels
NAME STATUS AGE LABELS
default Active 23d kubernetes.io/metadata.name=default
kube-node-lease Active 23d kubernetes.io/metadata.name=kube-node-lease
kube-public Active 23d kubernetes.io/metadata.name=kube-public
kube-system Active 23d kubernetes.io/metadata.name=kube-system
local-path-storage Active 23d kubernetes.io/metadata.name=local-path-storage
space1 Active 13m kubernetes.io/metadata.name=space1
space2 Active 13m kubernetes.io/metadata.name=space2
controlplane $
最大のポイントは、portsの前のハイフンです
これがあることでtoとportsが別の配列であることが示されます。
すなわち、or条件として記載されていることになります。
もしハイフンがない場合はAnd条件、つまり、space2に対してポート53でのみアクセス可能であるというNPとなります。
続いて space2 のNPです。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np
namespace: space2
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: space1
こちらは Engress が Ingress になったくらいなので特に解説はありません。