見出し画像

OpenShift SDNについて

『IT自動化の力でビジネス加速を全ての企業に』

”IT自動化の専門会社”、リアルグローブ・オートメーティッド(RGA)の技術ブログ編集部の水谷です。本日もRGAの技師がまとめた技術情報を読者の皆様にお届けしていきます!

RGAでは、OpenShiftを用いたエンタープライズ向けコンテナアプリケーションの開発支援も行っているのですが、このOpenShiftやKubernetesを用いてコンテナのオーケストレーションを行う際、カギとなるコンポーネントの1つにCNIプラグインがあります。そこで今回は、OpenShiftにおけるCNIプラグインとしてよく使われている OpenShift SDN にフォーカスを当て、どのようにプロジェクト間の通信を制御しているのかについてRGAの技師がまとめた記事をお送りします。

プロジェクト間の通信を正しく制限することは、セキュリティ面でとても重要な事柄の1つです。ややディープな内容とはなりますが、お付き合いいただければと思います。

――――――――――――――――――――――――――――――――――

この記事では、OpenShift SDNの動作モードの違いや、これを使ってどのようにプロジェクト間の通信を制御していくかについて書いていく。

OpenShift SDN とは何か

まず、本題に入る前にOpenShift SDNが何者なのか簡単に説明しておくと、OpenShift SDNは、OpenShiftのデフォルトCNIプラグインである。OpenShiftではOpenShift SDN以外のCNIプラグインも使用可能(e.g. flannel, calico)であるが、OpenShift SDNがデフォルトとなっている。

CNIプラグインとは何か

では、CNIプラグインとは何か。OpenShiftを含むKubernetesでは、全てのPodは独自のIPアドレスをもちろん、NATなしで他のノード上のPodと通信することができるようになっているが、この仕組みを提供しているのがCNIプラグインである。CNIプラグインは複数の実装があるが、その基本仕様はCNIで定められている(詳しくはCNIのGitHubリポジトリのREADMEを参照)。

なお、Kubernetesのネットワークモデルについては、こちらのオフィシャルページに書かれているので、必要に応じて参照してほしい。

また、以前の記事(EKSでCalicoを使ってみた[1.インストール編]EKSでCalicoを使ってみた[2. ネットワークポリシーを使ってみた編])では、Amazon EKS(Amazon Elastic Kubernetes Service)において、デフォルトのCNIプラグインからcalicoというCNIプラグインに変更したことについて書いているので、こちらも合わせて参考にしてほしい。

OpenShift SDN のモード

さて、このOpenShift SDNにはモードが3つある。そして、モードはクラスターインストール時に選択する(詳しくはこちらを参照)ようになっている。

さっそく3つのモードについて見ていこう。

・networkpolicy mode
これがOpenShift4におけるデフォルトモードである。特徴は、NetworkPolicy オブジェクトによって分離ポリシーを設定することができること。デフォルトでは別プロジェクトのpodとも疎通可能。

また、デフォルトネットワークポリシー を作成することで、後述のmultitenant modeのような「デフォルトで別プロジェクトと疎通不可」という環境を作ることもできる。

・multitenant mode
このモードは、デフォルトで別プロジェクトと疎通不可となる。しかし、プロジェクト同士を結合することで、複数プロジェクト間で通信可能にすることもできる。

・subnet mode
このモードでは、制限なしで別プロジェクトのPod同士が通信可能。

画像2

multitenant modeとsubnet modeでできることは、全部networkpolicy modeでもできるので、基本的にはnetworkpolicy modeを使っていればほとんどのケースに対応できるだろう。

NetworkPolicy オブジェクトを使って疎通制御する方法

さて、3つのモードの中から networkpolicy mode を選択した環境で、NetworkPoilcyオブジェクトを使って、他プロジェクトからの通信を制御できるか確認した。

まずは、(NetworkPolicyオブジェクトがない状態で)プロジェクト内のPodと疎通できることを確認する。

# テスト用プロジェクト作成
$ oc new-project test1

# プロジェクト内にアプリケーションを2つデプロイ
$ oc new-app httpd --name=httpd1
$ oc new-app httpd --name=httpd2

# アプリケーションのIPを確認
$ oc get pods --field-selector status.phase=Running -o custom-columns="NAME:{.metadata.name},HOST_IP:{.status.podIP}"
NAME             HOST_IP
httpd1-1-2np89   10.130.0.18
httpd2-1-j7p69   10.129.0.29

# svcの確認
$ oc get svc                                                                                                         
NAME     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
httpd1   ClusterIP   172.30.136.18   <none>        8080/TCP,8443/TCP   21m
httpd2   ClusterIP   172.30.92.238   <none>        8080/TCP,8443/TCP   21m

# httpd1にログインして、httpd2のsvc, podにアクセスできるか確認する
$ oc rsh httpd1-1-2np89

sh-4.2$ curl -I 10.129.0.29:8080
HTTP/1.1 403 Forbidden
Date: Mon, 27 Apr 2020 03:54:24 GMT
Server: Apache/2.4.34 (Red Hat) OpenSSL/1.0.2k-fips
Last-Modified: Thu, 14 Nov 2019 15:39:25 GMT
ETag: "f91-597504935e540"
Accept-Ranges: bytes
Content-Length: 3985
Content-Type: text/html; charset=UTF-8

sh-4.2$ curl -I 172.30.92.238:8080
HTTP/1.1 403 Forbidden
Date: Mon, 27 Apr 2020 03:59:53 GMT
Server: Apache/2.4.34 (Red Hat) OpenSSL/1.0.2k-fips
Last-Modified: Thu, 14 Nov 2019 15:39:25 GMT
ETag: "f91-597504935e540"
Accept-Ranges: bytes
Content-Length: 3985
Content-Type: text/html; charset=UTF-8

#(index.htmlを設置していないので、403が返ってくるが、疎通はできている。)

sh-4.2$ exit

さらに、(NetworkPolicyオブジェクトがない状態で)別プロジェクトのPodと疎通できることを確認する。

$ oc new-project test2

$ oc new-app httpd --name=httpd3

$ oc get pods
NAME             READY   STATUS      RESTARTS   AGE
httpd3-1-deploy   0/1     Completed   0          43s
httpd3-1-grpgj    1/1     Running     0          35s

$ oc rsh httpd3-1-grpgj

sh-4.2$ curl -I 10.129.0.29:8080
HTTP/1.1 403 Forbidden
Date: Mon, 27 Apr 2020 04:10:44 GMT
Server: Apache/2.4.34 (Red Hat) OpenSSL/1.0.2k-fips
Last-Modified: Thu, 14 Nov 2019 15:39:25 GMT
ETag: "f91-597504935e540"
Accept-Ranges: bytes
Content-Length: 3985
Content-Type: text/html; charset=UTF-8

sh-4.2$ curl -I 172.30.92.238:8080
HTTP/1.1 403 Forbidden
Date: Mon, 27 Apr 2020 04:11:41 GMT
Server: Apache/2.4.34 (Red Hat) OpenSSL/1.0.2k-fips
Last-Modified: Thu, 14 Nov 2019 15:39:25 GMT
ETag: "f91-597504935e540"
Accept-Ranges: bytes
Content-Length: 3985
Content-Type: text/html; charset=UTF-8

そして、NetworkPolicyオブジェクトを作成して他プロジェクトからのトラフィックを制限する。

では、test1プロジェクトにNetworkPolicyオブジェクトを作成し、他プロジェクトからのトラフィックを拒否する。test2のPodから接続を試して拒否されるか確認する。

# 前のprojectに戻る
$ oc project test1

# NetworkPolicy作成
$ oc apply -f - <<EOF                                                                                                                                                                                            
kind: NetworkPolicy                                                                                                                                                                                             
apiVersion: networking.k8s.io/v1                                                                                                                                                                                  
metadata:                                                                                                                                                                                                         
 name: allow-same-namespace                                                                                                                                                                                      
spec:                                                                                                                                                                                                             
 podSelector:                                                                                                                                                                                                    
 ingress:                                                                                                                                                                                                        
 - from:                                                                                                                                                                                                         
   - podSelector: {}                                                                                                                                                                                             
EOF

# 同一プロジェクト内なら疎通可能なことを確認
sh-4.2$ curl -I 10.129.0.29:8080
HTTP/1.1 403 Forbidden
Date: Mon, 27 Apr 2020 04:26:47 GMT
Server: Apache/2.4.34 (Red Hat) OpenSSL/1.0.2k-fips
Last-Modified: Thu, 14 Nov 2019 15:39:25 GMT
ETag: "f91-597504935e540"
Accept-Ranges: bytes
Content-Length: 3985
Content-Type: text/html; charset=UTF-8

sh-4.2$ curl -I 172.30.92.238:8080
HTTP/1.1 403 Forbidden
Date: Mon, 27 Apr 2020 04:26:56 GMT
Server: Apache/2.4.34 (Red Hat) OpenSSL/1.0.2k-fips
Last-Modified: Thu, 14 Nov 2019 15:39:25 GMT
ETag: "f91-597504935e540"
Accept-Ranges: bytes
Content-Length: 3985
Content-Type: text/html; charset=UTF-8

sh-4.2$ exit

# test2プロジェクトに移動する
$ oc project test2

# 他プロジェクトからだと疎通不可であることを確認
$ oc rsh httpd3-1-grpgj

sh-4.2$ curl -I 10.129.0.29:8080
curl: (7) Failed connect to 10.129.0.29:8080; Connection timed out

sh-4.2$ curl -I 172.30.92.238:8080
curl: (7) Failed connect to 172.30.92.238:8080; Connection timed out

結果はこのように、NetworkPolicyオブジェクトを作成したことにより、期待通りtest2のPodから接続を試して拒否された。

補足

OpenShift SDNについて調べていてわかったことが数点あったので、最後に挙げておく。

・基本的には後からモード変更するのはやめといた方が良いらしい。https://access.redhat.com/solutions/4628831

・ただし、OCP3でmultitenant modeからnetworkpolicy modeに変更する方法はある。https://docs.openshift.com/container-platform/3.9/install_config/configuring_sdn.html#migrating-between-sdn-plugins-networkpolicy

・multitenantとsubnetは将来的に無くなりそうな気配? https://access.redhat.com/solutions/3903301

執筆者:株式会社リアルグローブ・オートメーティッド技師 青島――――――――――――――――――――――――――――――――――

執筆者プロフィール:青島 秀治
株式会社リアルグローブ・オートメーティッド 技師
九州大学大学院理学府博士課程中退。
大学院では理論天文学が専門。数値計算プログラム開発の傍ら、研究用の計算機郡や学内システムの開発・運用を経験。
2019年よりAnsibleを用いた運用作業自動化や自社サービスのKubernetes移行、OpenShiftのインフラCI実装などの業務に従事。

【ご案内】
ITシステム開発やITインフラ運用の効率化、高速化、品質向上、その他、情シス部門の働き方改革など、IT自動化導入がもたらすメリットは様々ございます。

IT業務の自動化にご興味・ご関心ございましたら、まずは一度、IT自動化の専門家リアルグローブ・オートメーティッド(RGA)にご相談ください!

お問合せは以下の窓口までお願いいたします。

【お問い合わせ窓口】
代表窓口:info@rg-automated.jp
URL: https://rg-automated.jp

画像1