EKSでCalicoを使ってみた[2. ネットワークポリシーを使ってみた編]
『IT自動化の力でビジネス加速を全ての企業に』
”IT自動化の専門会社”、リアルグローブ・オートメーティッド(RGA)の技術ブログ編集部の馬塚です。本日もRGAの技師がまとめた技術情報を読者の皆様にお届けしていきます!
以前配信した「EKSでCalicoを使ってみた[1.インストール編]」で、Amazon EKSのCNIをデフォルトのamazon-vpc-cni-k8sからCalicoネットワークプラグインに変更することのメリットとして、Pod数の上限を解除できることを紹介しました。多数のPodを稼働させる必要があるプロジェクトにおいては、まさに救世主的なプラグインなのですが、実はCalicoを使うことのメリットは、これ以外にもあります。
今回はそのもう1つの大きなメリットについて知っていただければと思い、記事にまとめました。ネットワークポリシーに関するややディープな話となりますが、是非お付き合いいただければと思います。
――――――――――――――――――――――――――――――――――
前回の記事では、EKSデフォルトの amazon-vpc-cni-k8s ネットワーキングプラグインの代わりに Calico ネットワーキングプラグインを使用し、ノードあたりのPod数制限を回避する方法をご紹介しました。
しかし、Calicoネットワークプラグインを導入することで得られるメリットはそれだけではありません。Calicoのネットワークポリシー機能(マイクロサービスにおけるネットワークセキュリティー機能)も使えるようになります。
実はCalicoといえばこちらのネットワークセキュリティー機能の方が有名で、"calico"と検索してヒットする記事のほとんどがこちらの機能について言及されたものでした。(EKSのノード当たりのPod数制限を回避する目的で導入するという話はおそらくかなりのレアケースです)
今回はこのCalicoのネットワークポリシー機能の概要と動作検証の結果をご紹介します。
補足: 前回の記事でも少し触れましたが、amazon-vpc-cni-k8s を使用しながら、Calicoのネットワークポリシー機能を使用することもできます。ノード当たりのPod数制限が重大な問題とはならない場合は、こちらの方法でCalicoを導入した方が手軽で良さそうです。
ちなみにCalicoは、ネットワーキング、IPAM、ポリシー機能などの機能がモジュール化して設計されているため、それぞれ独立して利用することが可能になっているようです。(Exploring the Networking Foundation for EKS: amazon-vpc-cni-k8s + Calico)
そのため、下表のようにネットワークポリシー機能のみを利用する構成を取ることができます。
KubernetesのネットワークポリシーとCalicoのネットワークポリシーについて
実は今回の記事内では、KubernetesのネットワークポリシーとCalicoのネットワークポリシーという2種類のネットワークポリシーが登場します。
まずは、それぞれの違いをご紹介します。
Kubernetesのネットワークポリシー
Kubernetesにおけるネットワークポリシーとは、Pod間通信のルールを規定するものです。KubernetesはデフォルトではPod間の通信に制限はなく、クラスタ上のすべてのPodと自由に通信することができます。ネットワークポリシーを使うことでPod間通信に制限を与えることができます。
このネットワークポリシー機能は全てのKubernetes環境で利用できるわけではありません。ネットワークポリシーに対応したネットワークプラグインを使用しているときのみ利用することができます。
KubernetesはNetwork Policy API を用意することで、ユーザーがネットワークポリシーを定義するための "方法" を提供しています。そのためユーザーはネットワークプラグインの違いを意識せずにネットワークポリシー機能を使用することができます。
(参考: Get started with Kubernetes network policy)
Calicoのネットワークポリシー
Calicoのネットワークポリシーは、Kubernetesのネットワークポリシーのスーパーセットです。KubernetesのNetwork Policy APIに定義されている機能だけでなく、Calicoの独自機能も使うことができます。
例えば、
・ポリシーの優先順位付け
・より柔軟な一致ルール
・Pod、VM、ホストインターフェースを含む複数のタイプのエンドポイントにルールを適用(KubernetesのネットワークポリシーはPodにのみ適用)
などの機能が追加されています。
他にも色々あるようなので以下の参考リンクを参照して下さい。
(参考: Get started with Calico network policy)
動作検証
calicoctl のインストール
Calicoのネットワークポリシーを操作するためには calicoctl というコマンドラインツールが必要なのでインストールします。
インストール方法はこちらです。
本検証ではmacにbrewでインストールしました。
$ brew install calicoctl
calicoctl から Kubernetes API datastore への接続設定も必要です。
これも何種類かの設定方法があり、こちらで紹介されています。
今回の検証では次のように設定しました。
$ export DATASTORE_TYPE=kubernetes
$ export KUBECONFIG=~/.kube/config
正常に設定できていれば、次のように calicoctl コマンドが使えるようになります。
$ calicoctl get nodes
NAME
ip-192-168-36-230.ap-northeast-1.compute.internal
ip-192-168-81-67.ap-northeast-1.compute.internal
ちなみに、接続設定が正しくできていないと次のようなエラーがでます。
$ calicoctl get node
Failed to create Calico API client: no etcd endpoints specified
検証環境の用意
まずは、次のような検証環境を用意します。
$ kubectl create ns test-ns1
$ kubectl label ns test-ns1 ns=test-ns1
$ kubectl create ns test-ns2
$ kubectl label ns test-ns2 ns=test-ns2
$ kubectl run -n test-ns1 debug --image=nginx:latest --labels="app=debug"
$ kubectl run -n test-ns1 nginx --image=nginx:latest --labels="app=nginx"
$ kubectl run -n test-ns2 nginx --image=nginx:latest --labels="app=nginx"
Namespace "test-ns1" に作成した Pod "debug" から各 Namespace の Pod "nginx" に疎通確認を行い。NetworkPolicy の動作確認をしていきます。
そのために、各 "nginx" Pod のIPを確認しておきます。
$ kubectl get -n test-ns1 pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
debug 1/1 Running 0 67s 172.16.173.133 ip-192-168-36-230.ap-northeast-1.compute.internal <none> <none>
nginx 1/1 Running 0 49s 172.16.26.4 ip-192-168-81-67.ap-northeast-1.compute.internal <none> <none>
$ kubectl get -n test-ns2 pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 48s 172.16.26.5 ip-192-168-81-67.ap-northeast-1.compute.internal <none> <none>
test-ns1 の nginx: 172.16.26.4
test-ns2 の nginx: 172.16.26.5
デフォルト状態ではどのPodとも疎通可能であることを確認します。
1. test-ns1 の "debug" Podから test-ns1 の "nginx" Podに接続できるか確認
$ kubectl exec -n test-ns1 -it debug -- curl -m 3 -I 172.16.26.4
HTTP/1.1 200 OK
Server: nginx/1.19.1
Date: Sun, 26 Jul 2020 11:45:45 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 07 Jul 2020 15:52:25 GMT
Connection: keep-alive
ETag: "5f049a39-264"
Accept-Ranges: bytes
2. test-ns1 の "debug" Podから test-ns2 の "nginx" Podに接続できるか確認
$ kubectl exec -n test-ns1 -it debug -- curl -m 3 -I 172.16.26.5
HTTP/1.1 200 OK
Server: nginx/1.19.1
Date: Sun, 26 Jul 2020 11:59:53 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 07 Jul 2020 15:52:25 GMT
Connection: keep-alive
ETag: "5f049a39-264"
Accept-Ranges: bytes
calico の GlobalNetworkPolicy の作成
まずは、全インバウンドを拒否する Calico の GlobalNetworkPolicy を作成してみます。
GlobalNetworkPolicy はクラスタ全体に適用されるポリシーです。次の設定をすることで、全Namespaceの全Podが他のPodからのインバウンドを拒否するようになります。
$ calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: default-deny
spec:
selector: all()
types:
- Ingress
EOF
作成したオブジェクトを確認してみます。
$ calicoctl get globalNetworkPolicy
NAME
default-deny
では、実際にどのPodとも疎通できなくなっているか確認します。
1. test-ns1 の "debug" Podから test-ns1 の "nginx" Podに接続できるか確認
$ kubectl exec -n test-ns1 -it debug -- curl -m 3 -I 172.16.26.4
curl: (28) Connection timed out after 3000 milliseconds
command terminated with exit code 28
2. test-ns1 の "debug" Podから test-ns2 の "nginx" Podに接続できるか確認
$ kubectl exec -n test-ns1 -it debug -- curl -m 3 -I 172.16.26.5
curl: (28) Connection timed out after 3000 milliseconds
command terminated with exit code 28
想定どおり、どのPodとも疎通できなくなっています。
Kubernetes の NetworkPolicy を作成する
次は、test-ns1 に Kubernetes の NetworkPolicy を作成してみます。
NetworkPolicy オブジェクトは Namespace に拘束されるオブジェクトです。作成したNamespace内のPodにのみ効力が発生します。
ここでは、"app: nginx" というラベルのついたPodは "app: debug" というラベルがついたPodからのトラフィックを許可する設定をしています。
$ kubectl -n test-ns1 apply -f - <<EOF
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-debug-to-nginx
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: debug
EOF
1. test-ns1 の "debug" Podから test-ns1 の "nginx" Podに接続できるか確認
$ kubectl exec -n test-ns1 -it debug -- curl -m 3 -I 172.16.26.4
HTTP/1.1 200 OK
Server: nginx/1.19.1
Date: Sun, 26 Jul 2020 11:45:45 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 07 Jul 2020 15:52:25 GMT
Connection: keep-alive
ETag: "5f049a39-264"
Accept-Ranges: bytes
2. test-ns1 の "debug" Podから test-ns2 の "nginx" Podに接続できるか確認
$ kubectl exec -n test-ns1 -it debug -- curl -m 3 -I 172.16.26.5
curl: (28) Connection timed out after 3000 milliseconds
command terminated with exit code 28
新たに、NetworkPolicy オブジェクトを作成したことで、test-ns1 の "nginx" Podとは通信ができるようになりました。
ちなみに、Kubernetes の NetworkPolicy は、kubectl でも calicoctl でも確認することができます。
$ kubectl get networkpolicy -n test-ns1
NAME POD-SELECTOR AGE
allow-debug-to-nginx app=nginx 4m34s
$ calicoctl get networkpolicy -n test-ns1
NAMESPACE NAME
test-ns1 knp.default.allow-debug-to-nginx
Calico の NetworkPolicy の作成
次は、Calicoの NetworkPolicy を作成してみます。
内容は test-ns2 の "nginx" Podが test-ns1 の "debug" Podからのインバウンドを許可する設定にします。
Kubernetes と Calico では apiVersion が違うだけではなく、ポリシーの書き方も少し違います。
$ calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-debug-to-nginx
namespace: test-ns2
spec:
selector: app == 'nginx'
ingress:
- action: Allow
protocol: TCP
source:
selector: app == 'debug'
namespaceSelector: ns == 'test-ns1'
destination:
ports:
- 80
EOF
test-ns1 の "debug" podから test-ns2 の "nginx" podに接続できるようになったか確認してみます。
$ kubectl exec -n test-ns1 -it debug -- curl -m 3 -I 172.16.26.5
HTTP/1.1 200 OK
Server: nginx/1.19.1
Date: Sun, 26 Jul 2020 12:09:21 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 07 Jul 2020 15:52:25 GMT
Connection: keep-alive
ETag: "5f049a39-264"
Accept-Ranges: bytes
接続できるようになりました。
なお、Calico の API で作成した NetworkPolicy は、calicoctl からは確認できますが、kubectl からは確認できませんでした。
$ calicoctl get networkpolicy -n test-ns2
NAMESPACE NAME
test-ns2 allow-debug-to-nginx
$ kubectl get networkpolicy -n test-ns2
No resources found in test-ns2 namespace.
まとめ
以上の結果から、Kubernetes と Calico どちらの ネットワークポリシーも作成可能であることが確認できました。
先にご紹介したように、Calicoのネットワークポリシーは Kubernetes のそれのスーパーセットなので、Kubernetes には存在しない機能もたくさんあります。
しかし、Calicoの独自機能を使ってしまうとCalicoにロックインされるというデメリットもあるため、環境に合わせてCalico独自機能を使うか使わないか決める必要があります。
ちなみに今回はCalicoの検証が目的だったため、シンプルなネットワークポリシーしか作成しませんでしたが、Calico公式では本番環境でのベストプラクティスなども紹介しています。
より実践的な使い方を知りたい場合はこちらもご参照ください。
参考
・Project Calico 公式サイト … calicoのインストールや設定方法など。
・Kubernetes 公式サイト … ネットワークポリシーに対応するネットワークプラグインの一覧情報。
・クラウドネイティブ時代のネットワークOSS Project Calicoを理解する … Calicoについて詳しく記述されている貴重な日本語記事。
執筆者:株式会社リアルグローブ・オートメーティッド技師 青島――――――――――――――――――――――――――――――――――
執筆者プロフィール:青島 秀治
株式会社リアルグローブ・オートメーティッド 技師
九州大学大学院理学府博士課程中退。
大学院では理論天文学が専門。数値計算プログラム開発の傍ら、研究用の計算機郡や学内システムの開発・運用を経験。
2019年よりAnsibleを用いた運用作業自動化や自社サービスのKubernetes移行、OpenShiftのインフラCI実装などの業務に従事。
【ご案内】
ITシステム開発やITインフラ運用の効率化、高速化、品質向上、その他、情シス部門の働き方改革など、IT自動化導入がもたらすメリットは様々ございます。
IT業務の自動化にご興味・ご関心ございましたら、まずは一度、IT自動化の専門家リアルグローブ・オートメーティッド(RGA)にご相談ください!
お問合せは以下の窓口までお願いいたします。
【お問い合わせ窓口】
株式会社リアルグローブ・オートメーティッド
代表窓口:info@rg-automated.jp
URL: https://rg-automated.jp
(編集:馬塚勇介/校正:水谷裕一)