5
1

More than 1 year has passed since last update.

Antrea の FQDN based filtering を試してみる

Posted at

本記事は、TUNA-JP Advent Calendar 13日目の投稿です。今回は、Antrea 1.3 で導入された FQDN based filtering について紹介したいと思います。

はじめに

Antrea って何?という点については、@iwaseyusuke さんが 11日目の投稿「Antrea が OVS に書き込んでる Flow Table を読んでみよう (苦行)」で紹介されているので、今回は省略したいと思います。

Antrea は、通常の Kubernetes の Network Policy をサポートしているのですが、それだけではなく独自に拡張した Antrea Cluster Network Policy(ACNP)と呼ばれる CRD があります。 通常の Network Policy は開発者が自身のアプリケーションを保護することが目的ですが、ACNP は、管理者がクラスタ全体にセキュリティポリシーを設定できることを目的としています。そのため、ACNP が適用される順番は、Kubernetes の Network Policy の前になります。

ちなみに、Antrea Network Policy (ANP) と呼ばれる CRD も存在します。Namespace が対象である点が ACNP との違いです。ACNP と比較していくつか制限がありますが、今回試す FDQN based filtering は ANP でも使用できます。

FDQN based filtering とは、Fully Qualified Domain Name (FQDN) をもとに egress 通信を制御できる機能です。例えば、以下のように、app: test のラベルにマッチする Pod から example.com への通信をドロップするルールを作成することができます。

apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-fqdn-drop-example
spec:
  priority: 1
  appliedTo:
  - podSelector:
      matchLabels:
        app: test
  egress:
  - action: Drop
    to:
      - fqdn: "example.com"

通信を制御するためには、最終的には IP アドレスを知る必要がありますが、Antrea ではどうやって実装しているのか気になってので、今回調べてみました。

環境

今回、検証用に作成した環境は以下になります。

・ノード OS: Ubuntu 18.04
・Open vSwitch: 2.13.5
・Kubernetes: 1.22
・Antrea: 1.4

FQDN based filtering を試す

FQDN based filtering を試すために、まずは busybox の Pod をデプロイします。

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  containers:
  - image: busybox
    command:
      - sleep
      - "36000"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always

デプロイ後、busybox の Pod から google.com への ping が通ることを確認します。

$ kubectl exec -it busybox -- ping google.com
PING google.com (74.125.68.102): 56 data bytes
64 bytes from 74.125.68.102: seq=0 ttl=99 time=43.156 ms
64 bytes from 74.125.68.102: seq=1 ttl=100 time=41.788 ms
64 bytes from 74.125.68.102: seq=2 ttl=100 time=42.376 ms

次に、以下の ACNP を作成します。app: busybox のラベルにマッチする Pod から google.com への通信をドロップするルールになっています。

apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-fqdn-drop-google
spec:
  priority: 1
  appliedTo:
  - podSelector:
      matchLabels:
        app: busybox
  egress:
  - action: Drop
    to:
      - fqdn: "google.com"

上記 ACNP の作成後、google.com への ping が失敗するようになりました。ちゃんと、作成したポリシーが動作していることが分かります。

$ kubectl exec -it busybox -- ping google.com
PING google.com (74.125.68.102): 56 data bytes
^C
--- google.com ping statistics ---
30 packets transmitted, 0 packets received, 100% packet loss
command terminated with exit code 1

どうやって FQDN based filtering を実現しているのか?

さて、どうやって FQDN based filtering を実現しているのか?という話ですが、busybox Pod が動作しているノード上の Antrea Agent が CoreDNS に問い合わせを行って名前解決を行い、取得した IP アドレスをもとに Flow を作成しています。

Antrea Agent のログを見ると分かりやすいのですが、ACNP が作成されたら、名前解決を行って、得られた IP アドレスをもとに Flow を作成するという流れになっています。

I1212 02:30:24.487325       1 networkpolicy_controller.go:192] NetworkPolicy AntreaClusterNetworkPolicy:acnp-fqdn-drop-google applied to Pods on this Node
I1212 02:30:24.489093       1 fqdn.go:682] "Making DNS request" fqdn="google.com" dnsServer="10.96.0.10:53"
I1212 02:30:24.493767       1 fqdn.go:603] "Received DNS Packet with valid Answer" IPs=map[74.125.68.100:74.125.68.100 74.125.68.101:74.125.68.101 74.125.68.102:74.125.68.102 74.125.68.113:74.125.68.113 74.125.68.138:74.125.68.138 74.125.68.139:74.125.68.139] TTL=2
I1212 02:30:24.493902       1 fqdn.go:483] "Reconciling dirty rule" ruleID="5c0eef29c581d662"
I1212 02:30:24.499606       1 networkpolicy_controller.go:542] "Rule realization was done" ruleID="5c0eef29c581d662"

名前解決の処理は ACNP を作成した1回だけでなく定期的に行われるので、IP アドレスに変更があった場合も変更を検知して新しい Flow が作成されます。

antctl コマンドを使って Flow Table を確認すると、以下のように egress 通信用の Flow が作成されていることが分かります。

# antctl get ovsflows
~~ snip ~~
table=AntreaPolicyEgressRule, n_packets=11, n_bytes=1078, priority=14900,conj_id=3 actions=load:0x3->NXM_NX_REG3[],load:0x1->NXM_NX_REG0[20],goto_table:EgressMetric
table=AntreaPolicyEgressRule, n_packets=0, n_bytes=0, priority=14900,ip,nw_src=192.168.1.2 actions=conjunction(3,1/2)
table=AntreaPolicyEgressRule, n_packets=0, n_bytes=0, priority=14900,ip,nw_dst=74.125.68.101 actions=conjunction(3,2/2)
table=AntreaPolicyEgressRule, n_packets=0, n_bytes=0, priority=14900,ip,nw_dst=74.125.68.139 actions=conjunction(3,2/2)
table=AntreaPolicyEgressRule, n_packets=0, n_bytes=0, priority=14900,ip,nw_dst=74.125.68.113 actions=conjunction(3,2/2)
table=AntreaPolicyEgressRule, n_packets=0, n_bytes=0, priority=14900,ip,nw_dst=74.125.68.100 actions=conjunction(3,2/2)
table=AntreaPolicyEgressRule, n_packets=0, n_bytes=0, priority=14900,ip,nw_dst=74.125.68.102 actions=conjunction(3,2/2)
table=AntreaPolicyEgressRule, n_packets=0, n_bytes=0, priority=14900,ip,nw_dst=74.125.68.138 actions=conjunction(3,2/2)

※ Flow Table の詳細は、@iwaseyusuke さんの投稿 で解説されています!!

FQDN 周りの処理は主に fqdn.go で実装されているので、より詳細が知りたい方はこのあたりのコードを確認いただければと思います。

おわりに

今回は Antrea の FQDN based filtering について調べてみました。FQDN から Flow を作成するまでの処理を見て、ルール数が増えると CoreDNS に負荷がかかるんじゃないかなと思いましたが、FQDN ベースのルールはそんなにたくさん作らないですかね...? 機会があれば、大量に作成したときのパフォーマンスについて調べてみようと思います。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1