Red Hat OpenShift 仮想化におけるLocalnet UDNの例
CUDN Localnetネットワークを使用して、 OpenShift の仮想化VMを IBM Cloud VPC のサブネットに接続し、VLANを基盤とし、ネームスペースが分離されたトラフィックを実現します。
このチュートリアルでは、 IBM Cloud 上の Red Hat OpenShift on IBM Cloud において、Virtual Private Cloud(VPC)サブネット、Cluster User-Defined Networks(CUDN)、localnet、およびネームスペースを使用して、3層アプリケーションのサンプルを作成する方法について説明します。 この例では、仮想ローカルエリアネットワーク(VLAN)を基盤とするローカルネットネットワークを使用して、 Red Hat OpenShift Virtualization上で実行される仮想サーバーをVPCサブネットに直接接続する方法を示しています。 ネットワークの種類に関する詳細については、 『 vSphere® 』の管理者向けドキュメントにある「 Red Hat OpenShift の Open Virtual Network(OVN)ネットワーク 」を参照してください。
概要
この例では、Web層、データベース層、アプリケーション層ごとに別々のネットワークセグメントを持つ3層アプリケーションをデプロイします。 各ティアでは、専用のVPCサブネットと、一意のVLAN IDを持つローカルネットCUDNが使用されます。 Web層とデータベース層は1つのネームスペース(green )に配置され、アプリケーション層は別のネームスペース(red )に配置されています。これは、ネームスペースに基づく分離を実証するためのものです。
ネットワーク、ネームスペース、および仮想サーバーの詳細
次の表は、ネットワーク構成の例をまとめたものです。
| Localnet CUDN | 名前空間 | VLAN ID | VPC サブネット | 仮想サーバー |
|---|---|---|---|---|
vlan20-prod |
green |
20 | 198.18.0.0/24 | plant-web00, plant-web01 |
vlan21-db |
green |
21 | 198.18.1.0/24 | plant-db00, plant-db01 |
vlan22-app |
red |
22 | 198.18.2.0/24 | plant-app00, plant-app01 |
最終的な構成の図
このガイドにある各コードブロックは、ファイルにコピーして、 oc apply -f <file-name>.yml で実行することができます。 PDFやWord形式では、一部のコードブロックがページをまたぐ場合があり、また、長い行が改行される場合があります。
このガイドでは、 IBM Cloud のCLIコマンドにおいて、「 ibmcloud 」の略語として「 ic 」を使用しています。 シェルで alias ic=ibmcloud を定義するか、以下のコマンドにおいて ic を ibmcloud に置き換えてください。
開始前に
以下の項目がすべて整っていることを確認してください:
- VPCおよび Red Hat OpenShift リソースを管理する権限を持つ IBM Cloud アカウント。
- IBM Cloud のCLIがインストールされました。
- 「
container-service」および「vpc-infrastructure」プラグインがインストールされました。
container-service プラグインは、このガイドでクラスタにVLAN仮想ネットワークインターフェイス(VNI)をアタッチするために使用される ic ks コマンドを提供します。 vpc-infrastructure プラグインは、このガイドでVPCサブネット、仮想ネットワークインターフェイス(VNI)、およびその他のインフラストラクチャを作成するために使用される ic is コマンドを提供します。
必要なCLIプラグインをインストールする必要がある場合は、以下のコマンドを実行してください。
ibmcloud plugin install container-service
ibmcloud plugin install vpc-infrastructure
ネットワークの前提条件を確認する
Red Hat OpenShift on IBM Cloud をご利用の場合は、作業を開始する前に、 Red Hat OpenShift on IBM Cloud の「OVN UDN/CUDN ネットワークの前提条件 」をご確認ください。 Red Hat OpenShift Virtualization Service には、デフォルトでこれらの前提条件が含まれています。
グリーンティア用の名前空間とCUDN Localnetセカンダリネットワークの作成
Localnet ネットワークは、 Layer 2 のプライマリネットワーク、 Layer 2 のセカンダリネットワーク、および同じネームスペース内の他の Localnet ネットワークと共存することができます。 各ローカルネットには、 VLAN ID が必要です。 現在、VLAN 1つにつき1つのサブネットしか使用できません。
このVLANでは、ワーカー間で Layer 2 ドメインは作成されません。 VLANは、VPC内ではなく、各ワーカーノード内で使用されます。
green ネームスペース、および vlan20-prod と vlan21-db のネットワークを作成します。 oc apply -f step1.yml を実行して、マニフェストを適用します。
---
apiVersion: v1
kind: Namespace
metadata:
name: green
---
apiVersion: k8s.ovn.org/v1
kind: ClusterUserDefinedNetwork
metadata:
name: "vlan20-prod"
spec:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- "green"
network:
topology: Localnet
localnet:
role: "Secondary"
physicalNetworkName: "vpc-vlans"
ipam:
mode: Disabled
vlan:
mode: Access
access:
id: 20
---
apiVersion: k8s.ovn.org/v1
kind: ClusterUserDefinedNetwork
metadata:
name: "vlan21-db"
spec:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- "green"
network:
topology: Localnet
localnet:
role: "Secondary"
physicalNetworkName: "vpc-vlans"
ipam:
mode: Disabled
vlan:
mode: Access
access:
id: 21
以下の点に留意してください:
Localnetの設定でサブネットが定義されていません。VLAN 1は使用しないでください。- VLANは2~500の範囲で設定してください。 現在、VLAN 501 ~ 4094 は利用が制限されています。
red ティア用に、別のネームスペースと CUDN Localnet セカンダリネットワークを作成する
「 red 」ネームスペースと「 vlan22-app 」ネットワークを作成します。 oc apply -f step2.yml を実行して、マニフェストを適用します。
---
apiVersion: v1
kind: Namespace
metadata:
name: red
---
apiVersion: k8s.ovn.org/v1
kind: ClusterUserDefinedNetwork
metadata:
name: "vlan22-app"
spec:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- "red"
network:
topology: Localnet
localnet:
role: "Secondary"
physicalNetworkName: "vpc-vlans"
ipam:
mode: Disabled
vlan:
mode: Access
access:
id: 22
アカウントでの予約済みIPアドレスおよびVNIの作成
この手順では、各サブネットに予約済みIPアドレスを作成し、その予約済みIPアドレスを使用してVNIを作成した後、各仮想ネットワークインターフェースに MAC address を割り当てます(VNI )。
以下の点に留意してください:
- この手順では、
VLAN IDは接続されていません。 - この手順で使用するセキュリティグループを必ず確認してください。
ic is sgsを実行して、利用可能なセキュリティグループの一覧を表示します。 - この手順は一括で実行できます。
- ホストあたり256個のVNIが上限です。 フェイルオーバーや他のホストからの移行に備え、使用率を85%未満に抑えてください。
各サブネットに予約済みIPアドレスを作成する
まず、仮想サーバー用に各サブネットで予約済みIPアドレスを作成します:
ic is subnet-reserved-ip-create zone1-vm-prod --address 198.18.0.20 --name zone1-web00 --auto-delete false
ic is subnet-reserved-ip-create zone1-vm-db --address 198.18.1.20 --name zone1-db00 --auto-delete false
ic is subnet-reserved-ip-create zone1-vm-app --address 198.18.2.20 --name zone1-app00 --auto-delete false
予約済みIPアドレスを使用したVNIの作成
それでは、前の手順で予約したIP名を使用して、VNIを作成します:
ic is virtual-network-interface-create --name zone1-web00 --allow-ip-spoofing false --auto-delete false --protocol-state-filtering-mode disabled --enable-infrastructure-nat true --subnet zone1-vm-prod --vpc my-vpc --rip zone1-web00 --sgs handclap-roundworm-clique-eccentric --resource-group-name Default
ic is virtual-network-interface-create --name zone1-db00 --allow-ip-spoofing false --auto-delete false --protocol-state-filtering-mode disabled --enable-infrastructure-nat true --subnet zone1-vm-db --vpc my-vpc --rip zone1-db00 --sgs handclap-roundworm-clique-eccentric --resource-group-name Default
ic is virtual-network-interface-create --name zone1-app00 --allow-ip-spoofing false --auto-delete false --protocol-state-filtering-mode disabled --enable-infrastructure-nat true --subnet zone1-vm-app --vpc my-vpc --rip zone1-app00 --sgs handclap-roundworm-clique-eccentric --resource-group-name Default
VLAN VNI をクラスタに割り当てる
前の手順で作成した各VNIのIDを取得し、 IBM Cloud の container-service プラグインを使用して、そのVNIをクラスタに接続します。 クラスタ ID が必要です。これは、 ic ks cluster ls を実行することで取得できます。
以下の点に留意してください:
- ワーカーがVNIの割り当て量を超過している場合、関連する操作は失敗します。
- VNIは、クラスター(
floatingとも呼ばれる)または特定のワーカーに割り当てることができます。
VNI IDを調べてください。
ic is vni zone1-web00 | awk '$1 ~ /^ID/ {print $NF}'
ic is vni zone1-db00 | awk '$1 ~ /^ID/ {print $NF}'
ic is vni zone1-app00 | awk '$1 ~ /^ID/ {print $NF}'
各VNIを、対応するVLAN IDを持つクラスターに割り当ててください。 クラスター ID および VNI ID を、ご自身の環境の値に置き換えてください。
ic ks vni attach baremetal -c <CLUSTER_ID> --vni <VNI_ID_web00> --vlan 20
ic ks vni attach baremetal -c <CLUSTER_ID> --vni <VNI_ID_db00> --vlan 21
ic ks vni attach baremetal -c <CLUSTER_ID> --vni <VNI_ID_app00> --vlan 22
ネームスペースへの仮想サーバーの追加
以下のマニフェストは、1つの仮想サーバーを作成するための、 YAML の最小限のサンプルです。 このマニフェストは、名前空間やネットワークごとに更新することができます。 作成した各 VNI に対して、 MAC address が必要です。 ic is vnis を実行して一覧を表示し、 DHCP が正しく動作するように、テンプレートの「 macAddress 」フィールドを更新してください。
以下のコマンドを使用して、各 VNI の MAC address を確認してください。
ic is vni zone1-web00 | awk '/^Mac Address/ {print $NF}'
ic is vni zone1-db00 | awk '/^Mac Address/ {print $NF}'
ic is vni zone1-app00 | awk '/^Mac Address/ {print $NF}'
VNI ごとの出力例。 価値観が異なります:
02:00:01:00:98:A0
02:00:02:00:98:A5
02:00:02:00:98:AA
マニフェストを適用する前に、以下の点に留意してください:
- 各マニフェストのパスワードを更新してください。
- ログインするには、「
ssh_authorized_keys」フィールドに実際のSSH公開鍵を入力する必要があります。 - パスワードを使用したSSHは利用できません。
- すべての「
macAddress」という値を、前のコマンドで調べた該当するVNIの MACアドレスに置き換えてください。 「macAddress」は、DHCPが期待通りのIPアドレスを割り当てるように、VNIと一致している必要があります。
oc apply -f <file-name>.yml を使用して、以下のマニフェストをそれぞれ適用してください。 以下のリンクから、各マニフェストに直接移動できます。
greenネームスペース内の仮想サーバーplant-web00(vlan20-prodgreenネームスペース内の仮想サーバーplant-db00(vlan21-dbredネームスペース内の仮想サーバーplant-app00(vlan22-app
green ネームスペース内の仮想サーバー plant-web00 ( vlan20-prod
# Bare YAML to stand up a Red Hat OpenShift on IBM Cloud virtual machine
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: "plant-web00"
namespace: "green"
annotations:
description: "example vm plant-web00"
labels:
app: "plant-web00-green-server"
kubevirt.io/dynamic-credentials-support: 'true'
vm.kubevirt.io/template: "centos-stream9-server-small"
vm.kubevirt.io/template.namespace: openshift
vm.kubevirt.io/template.revision: '1'
vm.kubevirt.io/template.version: v0.34.0
spec:
dataVolumeTemplates:
- apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
creationTimestamp: null
name: "plant-web00-green-server"
spec:
sourceRef:
kind: DataSource
name: "centos-stream9"
namespace: openshift-virtualization-os-images
storage:
resources:
requests:
storage: 30Gi
runStrategy: RerunOnFailure
template:
metadata:
annotations:
vm.kubevirt.io/flavor: "small"
vm.kubevirt.io/os: "centos-stream9"
vm.kubevirt.io/workload: "server"
labels:
kubevirt.io/domain: example
kubevirt.io/size: "small"
spec:
domain:
cpu:
cores: 1
sockets: 1
threads: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- disk:
bus: virtio
name: cloudinitdisk
interfaces:
- model: virtio
name: default
state: up
bridge: {}
macAddress: 02:00:01:00:98:A0 # <- replace with the MAC of VNI zone1-web00
networkInterfaceMultiqueue: true
rng: {}
memory:
guest: "2Gi"
hostname: "plant-web00"
networks:
- name: default
multus:
networkName: vlan20-prod
terminationGracePeriodSeconds: 180
volumes:
- dataVolume:
name: "plant-web00-green-server"
name: rootdisk
- cloudInitNoCloud:
userData: |-
#cloud-config
user: admin
password: "aRandomPassword9292"
ssh_authorized_keys:
- "ssh-ed25519 AAAA....BBBB....CCCCC.....DDDD put-your-key-here@example.local"
chpasswd: { expire: False }
runcmd:
- [ dnf, install, -y, epel-release ]
- [ dnf, install, -y, iperf3, nmap-ncat, darkhttpd ]
name: cloudinitdisk
green ネームスペース内の仮想サーバー plant-db00 ( vlan21-db
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: "plant-db00"
namespace: "green"
annotations:
description: "example vm plant-db00"
labels:
app: "plant-db00-green-server"
kubevirt.io/dynamic-credentials-support: 'true'
vm.kubevirt.io/template: "centos-stream9-server-small"
vm.kubevirt.io/template.namespace: openshift
vm.kubevirt.io/template.revision: '1'
vm.kubevirt.io/template.version: v0.34.0
spec:
dataVolumeTemplates:
- apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
creationTimestamp: null
name: "plant-db00-green-server"
spec:
sourceRef:
kind: DataSource
name: "centos-stream9"
namespace: openshift-virtualization-os-images
storage:
resources:
requests:
storage: 30Gi
runStrategy: RerunOnFailure
template:
metadata:
annotations:
vm.kubevirt.io/flavor: "small"
vm.kubevirt.io/os: "centos-stream9"
vm.kubevirt.io/workload: "server"
labels:
kubevirt.io/domain: example
kubevirt.io/size: "small"
spec:
domain:
cpu:
cores: 1
sockets: 1
threads: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- disk:
bus: virtio
name: cloudinitdisk
interfaces:
- model: virtio
name: default
state: up
bridge: {}
macAddress: 02:00:01:00:98:A5 # <- replace with the MAC of VNI zone1-db00
networkInterfaceMultiqueue: true
rng: {}
memory:
guest: "2Gi"
hostname: "plant-db00"
networks:
- name: default
multus:
networkName: vlan21-db
terminationGracePeriodSeconds: 180
volumes:
- dataVolume:
name: "plant-db00-green-server"
name: rootdisk
- cloudInitNoCloud:
userData: |-
#cloud-config
user: admin
password: "aRandomPassword9292"
ssh_authorized_keys:
- "ssh-ed25519 AAAA....BBBB....CCCCC.....DDDD put-your-key-here@example.local"
chpasswd: { expire: False }
runcmd:
- [ dnf, install, -y, epel-release ]
- [ dnf, install, -y, iperf3, nmap-ncat, darkhttpd ]
name: cloudinitdisk
red ネームスペース内の仮想サーバー plant-app00 ( vlan22-app
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: "plant-app00"
namespace: "red"
annotations:
description: "example vm plant-app00"
labels:
app: "plant-app00-red-server"
kubevirt.io/dynamic-credentials-support: 'true'
vm.kubevirt.io/template: "centos-stream9-server-small"
vm.kubevirt.io/template.namespace: openshift
vm.kubevirt.io/template.revision: '1'
vm.kubevirt.io/template.version: v0.34.0
spec:
dataVolumeTemplates:
- apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
creationTimestamp: null
name: "plant-app00-red-server"
spec:
sourceRef:
kind: DataSource
name: "centos-stream9"
namespace: openshift-virtualization-os-images
storage:
resources:
requests:
storage: 30Gi
runStrategy: RerunOnFailure
template:
metadata:
annotations:
vm.kubevirt.io/flavor: "small"
vm.kubevirt.io/os: "centos-stream9"
vm.kubevirt.io/workload: "server"
labels:
kubevirt.io/domain: example
kubevirt.io/size: "small"
spec:
domain:
cpu:
cores: 1
sockets: 1
threads: 1
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- disk:
bus: virtio
name: cloudinitdisk
interfaces:
- model: virtio
name: default
state: up
bridge: {}
macAddress: 02:00:01:00:98:AA # <- replace with the MAC of VNI zone1-app00
networkInterfaceMultiqueue: true
rng: {}
memory:
guest: "2Gi"
hostname: "plant-app00"
networks:
- name: default
multus:
networkName: vlan22-app
terminationGracePeriodSeconds: 180
volumes:
- dataVolume:
name: "plant-app00-red-server"
name: rootdisk
- cloudInitNoCloud:
userData: |-
#cloud-config
user: admin
password: "aRandomPassword9292"
ssh_authorized_keys:
- "ssh-ed25519 AAAA....BBBB....CCCCC.....DDDD put-your-key-here@example.local"
chpasswd: { expire: False }
runcmd:
- [ dnf, install, -y, epel-release ]
- [ dnf, install, -y, iperf3, nmap-ncat, darkhttpd ]
name: cloudinitdisk
ネットワーク設定のテスト
IBM これらのテストを行う際は、クラスターと同じVPC内の Linux® ジャンプホストを使用することを推奨します。 ジャンプホストから、仮想サーバーの設定で指定した公開鍵を使用して、各仮想サーバーにSSHで接続します。
SSHエージェント転送を設定するか、ジャンプホスト上にホストされている新しい鍵を使用してください。 秘密鍵をシステム間でコピーしないでください。
1つのターミナルセッションから、SSHを使用してWeb層の仮想サーバーに接続します:
ssh admin@198.18.0.20
別のターミナルセッションから、SSH を使用してデータベース層の仮想サーバーに接続します:
ssh admin@198.18.1.20
別のターミナルセッションから、SSH を使用してアプリケーション層の仮想サーバーに接続します:
ssh admin@198.18.2.20
テスト (Tests)
ネットワークの設定を確認するために、以下のテストを実行してください。
-
各仮想サーバー上で、簡易版の HTTP サーバーを起動します。
198.18.0.20から、darkhttpd /usr/share/doc/bash --daemonを実行してください。198.18.1.20から、darkhttpd /usr/share/doc/bash --daemonを実行してください。198.18.2.20から、darkhttpd /usr/share/doc/bash --daemonを実行してください。
-
198.18.0.20から、curl -v http://198.18.1.20:8080を実行してください。 -
198.18.1.20から、curl -v http://198.18.0.20:8080を実行してください。 -
jump仮想サーバーから、
curl -v http://198.18.2.20:8080を実行してください。 -
198.18.1.20から、iperf3サーバーを起動します:iperf3 -s -p 9090。 -
198.18.0.20から、greenネームスペース内のiperf3サーバーに接続します:iperf3 -c 198.18.1.20 -p 9090。 -
198.18.1.20から198.18.0.20へ、およびその逆方向へ ping を実行します。 -
198.18.2.20およびジャンプ仮想サーバーの IP アドレスを使用して、前述のタスクを再実行してください。
マルチネットワークポリシーを適用し、テストを再実行する
vlan20-prod ネットワークに対して、 TCP のポート8080のみを許可するマルチネットワークポリシーを適用します。 以下のマニフェストを「 my-policy.yml 」という名前のファイルとして保存してください。 その後、 oc apply -f my-policy.yml を実行して適用してください。
---
apiVersion: k8s.ovn.org/v1alpha1
kind: MultiNetworkPolicy
metadata:
name: allow-8080-tcp
namespace: green
annotations:
k8s.v1.cni.cncf.io/policy-for: vlan20-prod
spec:
podSelector: {}
ingress:
- ports:
- protocol: TCP
port: 8080
egress:
- ports:
- protocol: TCP
port: 8080
policyTypes:
- Ingress
- Egress
vlan20-prod 上の plant-web00 に対して、 テスト を再実行してください。 TCP ポート8080は依然として機能していますが、 ping やポート9090での iperf3 テストなど、その他のトラフィックは、そのネットワーク接続では機能しなくなりました。
oc delete -f my-policy.yml を実行して、ポリシーを削除し、接続を復元してください。 テストは再び成功しました。