TT Lab
はじめる
学ぶ 学習パス コース

Kubernetes運用実務

デフォルト拒否から始めるポリシー設計

TT Labで続きを見る

目標

ネームスペースの通信のデフォルトを拒否に覆し、必要な経路だけをラベルで選んで開くポリシーのセットを、自分で書きます。

なぜ重要なのか

NetworkPolicyでいちばん間違えやすいのは、文法ではなく方向と結合の仕方です。ポリシーは、トラフィックを送る側ではなく受け取る側に付きます。webからapiへの通信を許可したいなら、ポリシーのpodSelectorがapiでなければならず、webはingress.fromの中に登場します。また、from配列の項目同士はORで、1つの項目内のnamespaceSelectorとpodSelectorはANDです。ハイフンの位置1つで、「特定のネームスペースの特定のPod」が「そのネームスペースのすべてのPod、またはどこにあってもそのPod」に変わります。そして、エグレスを塞ぐときは、DNSの例外を必ずセットで入れてください。実際の本番環境で、デフォルト拒否だけを先に入れたために名前解決が止まり、サービス全体が連鎖的に停止した事例が繰り返し報告されています。このラボのクラスターはPod間で実際のパケットが流れないので、採点はポリシーオブジェクトの内容とセレクターの意味で行われます。文法と考え方をここで固め、実際の遮断の確認は、CNIのある環境で行えばよいのです。

ステップ

  1. ネームスペースnetpol-labを作成し、/opt/lab/fixtures/k8s/workloads.yamlをその中に適用してください。結果として、web、api、dbの3つのPodがそれぞれ自分の名前と同じappラベルを持ち、apiのPodは追加でtier=backendラベルを持っている必要があります。
  2. netpol-labにNetworkPolicydefault-deny-ingressを作成してください。podSelectorは空のオブジェクト{}で、policyTypesはIngressだけ、ingressルールは1つもあってはいけません。
  3. NetworkPolicyallow-web-to-apiを作成してください。podSelector.matchLabels.appはapi、ingress[0].from[0]はpodSelector.matchLabels.app: webだけを持ちます(同じ項目にnamespaceSelectorを入れないでください)。許可するポートはTCP8080です。
  4. NetworkPolicydefault-deny-egressを作成してください。policyTypesはEgressだけです。続けてallow-dns-egressを作成し、egress[0].to[0].namespaceSelector.matchLabelsにkubernetes.io/metadata.name: kube-systemを書き、egress[0].portsにはポート53をUDPとTCPの2項目として入れてください。
  5. ネームスペースmonitoringを作成し、ラベルpurpose=monitoringを付けてください。そのあと、netpol-labにNetworkPolicyallow-from-monitoringを作成します。podSelector.matchLabels.appはapi、ingress[0].from[0].namespaceSelector.matchLabels.purposeはmonitoring、許可するポートは9090です。
  6. NetworkPolicyallow-office-cidrを作成してください。podSelector.matchLabels.appはwebで、ingress[0].from[0].ipBlock.cidrは10.0.0.0/16、exceptは10.0.5.0/24の1つだけです。
  7. NetworkPolicyapi-fullを作成してください。podSelector.matchLabels.appはapi、policyTypesはIngressとEgressの両方です。ingress[0].fromには項目が2つ以上(例: webのPodとmonitoringネームスペース)入っている必要があり、egress[0].to[0]はpodSelector.matchLabels.app: db、許可するポートは5432です。
  8. /root/ops/netpol/out/policy-map.jsonを作成してください。最上位のキーはweb、api、dbの3つで、各値はそのPodを選ぶポリシー名の配列です。空のセレクターを持つポリシーは3つのPodすべてに入っている必要があり、allow-web-to-apiはapiにだけ入っている必要があります(webやdbに入れてはいけません)。allow-office-cidrはwebに、api-fullはapiに入ります。最終的に、netpol-labのNetworkPolicyは6個以上である必要があります。

参考

ラボ用のネームスペースとラベル付きPodを作成する

ネームスペースnetpol-labを作成し、/opt/lab/fixtures/k8s/workloads.yamlをその中に適用してください。結果として、web、api、dbの3つのPodがそれぞれ自分の名前と同じappラベルを持ち、apiのPodは追加でtier=backendラベルを持っている必要があります。

ポリシーはラベルだけで対象を選びます。フィクスチャに3つのPodが用意されているので、そのまま適用しますが、どのネームスペースに適用するのかを確認してください。

イングレスのデフォルト拒否ポリシーを作成する

netpol-labにNetworkPolicydefault-deny-ingressを作成してください。podSelectorは空のオブジェクト{}で、policyTypesはIngressだけ、ingressルールは1つもあってはいけません。

ネームスペース全体を選ぶセレクターは、空のセレクターです。すべて拒否するとは、許可ルールを1つも書かないことです。

webからapiへのポートだけを開ける

NetworkPolicyallow-web-to-apiを作成してください。podSelector.matchLabels.appはapi、ingress[0].from[0]はpodSelector.matchLabels.app: webだけを持ちます(同じ項目にnamespaceSelectorを入れないでください)。許可するポートはTCP8080です。

ポリシーは送る側ではなく、受け取る側に付きます。同じネームスペースの中なので、相手を選ぶときにネームスペースセレクターを混ぜないでください。

エグレスのデフォルト拒否とDNSの例外

NetworkPolicydefault-deny-egressを作成してください。policyTypesはEgressだけです。続けてallow-dns-egressを作成し、egress[0].to[0].namespaceSelector.matchLabelsにkubernetes.io/metadata.name: kube-systemを書き、egress[0].portsにはポート53をUDPとTCPの2項目として入れてください。

エグレスを塞ぐと、まず名前解決が死にます。DNSはUDPだけでは済まないという点と、対象のネームスペースを選ぶ標準のラベルが何かを確認してください。

別のネームスペースから来るトラフィックを許可する

ネームスペースmonitoringを作成し、ラベルpurpose=monitoringを付けてください。そのあと、netpol-labにNetworkPolicyallow-from-monitoringを作成します。podSelector.matchLabels.appはapi、ingress[0].from[0].namespaceSelector.matchLabels.purposeはmonitoring、許可するポートは9090です。

ネームスペースを選ぶには、そのネームスペースにラベルが実際に付いている必要があります。セレクターが選ぶ対象がなければ、ポリシーは何の意味も持ちません。

IP範囲の許可と例外の指定

NetworkPolicyallow-office-cidrを作成してください。podSelector.matchLabels.appはwebで、ingress[0].from[0].ipBlock.cidrは10.0.0.0/16、exceptは10.0.5.0/24の1つだけです。

ipBlockは、広く開けて狭く除外する形で使います。除外する範囲は、必ず許可する範囲の中に含まれている必要があります。

イングレスとエグレスを1つのポリシーにまとめる

NetworkPolicyapi-fullを作成してください。podSelector.matchLabels.appはapi、policyTypesはIngressとEgressの両方です。ingress[0].fromには項目が2つ以上(例: webのPodとmonitoringネームスペース)入っている必要があり、egress[0].to[0]はpodSelector.matchLabels.app: db、許可するポートは5432です。

from配列の項目同士はORです。2種類の送信元を許可するには、項目を2つに分けてください。出ていく側は、データベースのポートだけが開きます。

Podごとの適用ポリシーのマップを作成する

/root/ops/netpol/out/policy-map.jsonを作成してください。最上位のキーはweb、api、dbの3つで、各値はそのPodを選ぶポリシー名の配列です。空のセレクターを持つポリシーは3つのPodすべてに入っている必要があり、allow-web-to-apiはapiにだけ入っている必要があります(webやdbに入れてはいけません)。allow-office-cidrはwebに、api-fullはapiに入ります。最終的に、netpol-labのNetworkPolicyは6個以上である必要があります。

空のセレクターを持つポリシーは、すべてのPodに適用されます。ポリシーが選ぶのは受け取る側だという点を、マップに反映してください。