Kubernetesネットワークポリシーについてはこの記事で十分です

Kubernetesネットワークポリシーについてはこの記事で十分です

現在、多くの組織がアプリケーションの実行に Kubernetes を採用しています。そのため、Kubernetes を新しいデータセンター オペレーティング システムと呼ぶ人もいます。その結果、組織は Kubernetes (多くの場合、k8s と略される) を、サイバーセキュリティを含む成熟したビジネス プロセスを必要とするミッション クリティカルなプラットフォームとして認識し始めています。

[[326130]]

この新しいプラットフォームの保護を任されているサイバーセキュリティ チームは、それが驚くほど異なることに気付くかもしれません。たとえば、デフォルトの Kubernetes ポリシーでは、すべての接続が許可されます。

この記事では、Kubernetes ネットワーク ポリシーの仕組み、従来のファイアウォール ポリシーとの比較、Kubernetes アプリケーションのセキュリティ保護に役立つ注意点とベスト プラクティスについて説明します。

Kubernetes ネットワークポリシー

Kubernetes は、プラットフォームにデプロイされたアプリケーションに対してレイヤー 3 セグメンテーションを適用するために使用できるネットワーク ポリシーと呼ばれるメカニズムを提供します。ネットワーク ポリシーには、レイヤー 7 制御や脅威検出などの最新のファイアウォールの高度な機能はありませんが、出発点として適切な基本的なネットワーク セキュリティを提供します。

ネットワークポリシーはポッド通信を制御する

Kubernetes ワークロードは、一緒にデプロイされた 1 つ以上のコンテナーで構成されるポッド内で実行されます。 Kubernetes は、各ポッドに、基盤となるサーバー間でも他のすべてのポッドからルーティング可能な IP アドレスを割り当てます。 Kubernetes ネットワーク ポリシーは、仮想マシン インスタンスへのアクセスを制御するために使用されるクラウド サービスのセキュリティ グループと同様に、ポッド グループのアクセス権限を指定します。

ネットワークポリシーの作成

他の Kubernetes リソースと同様に、ネットワーク ポリシーは YAML と呼ばれる言語を使用して定義できます。以下は、ロードバランサーから postgres へのアクセスを許可する簡単な例です。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.postgres
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: postgres
  10. 進入:
  11. -から
  12. - ポッドセレクタ:
  13. 一致ラベル:
  14. アプリ: バランス
  15. ポリシータイプ:
  16. - イングレス

独自のネットワーク ポリシーを記述するには、YAML の基本を理解している必要があります。 YAML はインデント (タブではなくスペースを使用) に基づいています。インデントされた項目は、その上にある最も近いインデントされた項目に属します。ハイフン (ダッシュ) は新しいリスト項目を開始します。その他の項目はすべてマップエントリです。 YAML に関する大量の情報はインターネット上で見つかります。

ポリシー YAML ファイルを書き込んだ後、kubectl を使用してポリシーを作成します。

  1. kubectl create -f ポリシー.yaml

ネットワークポリシー定義

ネットワーク ポリシー定義は、次の 4 つの要素で構成されます。

podSelector: このポリシーの対象となるポッド (ポリシー ターゲット)。必須

policyType: このポリシーに含まれるポリシーの種類 (ingress または egress) を指定します。このオプションはオプションですが、常に明示的に指定することをお勧めします。オプション

ingress: ターゲット ポッドへのトラフィックを許可します。オプション

出力: ターゲット ポッドからの送信トラフィックを許可します。オプション

次の例は、Kubernetes Web サイトから改変したもので (「role」を「app」に置き換えています)、4 つの要素を指定しています。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前: テストネットワークポリシー
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: db
  10. ポリシータイプ:
  11. - イングレス
  12. - 退出
  13. 進入:
  14. -から
  15. -ipブロック:
  16. cidr: 172.17.0.0/16
  17. を除外する
  18. - 172.17.1.0/24
  19. - 名前空間セレクター:
  20. 一致ラベル:
  21. プロジェクト: myproject
  22. - ポッドセレクタ:
  23. 一致ラベル:
  24. 役割: フロントエンド
  25. ポート:
  26. - プロトコル: TCP
  27. ポート: 6379
  28. 出口:
  29. -
  30. -ipブロック:
  31. cidr: 10.0.0.0/24
  32. ポート:
  33. - プロトコル: TCP
  34. ポート: 5978

4 つの要素をすべて含める必要はないことに注意してください。 podSelector は必須ですが、他の 3 つはオプションです。

policyType を省略すると、次のように推論されます。

  • ポリシーは常にイングレス定義を指定するものと見なされます。明示的に定義しない場合は、「トラフィックは許可されない」ものとして扱われます。
  • 出口要素の有無によって出口が誘発されます。

エラーを回避するには、常に policyType を明示的に指定することをお勧めします。

イングレスまたはエグレス定義が提供されていない場合、上記のロジックに基づいてそれらが存在すると想定すると、ポリシーはそれらを「許可されていないトラフィック」と見なします。

デフォルトのポリシーでは、

ポリシーが定義されていない場合、Kubernetes はすべての通信を許可します。すべてのポッドは互いに自由に通信できます。これはセキュリティの観点からは直感に反するように聞こえるかもしれませんが、Kubernetes はアプリケーションの通信を望む開発者によって設計されたことを覚えておいてください。ネットワーク ポリシーは、後から機能強化として追加されました。

名前空間

名前空間は、名前空間環境を相互に分離するように設計された Kubernetes のマルチテナント メカニズムですが、名前空間間の通信はデフォルトで許可されています。

ほとんどの Kubernetes エンティティと同様に、ネットワーク ポリシーは特定の名前空間に存在します。メタデータ ヘッダーは、ポリシーがどの名前空間に属しているかを Kubernetes に伝えます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前: テストネットワークポリシー
  5. 名前空間: my-namespace
  6. 仕様:
  7. ...

メタデータの名前空間を明示的に指定しない場合は、kubectl によって提供される名前空間が適用されます (デフォルトは namespace=default)。

  1. kubectl apply -n 私の名前空間 -f 名前空間.yaml

複数の名前空間に均一に適用されるポリシーを記述する場合を除き、名前空間を明示的に指定することをお勧めします。

ポリシー内の podSelector 要素は、ポリシーが属する名前空間からポッドを選択します (別の名前空間からポッドを選択することはできません)。

ingress 要素と egress 要素の podSelector は、namespaceSelector と一緒に使用しない限り、同じ名前空間内のポッドも選択します。

ポリシーの命名規則

ポリシーの名前は名前空間内で一意です。名前空間内に同じ名前のポリシーが 2 つ存在することはできませんが、異なる名前空間に同じ名前のポリシーが存在することは可能です。これは、複数の名前空間にポリシーを再適用する場合に非常に便利です。

私が気に入っている戦略的な命名方法の 1 つは、名前空間とポッドを組み合わせることです。次に例を示します。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.postgres
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: postgres
  10. 進入:
  11. -から
  12. - ポッドセレクタ:
  13. 一致ラベル:
  14. アプリ:管理者
  15. ポリシータイプ:
  16. - イングレス

ラベル

ポッドや名前空間などの Kubernetes オブジェクトには、ユーザー定義のラベルを添付できます。 Kubernetes ネットワーク ポリシーは、ラベルを使用して適用するポッドを選択します。

  1. ポッドセレクター:
  2. 一致ラベル:
  3. 役割: db

または、それらが適用される名前空間。次の例では、ラベルに一致する名前空間内のすべてのポッドを選択します。

  1. 名前空間セレクター:
  2. 一致ラベル:
  3. プロジェクト: myproject

注意すべき点が 1 つあります。namespaceSelector を使用する場合は、選択した名前空間に実際に使用しているタグが含まれていることを確認してください。 default や kube-system などの組み込み名前空間には、すぐに使用できるラベルがないことに注意してください。次のようにして名前空間にラベルを追加できます。

  1. kubectl ラベル 名前空間デフォルト名前空間 =デフォルト

メタデータ内の名前空間は、ラベルではなく、名前空間の実際の名前です。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前: テストネットワークポリシー
  5. 名前空間:デフォルト
  6. 仕様:
  7. ...

送信元と送信先

ファイアウォール ポリシーは、ソースとエンドポイントを含むルールで構成されます。 Kubernetes ネットワーク ポリシーはターゲット (ポリシーが適用されるポッドのセット) に対して定義され、ターゲットの受信トラフィックまたは送信トラフィックが指定されます。同じ例をもう一度使用すると、ポリシーがデフォルトの名前空間内のラベル「db:app」を持つすべてのポッドを対象としていることがわかります。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前: テストネットワークポリシー
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: db
  10. ポリシータイプ:
  11. - イングレス
  12. - 退出
  13. 進入:
  14. -から
  15. -ipブロック:
  16. cidr: 172.17.0.0/16
  17. を除外する
  18. - 172.17.1.0/24
  19. - 名前空間セレクター:
  20. 一致ラベル:
  21. プロジェクト: myproject
  22. - ポッドセレクタ:
  23. 一致ラベル:
  24. 役割: フロントエンド
  25. ポート:
  26. - プロトコル: TCP
  27. ポート: 6379
  28. 出口:
  29. -
  30. -ipブロック:
  31. cidr: 10.0.0.0/24
  32. ポート:
  33. - プロトコル: TCP
  34. ポート: 5978

このポリシーの Ingress 項目は、ターゲット ポッドへの着信トラフィックを許可します。したがって、入力は「送信元」として解釈され、宛先はそれぞれの「エンドポイント」として解釈されます。同様に、egress は「宛先」として解釈され、target はそれぞれの「ソース」として解釈されます。

出力とDNS

出力を実行するときは、Kubernetes がサービスの名前を IP アドレスに解決するために使用する DNS をブロックしないように注意する必要があります。そうでない場合、balance に DNS ルックアップの実行を許可していないため、このポリシーは機能しません。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.balance
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: バランス
  10. 出口:
  11. -
  12. - ポッドセレクタ:
  13. 一致ラベル:
  14. アプリ: postgres
  15. ポリシータイプ:
  16. - 退出

これを修正するには、DNS サービスへのアクセスを許可する必要があります。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.balance
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: バランス
  10. 出口:
  11. -
  12. - ポッドセレクタ:
  13. 一致ラベル:
  14. アプリ: postgres
  15. -
  16. ポート:
  17. - プロトコル: UDP
  18. ポート: 53
  19. ポリシータイプ:
  20. - 退出

「to」要素は空で、すべての名前空間内のすべてのポッドが暗黙的に選択され、balance が Kubernetes の DNS サービス (通常は kube-system 名前空間に配置) を介して DNS ルックアップを実行できるようになります。

これは機能しますが、許可が多すぎて安全ではありません。クラスター外部の DNS ルックアップを許可してしまうからです。

段階的にロックすることができます:

1. namespaceSelector を追加して、クラスター内でのみ DNS ルックアップを許可します。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.balance
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: バランス
  10. 出口:
  11. -
  12. - ポッドセレクタ:
  13. 一致ラベル:
  14. アプリ: postgres
  15. -
  16. - 名前空間セレクター: {}
  17. ポート:
  18. - プロトコル: UDP
  19. ポート: 53
  20. ポリシータイプ:
  21. - 退出

2. kube-system名前空間でのみDNSを許可する

これを行うには、kube-system 名前空間にラベルを追加する必要があります。

  1. kubectl ラベル名前空間 kube-system namespace=kube-system

次に、namespaceSelector を使用してポリシーで指定します。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.balance
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: バランス
  10. 出口:
  11. -
  12. - ポッドセレクタ:
  13. 一致ラベル:
  14. アプリ: postgres
  15. -
  16. - 名前空間セレクター:
  17. 一致ラベル:
  18. 名前空間: kube-system
  19. ポート:
  20. - プロトコル: UDP
  21. ポート: 53
  22. ポリシータイプ:
  23. - 退出

3. 心配性な人は、さらに一歩進んで、DNS を kube-system 名前空間内の特定の DNS サービスに制限したいかもしれません。以下の「名前空間とポッドによるフィルタリング」セクションを参照してください。

もう 1 つのオプションは、名前空間レベルで DNS を許可することです。これにより、各サービスに対して DNS を指定する必要がなくなります。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.dns
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクタ: {}
  8. 出口:
  9. -
  10. - 名前空間セレクター: {}
  11. ポート:
  12. - プロトコル: UDP
  13. ポート: 53
  14. ポリシータイプ:
  15. - 退出

空の podSelector は、名前空間内のすべてのポッドを選択します。

最初のマッチとルールの順序

ファイアウォール管理者は、パケットに対して実行されるアクション (許可または拒否) は、それに一致する最初のルールによって決定されることを知っています。しかし、Kubernetes では、ポリシーの順序は重要ではありません。ポリシーが定義されていない場合のデフォルトの動作では、すべての通信が許可され、すべてのポッドが相互に通信できるようになります。ポリシーが定義されると、少なくとも 1 つのポリシーによって選択された各ポッドは、それを選択したポリシーの結合 (論理 OR) に従って分離されます。

どのポリシーでも選択されていないポッドは開いたままになります。クリーンアップ ルールを定義することで、この動作を変更できます。

クリーンアップルール(拒否)

ファイアウォール ポリシーでは通常、any-any-any-deny ルールを使用して、明示的に許可されていないすべてのトラフィックをドロップします。 Kubernetes には拒否アクションはありませんが、policyTypes=Ingress を指定して実際のイングレスの定義を省略し、「イングレスを許可しない」と解釈される通常のルールを使用することで、同じ効果を実現できます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:すべて拒否
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクタ: {}
  8. ポリシータイプ:
  9. - イングレス

このポリシーは、名前空間内のすべてのポッドをソースとして選択し、イングレス (つまり、トラフィックが許可されない) を定義しません。

同様に、名前空間からのすべての送信トラフィックを拒否することもできます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前: deny- all -egress
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクタ: {}
  8. ポリシータイプ:
  9. - 退出

名前空間内のポッドへのアクセスを許可するその他のポリシーは、この拒否ポリシーよりも優先されることに注意してください。これは、ファイアウォールの拒否ポリシーの上に許可ポリシーを追加するのと同じです。

任意任意許可

上記の deny-all ポリシーを空の ingress 要素で変更することで、allow-all ポリシーを作成できます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:すべて許可
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクタ: {}
  8. 進入:
  9. - {}
  10. ポリシータイプ:
  11. - イングレス

これにより、すべての名前空間内のすべてのポッド (および IP) からデフォルトの名前空間内の任意のポッドへの通信が可能になります。これはデフォルトの動作なので、通常は必要ありません。ただし、問題を特定するには、他のすべてのルールを一時的に無効にすると役立つ場合があります。

このスコープを狭めて、デフォルトの名前空間内の特定のポッド セットへのアクセスのみを許可することができます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前: allow- all - to -balance
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: バランス
  10. 進入:
  11. - {}
  12. ポリシータイプ:
  13. - イングレス

次のポリシーは、すべての受信トラフィックと送信トラフィック (クラスター外部の IP へのアクセスを含む) を許可します。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:すべて許可
  5. 仕様:
  6. ポッドセレクタ: {}
  7. 進入:
  8. - {}
  9. 出口:
  10. - {}
  11. ポリシータイプ:
  12. - イングレス
  13. - 退出

複数の戦略を組み合わせる

戦略は、3 つのレベルで論理 OR を使用して結合されます。各ポッドは、適用されているすべてのポリシーの組み合わせに基づいて、通信を許可するかどうかを決定します。

1. 「from」および「to」項目では、「or」で結合される 3 種類の項目を定義できます。

  • namespaceSelector - 名前空間全体を選択
  • podSelector - ポッドを選択
  • ipBlock - サブネットを選択

from/to の下に任意の数の項目を定義できます (同じタイプの複数の項目も可)。それらは論理 OR を使用して結合されます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.postgres
  5. 名前空間:デフォルト
  6. 仕様:
  7. 進入:
  8. -から
  9. - ポッドセレクタ:
  10. 一致ラベル:
  11. アプリ: インデクサー
  12. - ポッドセレクタ:
  13. 一致ラベル:
  14. アプリ:管理者
  15. ポッドセレクター:
  16. 一致ラベル:
  17. アプリ: postgres
  18. ポリシータイプ:
  19. - イングレス

2. ポリシーでは、イングレス ポリシーに複数の「from」項目を含めることができ、それらは論理 OR によって結合されます。同様に、出力ポリシーには複数の「to」項目を含めることができ、これらも論理 OR によって結合されます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.postgres
  5. 名前空間:デフォルト
  6. 仕様:
  7. 進入:
  8. -から
  9. - ポッドセレクタ:
  10. 一致ラベル:
  11. アプリ: インデクサー
  12. -から
  13. - ポッドセレクタ:
  14. 一致ラベル:
  15. アプリ:管理者
  16. ポッドセレクター:
  17. 一致ラベル:
  18. アプリ: postgres
  19. ポリシータイプ:
  20. - イングレス

3. 複数の戦略も論理 OR を通じて組み合わせられます。

ただし、ポリシーを組み合わせる場合、いくつかの制限があります。Kubernetes は、異なる policyType (ingress または egress) のポリシーのみを組み合わせることができ、ingress (または egress) を指定する複数のポリシーは互いに上書きされます。

名前空間間の通信

デフォルトでは、名前空間間の通信が許可されます。これを変更するために、すべて拒否ポリシーを使用して、その名前空間との間の通信をブロックすることができます。

名前空間へのアクセスをブロックする場合は、namespaceSelector を使用して特定の名前空間からのアクセスを許可できます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:データベース.postgres
  5. 名前空間:データベース
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: postgres
  10. 進入:
  11. -から
  12. - 名前空間セレクター:
  13. 一致ラベル:
  14. 名前空間:デフォルト
  15. ポリシータイプ:
  16. - イングレス

これにより、デフォルトの名前空間内のすべてのポッドがデータベース名前空間の postgres ポッドにアクセスできるようになります。しかし、デフォルトの名前空間内の特定のポッドのみが postgres にアクセスできるようにしたい場合はどうすればよいでしょうか?

名前空間とポッドの組み合わせでフィルタリング

Kubernetes 1.11 以降では、論理 AND を使用して namespaceSelector と podSelector を組み合わせることができます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:データベース.postgres
  5. 名前空間:データベース
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: postgres
  10. 進入:
  11. -から
  12. - 名前空間セレクター:
  13. 一致ラベル:
  14. 名前空間:デフォルト
  15. ポッドセレクター:
  16. 一致ラベル:
  17. アプリ:管理者
  18. ポリシータイプ:
  19. - イングレス

なぜこれは「または」ではなく「かつ」と解釈されるのでしょうか?

podSelector はダッシュで始まっていないことに注意してください。これは、yaml では podSelector が前の namespaceSelector と同じリスト項目に属していることを意味するため、それらは論理 AND で結合されます。 podSelector の前にダッシュを追加すると、前の namespaceSelector と論理的に OR される新しいリスト項目が作成されます。すべての名前空間で特定のラベルを持つポッドを選択するには、空の namespaceSelector を指定します。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:データベース.postgres
  5. 名前空間:データベース
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: postgres
  10. 進入:
  11. -から
  12. - 名前空間セレクター: {}
  13. ポッドセレクター:
  14. 一致ラベル:
  15. アプリ:管理者
  16. ポリシータイプ:
  17. - イングレス

複数のタグは論理積を介して結合されます

複数のオブジェクト (ホスト、ネットワーク、グループなど) を含むファイアウォール ルールは、論理 OR として解釈されます。たとえば、パケットの送信元が HOST_1 または HOST_2 と一致する場合、次のルールが適用されます。

対照的に、Kubernetes では、podSelector と namespaceSelector 内の複数のラベルは論理 AND を使用して結合されます。たとえば、これは role=db と version=v2 の両方のラベルを持つポッドを選択します。

  1. ポッドセレクター:
  2. 一致ラベル:
  3. 役割: db
  4. バージョン: v2

同じロジックが、ポリシー ターゲット セレクター、ポッド セレクター、名前空間セレクターなど、すべてのタイプのセレクターに適用されます。

サブネットと IP アドレス (ipBlock)

ファイアウォールは、VLAN、IP、サブネットを使用してネットワークをセグメント化します。 Kubernetes では、ポッド IP は自動的に割り当てられ、頻繁に変更される可能性があるため、ネットワーク ポリシーではラベルを使用してポッドと名前空間を選択します。サブネット (ipBlock) は、入力または出力接続 (南北) に使用されます。たとえば、次のポリシーでは、デフォルトの名前空間内のすべてのポッドが Google の DNS サービスにアクセスできるようになります。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前: 出力DNS
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクタ: {}
  8. ポリシータイプ:
  9. - 退出
  10. 出口:
  11. -
  12. -ipブロック:
  13. cidr: 8.8.8.8/32
  14. ポート:
  15. - プロトコル: UDP
  16. ポート: 53

この場合、空の podSelector は「この名前空間内のすべてのポッドを選択する」ことを意味します。このポリシーは 8.8.8.8 へのアクセスのみを許可し、他の IP へのアクセスは拒否します。つまり、実際には、Kubernetes 内部 DNS サービスへのアクセスがブロックされていることになります。それでも許可したい場合は、明示的に指定する必要があります。

通常、ipBlock と podSelector は相互に排他的です。これは、通常、ipBlock では内部ポッド IP を使用しないためです。内部ポッド IP で ipBlock を指定すると、実際にはそれらの IP を持つポッドとの通信が許可されます。しかし、実際にはどの IP を使用するかは不明であるため、ポッドの選択に IP を使用しないでください。

次のポリシーにはすべての IP が含まれており、他のすべてのポッドへのアクセスが許可されます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前: 出口-任意
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクタ: {}
  8. ポリシータイプ:
  9. - 退出
  10. 出口:
  11. -
  12. -ipブロック:
  13. cidr: 0.0.0.0/0

内部 IP を除外することで、外部 IP のみへのアクセスを許可できます。たとえば、ポッドのサブネットが 10.16.0.0/14 の場合:

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前: 出口-任意
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクタ: {}
  8. ポリシータイプ:
  9. - 退出
  10. 出口:
  11. -
  12. -ipブロック:
  13. cidr: 0.0.0.0/0
  14. を除外する
  15. - 10.16.0.0/14

ポートとプロトコル

通常、ポッドは 1 つのポートのみをリッスンするため、ポリシーでポートを省略して、デフォルトで任意のポートを許可することができます。ただし、明示的に指定された限定されたポートにポリシーを設定することをお勧めします。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.postgres
  5. 名前空間:デフォルト
  6. 仕様:
  7. 進入:
  8. -から
  9. - ポッドセレクタ:
  10. 一致ラベル:
  11. アプリ: インデクサー
  12. - ポッドセレクタ:
  13. 一致ラベル:
  14. アプリ:管理者
  15. ポート:
  16. - ポート: 443
  17. プロトコル: TCP
  18. - ポート: 80
  19. プロトコル: TCP
  20. ポッドセレクター:
  21. 一致ラベル:
  22. アプリ: postgres
  23. ポリシータイプ:
  24. - イングレス

ポートは、それが出現する「to」または「from」句内のすべての項目に適用されることに注意してください。異なるアイテムに異なるポートを指定する場合は、イングレスまたはエグレスを複数の「to」または「from」エントリに分割し、それぞれに独自のポートを設定できます。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.postgres
  5. 名前空間:デフォルト
  6. 仕様:
  7. 進入:
  8. -から
  9. - ポッドセレクタ:
  10. 一致ラベル:
  11. アプリ: インデクサー
  12. ポート:
  13. - ポート: 443
  14. プロトコル: TCP
  15. -から
  16. - ポッドセレクタ:
  17. 一致ラベル:
  18. アプリ:管理者
  19. ポート:
  20. - ポート: 80
  21. プロトコル: TCP
  22. ポッドセレクター:
  23. 一致ラベル:
  24. アプリ: postgres
  25. ポリシータイプ:
  26. - イングレス

ポートのデフォルトの動作:

  • ポートが完全に省略されている場合は、すべてのポートとすべてのプロトコルが暗黙的に指定されます。
  • プロトコルが省略された場合、デフォルトでTCPになります。
  • ポートを省略すると、すべてのポートがデフォルトになります。

ベスト プラクティス: デフォルトの動作に依存せず、明示的に指定します。

サービスのポートではなく、ポッドのポートを使用する必要があることに注意してください。

ポリシーはポッドまたはサービスに対して定義されていますか?

Kubernetes 内のポッドが別のポッドにアクセスする場合、通常はサービス (サービスを実装するポッドにトラフィックを転送する仮想ロード バランサー) を経由します。ネットワーク ポリシーがサービスへのアクセスを制御すると思われるかもしれませんが、そうではありません。 Kubernetes ネットワーク ポリシーは、サービス ポートではなくポッド ポートに適用されます。

たとえば、サービスがポート 80 でリッスンしているが、ポート 8080 でリッスンしているポッドにトラフィックを転送する場合は、ネットワーク ポリシーでポート 8080 を指定する必要があります。

この設計は最適ではありません。サービスの内部動作 (ポッドがリッスンしているポートなど) が変更されると、ネットワーク ポリシーを更新する必要があるためです。

どうやらこの問題には解決策があり、それはハードコードされた数値ポートの代わりに名前付きポートを使用することです。

  1. APIバージョン: networking.k8s.io/v1
  2. 種類: ネットワークポリシー
  3. メタデータ:
  4. 名前:デフォルト.allow-hello
  5. 名前空間:デフォルト
  6. 仕様:
  7. ポッドセレクター:
  8. 一致ラベル:
  9. アプリ: こんにちは
  10. ポリシータイプ:
  11. - イングレス
  12. 進入:
  13. -から
  14. - ポッドセレクタ:
  15. 一致ラベル:
  16. 実行: curl
  17. ポート:
  18. - ポート: my-http

ポッド定義でこのポートの名前を指定する必要があります。

  1. apiバージョン: extensions/v1beta1
  2. 種類: デプロイメント
  3. メタデータ:
  4. ラベル:
  5. アプリ: こんにちは
  6. 名前: こんにちは
  7. 仕様:
  8. セレクタ:
  9. 一致ラベル:
  10. アプリ: こんにちは
  11. テンプレート:
  12. メタデータ:
  13. ラベル:
  14. アプリ: こんにちは
  15. 仕様:
  16. コンテナ:
  17. - イメージ: gcr.io/hello-minikube-zero-install/hello-node
  18. imagePullPolicy: 常に
  19. 名前: hello-node
  20. ポート:
  21. - コンテナポート: 8080
  22. 名前: my-http

これにより、ネットワーク ポリシーがポッドから切り離されます。

イングレス

Kubernetes では、「ingress」という用語には 2 つの意味があります。

  1. Ingressネットワークポリシーを使用すると、他のポッドまたは外部IPからのポッドへのアクセスを制御できます。
  2. Kubergess の Ingress は、トラフィックをクラスターにルーティングするように外部ロードバランサーを構成する方法です。

Kubernetes イングレスからのアクセスを制限するために k8s ネットワーク ポリシーを記述することもできますが、これはロード バランサーの内部 IP のみを制御するため、ほとんどの場合あまり役に立ちません。どの外部サブネットがクラスターにアクセスできるかを制御するには、外部の適用ポイント (ロード バランサー自体やロード バランサーの前にあるファイアウォールなど) でアクセス制御を構成する必要があります。

イングレスとエグレスの両方を定義する必要がありますか?

簡単に答えると、はいです。ポッド A がポッド B にアクセスできるようにするには、ポッド A が出力ポリシーを介して送信接続を作成できるようにし、ポッド B が入力ポリシーを介して受信接続を受け入れるようにする必要があります。

ただし、実際には、2 つの方向のいずれかにデフォルトの許可ポリシーを使用する場合があります。

ソース ポッドが 1 つ以上の出力ポリシーによって選択された場合、ポリシーの結合に基づいて制限されるため、宛先ポッドへの接続を明示的に許可する必要があります。ポッドがどのポリシーでも選択されていない場合は、デフォルトですべての送信トラフィックが許可されます。

同様に、1 つ以上のイングレス ポリシーによって選択されたターゲット ポッドも、ポリシーの組み合わせによる制限の対象となり、その場合は、ソース ポッドからのトラフィックを受け入れることを明示的に許可する必要があります。ポッドがどのポリシーでも選択されていない場合は、デフォルトですべての受信トラフィックが許可されます。

ホストネットワークトラップ

Kubernetes は通常、独自の分離されたネットワーク内でポッドを実行します。ただし、ホスト上でポッドを実行するように Kubernetes に指示することはできます。

  1. ホストネットワーク: true

これにより、ネットワーク ポリシーが完全にバイパスされ、ポッドはホスト上で実行されている他のプロセスと同じように通信します。

トラフィックログ

Kubernetes ネットワーク ポリシーではトラフィック ログを生成できません。これにより、戦略が期待どおりに機能しているかどうかを知ることが難しくなります。これは、セキュリティ分析の観点からも大きな制限となります。

外部サービスへのトラフィックの制御

Kubernetes ネットワーク ポリシーでは、出力用の完全修飾ドメイン名 (DNS) を指定することはできません。これは、aws.com など、固定 IP を持たない外部サイトへのトラフィックを制御する場合の制限です。

ポリシー検証

ファイアウォールは無効なポリシーに対して警告を発したり、無効なポリシーの受け入れを拒否したりします。 Kubernetes でも​​検証が行われました。 kubectl を使用してネットワーク ポリシーを定義すると、Kubernetes によってポリシーが無効であると通知され、受け入れを拒否される場合があります。それ以外の場合、Kubernetes はポリシーを取得し、不足している詳細を変更します。これは次のコマンドで確認できます。

kubernetes ネットワークポリシーを取得する-o ヤムル

Kubernetes の検証は絶対確実ではなく、ポリシーで特定の種類のエラーが許容される可能性があることに注意してください。

埋め込む

Kubernetes 自体はネットワーク ポリシーを強制するものではなく、コンテナ ネットワーク インターフェイス (CNI) と呼ばれる基盤となるシステムに強制のハードワークを渡すだけの API ゲートウェイです。適切な CNI なしで Kubernetes クラスターでポリシーを定義することは、ファイアウォールがインストールされていないサーバー上でファイアウォール ルールを定義するようなものです。セキュリティ対応の CNI があることを確認するか、マネージド Kubernetes プラットフォームの場合は、CNI をインストールするネットワーク ポリシーを明示的に有効にする必要があります。

CNI でサポートされていないネットワーク ポリシーを定義した場合、Kubernetes は警告を発しないことに注意してください。

ステートフルかステートレスか?

現在、すべての Kubernetes CNI はステートフルであるため、ポッドは応答用に高ポートを開かなくても、開始した TCP 接続で応答を受信できます。ステートフル性を保証する Kubernetes 標準は知りません。

高度なセキュリティポリシー管理

Kubernetes のより高度なネットワーク ポリシーを実装する方法をいくつか紹介します。

  1. サービス メッシュ設計パターンでは、サイドカーを使用して、サービス レベルでより高度なテレメトリとトラフィック制御を提供します。例については、Istio を参照してください。
  2. 一部の CNI プロバイダーは、Kubernetes ネットワーク ポリシーを超えてツールを拡張しています。
  3. Tufin Orca - Kubernetes ネットワーク ポリシーの視覚化と自動化。

要約する

Kubernetes ネットワーク ポリシーはクラスターをセグメント化する優れた方法を提供しますが、直感的ではなく、多くの注意点があります。この複雑さのため、戦略に「バグ」を持つクラスターが多数存在するはずだと私は考えています。考えられる解決策としては、自動化されたポリシー定義やその他のセグメンテーション方法があります。その間、この記事が皆さんが抱えている問題の解明と解決に役立つことを願っています。

<<:  Nutanixは、COVID-19の課題を乗り越えるパートナーとその顧客を支援するために特別な財政支援プログラムを提供しています。

>>:  Spring BootでマルチテナントSaaSプラットフォームを構築するコア技術についてお話しします

推薦する

役に立つ情報: Catalyst-Seattle/10G ポート/4T トラフィック開始

Catalyst、この製品は5年前から存在しており(ドメイン名の更新は2017年に終了しました)、パ...

ユーザーエクスペリエンスの向上におけるウェブサイトインタラクションの役割についての簡単な分析

現在、ウェブサイトのユーザー エクスペリエンスの向上は、多くのウェブマスターの注目の的となっています...

最新のTOP44ウェブマスターウェブサイトの要約と分析

昨年3月に、Alexaランキング1万位以下の国内ウェブマスターサイトを初めてまとめました。その時は合...

Webmaster.com からの毎日のレポート: OICQ.com が 14,000 ドルで売却され、Tencent はお気に入りの古いドメイン名を放棄

1. OICQ.comが14,000ドルで売却され、テンセントはお気に入りの古いドメイン名を放棄した...

SEO診断の目標: 適切なSEOの方向性を見つけ、SEO戦略を策定する

ウェブサイトの SEO 診断は SEO サービスの一分野です。これまで具体的に言及されていませんでし...

2020年後半、中国のクラウドプロフェッショナルサービス市場規模は91.2億人民元に達した。

最近、国際データコーポレーション(IDC)は最新の「中国クラウド専門サービス市場(2020年下半期)...

優れた SEM 広告タイトルを書くための 7 つのヒント: ユーザーを誘導して惹きつける方法

SEMプロモーションは今や企業からますます注目を集めています。限られたスペースでより重要な情報を表示...

2018 年のクラウド コンピューティング市場を振り返ると、変化は需要よりも大きいのでしょうか?

今年、徐々に成熟し、導入に向けて順調に進んでいるように見えるクラウドコンピューティングも、実は内部的...

SEO: 煙と雲

SEOはキーワードがすべて私は「do」という形容詞を使うのが本当に嫌いです。検索エンジンを圧倒しよう...

簡単な分析: 従来の企業はどのようにマーケティングと統合できるでしょうか?

現代社会では、インターネットの急速な発展により、オンラインマーケティングはもはや目新しいものではなく...

テンセントマーケティングケーススタディ: モバイル QQ vs. WeChat

5月28日、メディアはテンセントのユーザーに対して大きなジョークを飛ばした。このジョークの背後にある...

budgetvm-22% 割引コード/すべての VPS および専用サーバー/新しい中国語ウェブサイト

Budgetvmのカスタマーサービスから、中国の顧客向けに特別なウェブサイトを開発し、2つの特別割引...

エッジコンピューティングはデータストレージをどのように変えるのでしょうか?

エッジ コンピューティングは、データ転送コストと損失を削減することで、企業が効率的で信頼性の高いスト...

コスト効率の高い米国VPS、優れたネットワークを備えた安価でコスト効率の高い米国VPS

コスト効率の高いアメリカの VPS、皆さんが言いたいのは、コスト効率の高いアメリカの VPS、または...

清華紫光集団は、12のカテゴリーで267のクラウドサービス製品を含む清華紫光集団パブリッククラウドの商用試験を開始したと発表した。

2018 年 7 月 10 日、清華紫光集団は清華パブリッククラウドの商用試験利用を開始したことを発...