メインコンテンツまでスキップ

Implementing Ingress Controls

アーキテクチャ図に示されているように、「catalog」名前空間は「ui」名前空間からのトラフィックのみを受け取り、他の名前空間からは受け取りません。また、「catalog」データベースコンポーネントは「catalog」サービスコンポーネントからのトラフィックのみを受け取ることができます。

「catalog」名前空間へのトラフィックを制御するイングレスネットワークポリシーを実装することから始めましょう。

ポリシーを適用する前に、「catalog」サービスは「ui」コンポーネントからアクセスできます:

~$kubectl exec deployment/ui -n ui -- curl -v catalog.catalog/health --connect-timeout 5
   Trying XXX.XXX.XXX.XXX:80...
* Connected to catalog.catalog (XXX.XXX.XXX.XXX) port 80 (#0)
> GET /health HTTP/1.1
> Host: catalog.catalog
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
...

同様に、「orders」コンポーネントからもアクセスできます:

~$kubectl exec deployment/orders -n orders -- curl -v catalog.catalog/health --connect-timeout 5
   Trying XXX.XXX.XXX.XXX:80...
* Connected to catalog.catalog (XXX.XXX.XXX.XXX) port 80 (#0)
> GET /health HTTP/1.1
> Host: catalog.catalog
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
...

ここで、「ui」コンポーネントからのみ「catalog」サービスコンポーネントへのトラフィックを許可するネットワークポリシーを定義します:

~/environment/eks-workshop/modules/networking/network-policies/apply-network-policies/allow-catalog-ingress-webservice.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
namespace: catalog
name: allow-catalog-ingress-webservice
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: catalog
app.kubernetes.io/component: service
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ui
podSelector:
matchLabels:
app.kubernetes.io/name: ui
A

podSelectorは、ラベルapp.kubernetes.io/name: catalogapp.kubernetes.io/component: serviceを持つポッドをターゲットにします

B

このingress.from設定は、ラベルapp.kubernetes.io/name: uiを持ち、kubernetes.io/metadata.name: uiで識別されるui名前空間で実行されているポッドからの受信接続のみを許可します

ポリシーを適用しましょう:

~$kubectl apply -f ~/environment/eks-workshop/modules/networking/network-policies/apply-network-policies/allow-catalog-ingress-webservice.yaml

これで、「ui」から「catalog」コンポーネントにアクセスできることを確認してポリシーを検証できます:

~$kubectl exec deployment/ui -n ui -- curl -v catalog.catalog/health --connect-timeout 5
  Trying XXX.XXX.XXX.XXX:80...
* Connected to catalog.catalog (XXX.XXX.XXX.XXX) port 80 (#0)
> GET /health HTTP/1.1
> Host: catalog.catalog
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
...

しかし、「orders」コンポーネントからはアクセスできません:

~$kubectl exec deployment/orders -n orders -- curl -v catalog.catalog/health --connect-timeout 5
*   Trying XXX.XXX.XXX.XXX:80...
* ipv4 connect timeout after 4999ms, move on!
* Failed to connect to catalog.catalog port 80 after 5001 ms: Timeout was reached
* Closing connection 0
curl: (28) Failed to connect to catalog.catalog port 80 after 5001 ms: Timeout was reached
...

上記の出力からわかるように、「ui」コンポーネントだけが「catalog」サービスコンポーネントと通信でき、「orders」サービスコンポーネントはできません。

しかし、これはまだ「catalog」データベースコンポーネントを開放したままにしています。そこで、「catalog」サービスコンポーネントだけが「catalog」データベースコンポーネントと通信できるようにするネットワークポリシーを実装しましょう。

~/environment/eks-workshop/modules/networking/network-policies/apply-network-policies/allow-catalog-ingress-db.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
namespace: catalog
name: allow-catalog-ingress-db
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: catalog
app.kubernetes.io/component: mysql
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: catalog
app.kubernetes.io/component: service
A

podSelectorは、ラベルapp.kubernetes.io/name: catalogapp.kubernetes.io/component: mysqlを持つポッドをターゲットにします

B

ingress.fromは、ラベルapp.kubernetes.io/name: catalogapp.kubernetes.io/component: serviceを持つポッドからの受信接続のみを許可します

ポリシーを適用しましょう:

~$kubectl apply -f ~/environment/eks-workshop/modules/networking/network-policies/apply-network-policies/allow-catalog-ingress-db.yaml

「orders」コンポーネントから「catalog」データベースに接続できないことを確認することで、ネットワークポリシーを検証してみましょう:

~$kubectl exec deployment/orders -n orders -- curl -v telnet://catalog-mysql.catalog:3306 --connect-timeout 5
*   Trying XXX.XXX.XXX.XXX:3306...
* ipv4 connect timeout after 4999ms, move on!
* Failed to connect to catalog-mysql.catalog port 3306 after 5001 ms: Timeout was reached
* Closing connection 0
curl: (28) Failed to connect to catalog-mysql.catalog port 3306 after 5001 ms: Timeout was reached
command terminated with exit code 28
...

しかし、「catalog」ポッドを再起動すると、まだ接続することができます:

~$kubectl rollout restart deployment/catalog -n catalog
~$kubectl rollout status deployment/catalog -n catalog --timeout=2m

上記の出力からわかるように、「catalog」サービスコンポーネントのみが「catalog」データベースコンポーネントと通信できるようになりました。

これで「catalog」名前空間に効果的なイングレスポリシーを実装したので、同じロジックをサンプルアプリケーションの他の名前空間とコンポーネントに拡張し、サンプルアプリケーションの攻撃対象領域を大幅に減らし、ネットワークセキュリティを向上させることができます。