6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[OpenShift Virtualization] VMを追加のOverlay Networkに参加させ、静的IPを振ってLive Migrationしたりアクセス制御したりして遊ぶ

Last updated at Posted at 2024-05-25

はじめに

この記事では、前回の記事の続きとして、仮想マシンのLive Migration前後で変わらないIPアドレス(静的IPアドレス)を付与します。また、その静的IPアドレスを用いてアクセス制御を試してみます。

OpenShiftのOverlay Networkについて

この記事の内容を読み進める上では、OpenShift上でPod(インスタンス)達が相互に通信する為の仮想ネットワーク(Overlay Network)に関するイメージを持っておくことが重要です。KubernetesはCNI(Container Network Interface)プラグインを適用する事で、Cluster上に任意のOverlay Networkを展開することができますが、OpenShiftではver4.14から「OVN-Kubernetes CNI」をデフォルトに採用しています。

ver 4.13までデフォルトだった「OpenShift SDN CNI」は、ver4.14以降は非推奨になりました。詳細はこちらを参照ください。

Overlay NetworkとPod達の関係を絵にすると以下のようになります。
パッと見難しそうなのですが、実はとても簡単です。順を追って解説します。
image.png

同一Node内に閉じたPod間通信

これは、各Pod同士がレイヤ2(L2)で通信可能です。「OVN-Kubernetes CNI」は仮想的なL2スイッチとしてOpen vSwitch(OVS)を採用し、Podに割り当てられた仮想NIC(名称はeth0)に振られたMACアドレスで通信します。つまり、同一ホスト内に閉じてL2レベルで通信しているということです。

Nodeを跨いだPod間通信

既にOpenShift/Kubernetes上にコンテナやVMをDeployして通信させた事のある方は、特にコンテナやVMがどのNodeの上で起動しているのかを意識していないと思いますが、しかしよく考えると変です。Nodeを跨いだ通信は一体どうやって実現しているのか?と。更に、同じLANにつながっているNodeならいざ知らず、例えばNodeが異なるAvailability Zone(AZ)に跨っている場合など、いったいPod同士はどうやってお互いのMACアドレスを宛先に通信できているのでしょうか?

その実現手段が「L2 over L3」という技術です。あるいは「トンネリング」と呼びます。ここでは詳細は割愛します(ググってみてください)が、ざっくりいうとレイヤ3(L3)の世界、つまりIPの世界において仮想的なトンネルを張り、Pod同士を物理アドレス(MACアドレス)で通信させています。

このトンネリングのプロトコルは様々なものがあります。例えば「VXLAN(仮想拡張可能LAN)」や「NVGRE(汎用ルーティングカプセル化を使用したネットワーク仮想化)」が有名です。特に、従来OpenShiftに採用されていたデフォルトのCNIプラグインである「OpenShift SDN CNI」はトンネリングプロトコルとして「VXLAN」を採用していました。「VXLAN」にはCPU使用率の上昇を招くという欠点があり(詳細はこちら)、それも踏まえて現在の「OVN-Kubernetes CNI」では「Geneve」というプロトコルが採用されています。マニアックな話ですし、L2 over L3のトンネルはOpenShiftのインストール時に自動的に作成されます。よって特にクラスター管理者が意識するものでもありません。

これによって、Node達が接続されている物理的なネットワーク(Underlay Network)を介して、Pod同士が通信されるわけですが、しかし当のPod達はそんなものは意識しません。自分たちはNode内に閉じた通信だろうが、Nodeを跨いだ通信だろうが、仮想的にPod達が参加するネットワーク、つまりOverlay Networkしか意識する事はありません。

なお、このデフォルトのOverlay Networkである「Pod Network(Cluster Networkともいう)」はPod間の通信のみならず、Kubernetes Clusterとの通信にも使われます。例えば、Podのヘルスチェックや、各種メトリクスの収集 等、いわゆる「U-Plane」のみならず「C-Plane」の通信も走っています。

Pod Networkに参加するPod達は、作成されたタイミングで自動的にCluster内でユニークなIPアドレスを振られます。ただし、Podが再作成されたり、Nodeを跨いだリスケジュールが行われる際には、IPアドレスは勝手に変わります。

これは、以前の記事でVMをLive Migrationした際にも確認できました。

Overlay Networkは追加できる

Podに複数の仮想NICを追加する事ができるCNIプラグインである「Multus CNI」を利用する事で、Podをデフォルトのネットワーク以外のOverlay Networkに参加させることができます。
image.png

また、今回は試すことはできませんが、Node(サーバ)が複数の物理NICを有しており、それぞれが異なるUnderlay Networkに接続している場合、Underlay Networkのレベルでも通信を分離することが可能です。

上の図でいう「Overlay Network 1」はデフォルトのPod Networkです。つまり、eth0にはPod Networkから自動的にIPアドレスが付与され、仮にVM(を内包するPod)がLive Migrationした場合は、勝手にIPアドレスが変わります。しかし、任意で追加する「Overlay Network 2」に接続しているeth1は、静的IPアドレスを振ることが可能です。これにより、VMが再作成されたりLive Migrationしても変わらない、「そのVM固有のIPアドレス」を保持させることが可能です。

というわけで、早速やっていきます。

VMを追加ネットワークに参加させよう

まずはOpenShift Cluster内に二つめのOverlay Networkを作成します。
image.png

とても簡単に作れます。

NetworkAttachmentDefinitionsの作成

追加のOverlay Networkの展開は、NetworkAttachmentDefinitions(NAD)と呼ばれるリソースを作成する事で可能です。

今回はNameSpace: virtual-machineに「OVN Kubernetes L2 overlay network」を作成します。
こちらのNADのテンプレを使ってoc apply -fでサクッと作成できてしまいます。

こちらのNADのテンプレではMTU=1300という設定が入っていますが、特にMTUの設定は不要です。MTUはLinux Kernelが自動的に設定(ただしデフォルト値が1300になっている)します。また、OVN-Kubernetesは1500byteを超えるイーサネットフレーム(ジャンボフレーム)にも対応しています。

apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: l2-network
  namespace: virtual-machine
spec:
  config: |
    {
            "cniVersion": "0.3.1", 
            "name": "virtual-machine-l2-network", 
            "type": "ovn-k8s-cni-overlay", 
            "topology":"layer2", 
            "netAttachDefName": "virtual-machine/l2-network" 
    }

これでOverlay Networkの追加が完了しました。
image.png

詳細は後述しますが、「OVN-Kubernetes CNI」は追加ネットワークに適用できるMultiNetworkPolicyに対応しており、そのおかげでアクセス制御も容易に実施できるのです。

VMを作成する

VMの作成については、前回の記事を参照頂き、

  • StorageClassocs-storagecluster-ceph-rbd-virtualizationを選択し、Live Migration可能なRWXPersistentVolume(PV)をプロビジョニングできる様にする
  • SSHするための公開鍵を登録する
    を実施しますが、加えて以下二つの作業を行います。
  • 追加のNetwork Interfaceeth1を設定する
  • eth1に静的IPアドレスを設定する

つまり、これから作成するVM(名称はfedora-sourceとしておきます)と2つのOverlay Networkの関係はこんな感じです。
image.png

作成時に追加のNetwork Interfaceを設定する

VM作成のカスタマイズ画面にてタブ「Network interfaces」から「Add network interface」をクリックします。
インターフェース名はランダムに割り当てられますが、任意の好きなものを設定する事も可能です。
「Network」は、既に追加済みのNADがあれば選択されている状態です。複数のNADがあればプルダウンから選べます。
今回は必要な設定がされているので、このまま「Save」をクリックします。
image.png

これでNetwork Interfaceeth1の追加が完了です。
image.png

eth1に静的IPアドレスを設定する

VM作成画面のタブ「Scripts」に移動します。SSH公開鍵の登録は「Public SSH key」から行いましたが、今回は「Cloud-init」欄の「Edit」から、VM作成時に初回のみ実施する設定を行います。

「Add network data」にチェックを入れると、Network Interfaceの設定を入れられます。
image.png

対象の「Ethernet name」と付与したい「IP addreses」を入力し、「Apply」をクリックします。
これでOKです。VMの名前をfedora-sourceとして、「Create VirtualMachine」をクリックしてVMを作成します。

VMが起動すると、Pod Networkに接続しているeth0には自動的にIPアドレスが振られますが、追加したOverlay Networkに接続しているeth1には指定した静的IPアドレス192.168.100.10が振られます。
image.png

Live Migrationしてeth1のIPアドレスが変わらないか確認する

Live Migration前の各種情報は以下です。

  • Node: ip-10-0-64-154.ap-northeast-3.compute.internal
  • IP address:
    • default(=eth0): 10.129.8.114
    • nic-plum-dog-12(=eth1): 192.168.100.10

なお、VMの詳細情報はoc describe vmiコマンドで確認することも可能です。Interfaceseth0及びeth1の情報を確認できます。なお「OVN-Kubernetes」はIPv6/IPv4のデュアルスタックに対応しており、実はeth1にはIPv6アドレスも設定されますが今回は気にしません。

~ % oc describe vmi fedora-source
(中略)
  Interfaces:
    Info Source:     domain, guest-agent
    Interface Name:  eth0
    Ip Address:      10.129.8.114
    Ip Addresses:
      10.129.8.114
    Mac:             02:7b:6f:00:00:2c
    Name:            default
    Queue Count:     1
    Info Source:     domain, guest-agent, multus-status
    Interface Name:  eth1
    Ip Address:      192.168.100.10
    Ip Addresses:
      192.168.100.10
      fe80::e46:cadf:ece1:1dd0

では、Migrateしてみます。
image.png

Live Migration後の情報を見ます。

  • Node: ip-10-0-49-4.ap-northeast-3.compute.internal
  • IP address:
    • default(=eth0): 10.131.4.36
    • nic-plum-dog-12(=eth1): 192.168.100.10

image.png

eth1のIPアドレスは変わっていません!これでVMに固有の静的IPアドレスを振れる事が確認できました。

同じ手順でもう一つのVMを作成する。

この後のMultiNetworkPolicyを試す為に、全く同様の手順でもう一つのVM(名前はfedora-destination、静的IPアドレスは192.168.100.20とする)を作成してください。
image.png

2つの仮想NICが付いた2つのVM、それぞれが2つのOverlay Networkに接続している状態です。

2nd Overlay Network内でVM同士の通信状況を確認する

2つのVMはそれぞれ仮想NICeth1が2nd Overlay Networkに接続しています。ということは通信可能ということ。
tracerouteコマンドで疎通状況を確認してみます。

前回の記事を参考にして、fedora-sourceにSSH接続しておきます。tracerouteをインストールしておいてください。

[fedora@fedora-source ~]$ sudo yum install traceroute -y

fedora-destinationのIPアドレス192.168.100.20tracerouteしてみます。

[fedora@fedora-source ~]$ traceroute 192.168.100.20
traceroute to 192.168.100.20 (192.168.100.20), 30 hops max, 60 byte packets
 1  192.168.100.20 (192.168.100.20)  3.698 ms *  3.656 ms

当然ながら1ホップで到達しました。次に、fedora-sourceを踏み台サーバにしてfedora-destinationにSSHしてみます。今からやることはこんな感じ。
image.png

そのためにはfedora-sourceに対して、fedora-destinationに登録しておいた公開鍵のペアである秘密鍵を転送しておく必要があるので、SCPコマンドを使ってローカルからid_rsaを転送します。oc login済みのターミナルでvirtctlコマンドの中にSCPコマンドを盛り込むことができます。virtctlコマンド、地味に便利だ...

~ % virtctl -n virtual-machine scp <path_to_sshkey> fedora@fedora-source:~/ --identity-file=<path_to_sshkey>

<path_to_sshkey>id_rsaのパスです。

ファイルが転送されたっぽいですが、ちゃんと転送されたか、fedora-sourceにSSHして見てみます。

~ % virtctl -n virtual-machine ssh fedora@fedora-source:~/ --identity-file=<path_to_sshkey>

lsコマンドで確認。あとid_rsaがオーナーのみ参照・更新できる権限かも見ておきます。

[fedora@fedora-source ~]$ ls -la | grep id_rsa
-rw-------. 1 fedora fedora 2622 May 24 16:12 id_rsa

大丈夫そうです。では、このままfedora-destinationにSSHしてみます。

[fedora@fedora-source ~]$ ssh -i id_rsa 192.168.100.20
[fedora@fedora-destination ~]$ 

できました!

VMを踏み台サーバにして別のVMに入る。こうした作業がOpenShiftの上で行われている事が面白いですね。つまり、OpenShift VirtualizationはVMの為の基盤としてもとても自然に動作します。

この後、MultiNetworkPolicyを適用した状態でもう一回SSHしますので、一度exitしておいて、踏み台サーバに戻って来ておきます。

[fedora@fedora-source ~]$ ssh -i id_rsa 192.168.100.20
Last login: Sat May 25 03:29:46 2024 from 192.168.100.10

[fedora@fedora-destination ~]$ exit
logout
Connection to 192.168.100.20 closed.

[fedora@fedora-source ~]$

MultiNetworkPolicyを設定し、2つのVM間のアクセス制御を行う

MultiNetworkPolicyNetworkPolicyと名前が似ています。後者はPod Network内における、その名の通り「ネットワークポリシー」を設定するCustom Resourceです。

NetworkPolicyの詳細はこちらを御覧ください。

MultiNetworkPolicyは追加ネットワークに対するネットワークポリシーを設定できるCustom Resourceです。NetworkPolicy自体のAPIが使えますので、記法は同じです。

なお、OpenShiftのデフォルトではMultiNetworkPolicyのAPIが使えませんので、有効化しておきます。方法はOpenShiftのドキュメントで公開されていますので、こちらを参考にして有効化しておきます。要はnetwork.operator.openshift.ioをいじるわけです。

ローカルでmultinetwork-enable-patch.yamlを作成して、

apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  name: cluster
spec:
  useMultiNetworkPolicy: true

oc patchしてください。

oc patch network.operator.openshift.io cluster --type=merge --patch-file=multinetwork-enable-patch.yaml

これでapiVersion: k8s.cni.cncf.io/v1beta1が使えるようになりました。

いよいよMultiNetworkPolicy(MNP)を作ります。今回MNPを適用する2nd Overlay NetworkはNameSpace: virtual-machineにありますので、同じNameSpaceにMNPをapplyしてます。

リソース名はmnp-ingress-vm.yamlとしました。

OVN-KuberneteとMNPの互換性についてはこちらを参照ください。

apiVersion: k8s.cni.cncf.io/v1beta1
kind: MultiNetworkPolicy
metadata:
  name: mnp-ingress-vm
  namespace: virtual-machine
  annotations:
    k8s.v1.cni.cncf.io/policy-for: virtual-machine/l2-network
    # ここでMNPを適用する追加NWを指定します。
    # 以下の記法はNetworkPolicyと全く同じです。
spec:
  podSelector:
    matchLabels:
      vm.kubevirt.io/name: fedora-destination
      # MNPを適用するPodを特定するkeyを指定します。今回はPod名をそのまま指定します。
  policyTypes:
    - Ingress
  ingress:
    - from:
        - ipBlock:
            cidr: 192.168.100.30
            except: []
      ports:
        - protocol: TCP
          port: 22

このポリシーは「fedora-destinationに対して、IPアドレス192.168.100.30から22番ポートにのみInのアクセスを認める」というポリシーです。

さて、IPアドレス192.168.100.30fedora-sourceのIPアドレス192.168.100.10とは異なります。ということは、このMultiNetworkPolicyを適用してしまうと、fedora-sourceからfedora-dextinationにSSHできなくなってしまうはずです。

試してみましょう。上記のmnp-ingress-vm.yamloc apply -fしてください。
image.png

再度、fedora-sourceからfedora-destinationにSSHを試みます。

[fedora@fedora-source ~]$ ssh -i id_rsa 192.168.100.20

あれれ、いつまでたっても接続できません。そりゃそうです。ctrl + cで中断します。
GUIでMNPのYAMLを修正してみます。cidrのIPアドレスをfedora-sourceのIPアドレス192.168.100.10に変更して「保存」をクリックします。
image.png

もう一回SSHを試します。

[fedora@fedora-source ~]$ ssh -i id_rsa 192.168.100.20
Last login: Sat May 25 03:33:16 2024 from 192.168.100.10
[fedora@fedora-destination ~]$ 

今度はちゃんとSSHできました。

おわりに

OpenShiftの追加ネットワークを設定し、OpenShift Virtualization上で建てたVM間の疎通を確認しました。またVMに静的IPアドレスを振ってネットワークポリシーを適用したりしました。
これまでのVMの運用のあり方をOpenShift上でも遜色なく適用する事が確認できました。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?