
- はじめに
- 1. CiliumNetworkPolicyとは
- 2. Advanced Container Networking Services (ACNS)の有効化
- 3. サンプルアプリをデプロイする
- 4. ネットワークポリシーを実装する前の挙動を確認する
- 5. CiliumNetworkPolicyを実装する
- 6. 通信制御の動作確認
- 7. まとめ
- ACS事業部のご紹介
はじめに
こんにちは。ACS事業部 木戸と申します。
今回は先日検証したCiliumに対応したAKS環境を使って、CiliumNetworkPolicy による通信制御が行われるか検証してみたいと思います。
1. CiliumNetworkPolicyとは
CiliumNetworkPolicyは、Cilium(Linuxカーネルが提供するeBPFを活用したCNIプラグイン)が提供するカスタムリソースです。
Kubernetes標準のNetworkPolicyによるL3/L4(IP・ポート)の制御に加え、L7(HTTPやgRPCなどのアプリケーション層)レベルでのトラフィック制御やFQDN制限などが実現でき、より細やかな制御が可能となります。
2. Advanced Container Networking Services (ACNS)の有効化
今回は以下の3パターンを検証してみました。
1) 特定のコンテナ間通信のみ許可する
2) バックエンドからアクセス可能な外部 URL を制限する
3) 特定のコンテナ間通信を拒否するようにルールを変更する
2) を実現するには L7 レベルの通信を制御するため、AKS 側で Advanced Container Networking Services (ACNS) の有効化が必要です。
// Azure環境にログイン
az login
// 既存のAKSにACNS機能のオプションを反映
az aks update \
--resource-group {リソースグループ名} \
--name {AKSの名前} \
--enable-acns \
--acns-advanced-networkpolicies L7
3. サンプルアプリをデプロイする
前回のサンプルアプリを修正して、入力した値をそのままEchoで返却する別のコンテナを作成します。
バックエンドからEchoサーバへのコンテナ間の通信制御ができるかを検証します。
またバックエンドから外部サイトのURLにアクセスする際、許可されたURLのみ通信可能になるように制御を追加します。
最終的には以下の図のような実装内容となりました。
4. ネットワークポリシーを実装する前の挙動を確認する
まずはネットワークポリシーを実装する前にどのような挙動になるのかを確認しておきます。
通信制御を行う前は、外部サイトへのアクセスが全て通信可能になっています。


フロントエンドのコンテナからもEchoサーバーへ通信が行える状態になっています。
// フロントエンドのPodにアクセス
kubectl exec -it {サンプルアプリのPod名} -n sample-1 -- /bin/sh
// フロントエンドからEchoサーバに通信ができるかを検証し、通信に成功することを確認
/usr/src/app # wget http://sampleapp-echo-service:3001
<結果>
Connecting to sampleapp-echo-service:3001 (xx.xx.xx.xxx:3001)
saving to 'index.html'
index.html 100% |****************************************| 98 0:00:00 ETA
'index.html' saved
5. CiliumNetworkPolicyを実装する
以下のYAMLをデプロイして、CiliumNetworkPolicyを適用します。
1. バックエンドのアウトバウンド通信を制御するルール(egressルール)
# Backendサービスの通信制御
# egress ルールで、backend からのアウトバウンド通信を制御
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: backend-egress-policy
namespace: sample-1
spec:
endpointSelector:
matchLabels:
app: sampleapp-backend
egress:
# DNS プロキシ設定 ― toFQDNs の名前解決に必要
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
"k8s:k8s-app": kube-dns
toPorts:
- ports:
- port: "53"
protocol: ANY
rules:
dns:
- matchPattern: "*"
# echo サーバーへの3001ポートへの通信を許可
- toEndpoints:
- matchLabels:
app: sampleapp-echo
toPorts:
- ports:
- port: "3001"
protocol: TCP
# APCドメインへの80,443ポートのアクセスのみ許可
- toFQDNs:
- matchName: techblog.ap-com.co.jp
- matchPattern: "*.ap-com.co.jp"
toPorts:
- ports:
- port: "443"
protocol: TCP
- port: "80"
protocol: TCP
2. Echoサーバーのインバウンド通信を制御するルール(ingerssルール)
# Echoサービスへの通信制御
# ingress ルールで、echo へのインバウンド通信を制御
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: echo-ingress-policy
namespace: sample-1
spec:
endpointSelector:
matchLabels:
app: sampleapp-echo
ingress:
# backend からのインバウンド通信を許可
- fromEndpoints:
- matchLabels:
app: sampleapp-backend
# バックエンドからの3001ポートの通信のみ許可
toPorts:
- ports:
- port: "3001"
protocol: TCP
AKSに設定追加を行った後、CiliumNetworkPolicyが設定されたことを確認します。
// CiliumNetworkPolicyの適用 kubectl apply -f cilium-networkpolicy.yaml // ネットワークポリシーの確認 kubectl get ciliumnetworkpolicy -n sample-1 <結果> NAME AGE VALID backend-egress-policy 3m5s True echo-ingress-policy 3m5s True
6. 通信制御の動作確認
サンプルアプリとkubectlを使って、Ciliumによる通信制御が行われているか確認します。
バックエンドから特定のURLにのみアクセスできる状態かどうかの確認
サンプルアプリ内に表示されている3つのURLに対して順番に実行していき、techblog.ap-com.co.jp だけが正しく値が返却されてくる事を確認します。
通信失敗

通信成功

Echoサーバへの通信制御の確認
サンプルアプリからバックエンド経由でEhcoサーバからの反応があるかを確認します。
正常に返却されてくる事が確認できます。

次に、kubectlコマンドでフロントエンドのbashを起動し、wgetコマンドでEchoサーバにアクセスできるかを検証します。
フロントエンドからEchoサーバへの通信は失敗することが確認できます。
// フロントエンドのPodにアクセス
kubectl exec -it {フロントエンドのPod名} -n sample-1 -- /bin/sh
// フロントエンドからEchoサーバに通信ができるかを検証し、通信に失敗することを確認
// Ciliumのネットワークポリシーで制御できている事を確認。
/usr/src/app # wget http://sampleapp-echo-service:3001
<結果>
Connecting to sampleapp-echo-service:3001 (xx.xx.xx.xxx:3001)
wget: can't connect to remote host (xx.xx.xx.xx): Operation timed out
CiliumNetworkPolicyを再編集し、バックエンドからEchoサーバに通信できないようにしてみる
次にバックエンドの通信制御のCiliumNetworkPolicyを修正して、バックエンドからEchoサーバに通信できないようにしてみます。
YAMLを以下のように修正してデプロイしなおします。
(echoサーバーへの通信許可ルールをコメント化)
# Backendサービスの通信制御
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: backend-egress-policy
namespace: sample-1
spec:
endpointSelector:
matchLabels:
app: sampleapp-backend
egress:
# DNS プロキシ設定 ― toFQDNs の解決に必須
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
"k8s:k8s-app": kube-dns
toPorts:
- ports:
- port: "53"
protocol: ANY
rules:
dns:
- matchPattern: "*"
# # echo サーバーへの通信許可のルールを削除
# - toEndpoints:
# - matchLabels:
# app: sampleapp-echo
# toPorts:
# - ports:
# - port: "3001"
# protocol: TCP
# APC ドメインへのアクセスのみ許可
- toFQDNs:
- matchName: techblog.ap-com.co.jp
- matchPattern: "*.ap-com.co.jp"
toPorts:
- ports:
- port: "443"
protocol: TCP
- port: "80"
protocol: TCP
// CiliumNetworkPolicyの適用 kubectl apply -f cilium-networkpolicy.yaml
ルールの適用後に再度コンテナ間通信のサンプルアプリを実行すると、想定通り今度はエラーになります。

7. まとめ
今回はCiliumNetworkPolicy を用いて特定URLのみの許可や特定のコンテナへの通信許可などの通信制御を検証してみました。
名前空間やDeloymentに設定したラベルを条件にする事で柔軟にコンテナ間の通信制御を設計できると感じました。
またKubernetes標準のNetworkPolicyだけでは制御が難しいL7の通信制御も可能で、特定のAPIのみ実行可能などの制御を加える事でセキュリティを向上させる事ができる事も利点の一つだと感じました。
ACS事業部のご紹介
私達ACS事業部はクラウドネイティブ技術、Azure AI サービス、Platform Engineering、AI駆動開発支援などを通して、攻めのDX成功に向けた開発者体験・開発生産性の向上・内製化のご支援をしております。
www.ap-com.co.jp
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。
www.ap-com.co.jp
