kubestronautへの道 ~CKS編 その19 killer coda「NetworkPolicy」~

tech article

今日覚えて帰ること

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 Namespace app .

It should still allow DNS traffic on port 53 TCP and UDP.

app という namespace に存在する pod からは TCP/UDP の53番ポート以外のアウトバウンド通信を制限せよ、と言っています。

ということで、networkpolicy を作成していきます。
以下のページを参考にします。

ネットワークポリシー
IPアドレスまたはポートのレベル(OSI参照モデルのレイヤー3または4)でトラフィックフローを制御したい場合、クラスター内の特定のアプリケーションにKubernetesのネットワークポリシーを使用することを検討してください。ネットワークポリシーはアプリケーション中心の構造であり、Podがネットワークを介して多様な「エン...

上記のページの「デフォルトで外向きのすべてのトラフィックを拒否する」という箇所を参考にします。

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 Namespace default 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 and space2 .

We need a new NetworkPolicy named np that restricts all Pods in Namespace space1 to only have outgoing traffic to Pods in Namespace space2 . Incoming traffic not affected.

We also need a new NetworkPolicy named np that restricts all Pods in Namespace space2 to only have incoming traffic from Pods in Namespace space1 . 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 になったくらいなので特に解説はありません。

タイトルとURLをコピーしました