Egressコントロールの実装
上記のアーキテクチャ図に示されているように、'ui'コンポーネントはフロントフェイシングアプリです。そこで、'ui'コンポーネントのネットワークコントロールの実装を開始するために、'ui'namespaceからのすべてのegressトラフィックをブロックするネットワークポリシーを定義します。
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: default-deny
spec:
podSelector:
matchLabels: {}
policyTypes:
- Egress
空のセレクタ{}はすべてのPodにマッチします
EgressポリシータイプはPodからのアウトバウンドトラフィックを制御します
注意 : ネットワークポリシーにはnamespaceが指定されていません。これは、クラスター内の任意のnamespaceに適用できる汎用ポリシーであるためです。
それでは、'ui'コンポーネントから'catalog'コンポーネントにアクセスしてみましょう。
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:03 --:--:-- 0
curl: (28) Resolving timed out after 5000 milliseconds
command terminated with exit code 28
curlコマンドの実行時に、以下の文が表示されるは ずです。これは、'ui'コンポーネントが'catalog'コンポーネントと直接通信できなくなったことを示しています。
curl: (28) Resolving timed out after 5000 milliseconds
上記のポリシーを実装すると、'ui'コンポーネントは'catalog'サービスやその他のサービスコンポーネントへのアクセスが必要であるため、サンプルアプリケーションが正しく機能しなくなります。'ui'コンポーネントに対して効果的なegressポリシーを定義するには、コンポーネントのネットワーク依存関係を理解する必要があります。
'ui'サービスが正常に機能するには、以下の3つのegressネットワーク接続が必要です。
- 'catalog'、'orders'などの他のすべてのサービスと通信できる機能
kube-systemなどのク ラスターシステムnamespace内のクラスター全体の共通ツールにアクセスできる機能- DNS名を解決するためにkube-dnsサービスにアクセスできる機能。EKS Auto Modeクラスターの場合、このIPは
172.20.0.10/32です。以下の構成でこの接続が有効になります。
以下のネットワークポリシーは、上記の要件を念頭に置いて設計されています。
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
namespace: ui
name: allow-ui-egress
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: ui
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 172.20.0.10/32
- namespaceSelector:
matchLabels:
podSelector:
matchLabels:
app.kubernetes.io/component: service
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
最初のegressルールは、内部サービスのドメイン名解決のためにDNSサーバーへのegressトラフィックを許可することに焦点を当てています。
最初のegressルールは、'catalog'、'orders'などのすべてのserviceコンポーネントへのegressトラフィック(データベースコンポーネントへのアクセスは提供しない)を許可することに焦点を当てており、namespaceSelectorと組み合わせることで、Podラベルがapp.kubernetes.io/component: serviceと一致する限り、任意のnamespaceへのegressトラフィックを許可します。
2番目のegressルールは、kube-system namespace内のすべてのコンポーネントへのegressトラフィックを許可することに焦点を当てており、これによりシステムnamespace内のコンポーネントとの他の重要な通信が可能になります。
この追加ポリシーを適用しましょう:
それでは、'catalog'サービスに接続できるかどうかをテストしてみましょう:
OK
出力からわかるよう に、'catalog'サービスには接続できますが、app.kubernetes.io/component: serviceラベルがないため、データベースには接続できません:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:05 --:--:-- 0
* Failed to connect to catalog-mysql.catalog port 3306 after 5000 ms: Timeout was reached
* Closing connection 0
curl: (28) Failed to connect to catalog-mysql.catalog port 3306 after 5000 ms: Timeout was reached
command terminated with exit code 28
同様に、'order'サービスなどの他のサービスに接続できるかどうかをテストできます。接続できるはずです。ただし、インターネットや他のサードパーティサービスへの呼び出しはブロックされるはずです。
Trying XXX.XXX.XXX.XXX:80...
* Trying [XXXX:XXXX:XXXX:XXXX::XXXX]:80...
* Immediate connect fail for XXXX:XXXX:XXXX:XXXX::XXXX: Network is unreachable
curl: (28) Failed to connect to www.google.com port 80 after 5001 ms: Timeout was reached
command terminated with exit code 28
これで'ui'コンポーネントに対する効果的なegressポリシーを定義したので、catalogサービスとデータベースコンポーネントに焦点を当て、'catalog' namespaceへのトラフィックを制御するネットワークポリシーを実装しましょう。