오픈스택을 설치할 때 상황이나 구성에 따라 설치 컴포넌트 선정이나 설정이 달라지게 됩니다
이번에는 다음과 같은 구성에 대해서 생각해 보도록 하죠

하나의 클러스터에서 두 개의 외부 네트워크를 사용하게 되는 경우를 가정해 보도록 하겠습니다
각각의 네트워크를 사용할 수 있는 컴퓨트 노드가 그룹으로 있을거고 각 그룹은 기본적으로 접근이 안되도록 분리하는게 보안적으로 더 좋아보입니다

이렇게 분리된 2개의 네트워크, 컴퓨트 노드 그룹을 가용성 영역(Availability zone, 이후 AZ)을 사용하여 kolla ansible 로 설치해 보도록 하겠습니다.

네트워크 구성

일단 네트워크부터 구성해 보도록 하겠습니다.

VM간의 게스트 네트워크도 같이 분리한 네트워크 구성

외부 네트워크만 영역별로 나누려고 했었는데 VM간의 게스트 네트워크도 같이 분리했습니다.

  • api/internal 은 오픈스택의 컴포넌트 간 내부 통신용으로 사용하게 되고, 옥타비아(LB)를 설치할 예정이어서 옥타비아 관리 네트워크 용도로 관리존의 게스트 네트워크도 같이 쓰게 하겠습니다.
    • 10.10.101.0/24 (vlan 101)
  • managemnt 는 일반적인 노드 관리 및 배포를 할 때 쓰고 또한 대시보드(Horizon) 접속용으로도 같이 쓰게할 예정입니다.
    • 192.168.52.0/24
  • internal과 external은 각 존의 게스트 네트워크 용도와 외부 네트워크 용도로 사용하게 되겠습니다.
    • zone01 internal 10.10.102.0/24 (vlan 102)
    • zone01 external 10.10.111.0/24 (vlan 111)
    • zone02 internal 10.10.103.0/24 (vlan 103)
    • zone02 external 10.10.112.0/24 (vlan 112)

옥타비아도 AZ를 사용해서 각 존에 배치되게 할 예정이라 각 존의 게스트 네트워크는 관리존의 게스트 네트워크와 통신할 수 있게 라우팅 설정을 하였습니다.

오픈스택 컴포넌트 구성

AZ를 사용해서 네트워크를 나누는게 목적이기 때문에 필수 컴포넌트를 제외하고는 설치하지 않겠습니다.

설치할 컴포넌트는 keystone, nova, glance(local disk 사용), cinder(lvm/iscsid 사용), neutron(ovs 사용, agent ha 구성), octavia, barbican 으로 하였습니다.

오픈스택 버전은 2023.2(bobcat) 입니다.

네트워크 컴포넌트 구성

목적에 맞게 네트워크 구성만 좀 더 설명해 보겠습니다.

옥타비아 컴포넌트는 관리노드에 설치되는 건 기존과 달라지지 않습니다.
AZ를 사용하더라도 결국 네트워크 설정은 neutron 컴포넌트 들이 하게 되기 때문에 각 존마다 네트워크 노드가 있어야 됩니다만 이번에는 각 존의 컴퓨트 노드들에게 네트워크 노드의 역할을 같이 하도록 하겠습니다.
관리노드도 옥타비아 관리 네트워크가 구성되어야 하기 때문에 네트워크 노드 역할을 같이 하게 됩니다.

그러면 다음과 같이 네트워크 컴포넌트들이 구성되게 됩니다.

서버 구성 정보

지금까지 구성한 오픈스택을 설치하기 위한 서버들은 다음과 같이 준비했습니다. KVM 서버를 이용해 VM들을 생성하고 openvswitch 를 이용해서 네트워크 닉을 구성했습니다. 각 서버의 OS는 Rocky 9.2 입니다.

그룹호스트명코어메모리스토리지서버IP비고
관리존manage-deploy48G60G,250Geth0, eth1x.x.x.100
manage-control011632G60Geth0, eth1x.x.x.101
manage-control021632G60Geth0, eth1x.x.x.102
manage-control031632G60Geth0, eth1x.x.x.103
zone01zone01-compute111632G60G,40G,40G,40Geth0, eth1,eth2,eth3x.x.x.111eth2 internal, eth3 external
zone01-compute121632G60G,40G,40G,40Geth0, eth1,eth2,eth3x.x.x.112eth2 internal, eth3 external
zone02zone02-compute211632G60G,40G,40G,40Geth0, eth1,eth2,eth3x.x.x.121eth2 internal, eth3 external
zone02-compute221632G60G,40G,40G,40Geth0, eth1,eth2,eth3x.x.x.122eth2 internal, eth3 external

오픈스택 설치

다음과 같은 순서로 설치를 해보도록 하겠습니다.

  1. 배포 환경 구성
  2. 배포 설정
  3. 배포

배포 환경 구성

배포서버에 kolla ansible 을 설치를 하여 배포준비를 하고 ansible 사용이 가능하게 된 후 각 노드들에 대한 설정을 하도록 하겠습니다.

# ssh hostkey checking disable
cat << EOF > /root/.ssh/config
Host *
  StrictHostKeyChecking  no
  UserKnownHostsFile /dev/null
EOF

# install require package
dnf -y install git python3 python3-devel \
    libffi-devel gcc openssl-devel python3-libselinux
dnf -y install sshpass qemu-img wget guestfs-tools

# kolla ansible virtualenv
mkdir -p /playcecloud/venv
python3 -m venv --system-site-packages /playcecloud/venv/kolla-ansible
source /playcecloud/venv/kolla-ansible/bin/activate
python -m pip install -U pip
pip install 'ansible-core>=2.14,<2.16'
pip install selinux
pip install git+https://opendev.org/openstack/kolla-ansible@stable/2023.2
kolla-ansible install-deps

# client 설치
pip install python-openstackclient \
  -c https://releases.openstack.org/constraints/upper/2023.2
pip install python-neutronclient \
  -c https://releases.openstack.org/constraints/upper/2023.2
pip install python-glanceclient \
  -c https://releases.openstack.org/constraints/upper/2023.2
pip install python-octaviaclient \
  -c https://releases.openstack.org/constraints/upper/2023.2
pip install python-barbicanclient \
  -c https://releases.openstack.org/constraints/upper/2023.2

배포 설정

각 설정 부분에서 모든 노드에 적용하게 되는 부분이 있어 ansible을 사용하게 됩니다. 따라서 아래 작업들은 대부분 kolla ansible 가상 환경이 적용되어 있는 상태에서 작업합니다.

기본 설정 파일 복사

# kolla
mkdir -p /etc/kolla
cp /playcecloud/venv/kolla-ansible/share/kolla-ansible/etc_examples/kolla/* \
   /etc/kolla/
cp /playcecloud/venv/kolla-ansible/share/kolla-ansible/ansible/inventory/multinode \
   /etc/kolla/

global.yml

필요한 정보라고 생각하는 것들만 남기고 삭제한 전체 yaml 파일을 보여드리도록 하겠습니다.

---
workaround_ansible_issue_8743: yes

# container image config
#config_strategy: "COPY_ALWAYS"
#kolla_base_distro: "rocky"
#openstack_release: "2023.2"
#openstack_tag: "{{ openstack_release ~ openstack_tag_suffix }}"
#openstack_tag_suffix: ""

#docker_registry:
#docker_registry_insecure: "no"
#docker_registry_username:
#docker_namespace: "kolla"

# network config
kolla_internal_vip_address: "10.10.101.254"
#kolla_internal_fqdn: "{{ kolla_internal_vip_address }}"
kolla_external_vip_address: "192.168.52.254"
#kolla_external_fqdn: "{{ kolla_external_vip_address }}"

network_interface: "eth1.101"
kolla_external_vip_interface: "eth0"
#api_interface: "{{ network_interface }}"
#tunnel_interface: "eth1.102"
#octavia_network_interface: "{{ api_interface }}"

# provider nic config is inventory file
#neutron_external_interface: "eth3"
#neutron_bridge_name: "br-ex"

#neutron_plugin_agent: "openvswitch"
#neutron_ipam_driver: "internal"

# TLS config
kolla_enable_tls_internal: "yes"
kolla_enable_tls_external: "yes"
#kolla_certificates_dir: "{{ node_config }}/certificates"
#kolla_external_fqdn_cert: "{{ kolla_certificates_dir }}/haproxy.pem"
#kolla_internal_fqdn_cert: "{{ kolla_certificates_dir }}/haproxy-internal.pem"
kolla_admin_openrc_cacert: "/etc/pki/tls/certs/ca-bundle.crt"
openstack_cacert: "/etc/pki/tls/certs/ca-bundle.crt"
kolla_copy_ca_into_containers: "yes"
#haproxy_backend_cacert: "{{ 'ca-certificates.crt' if kolla_base_distro in ['debian', 'ubuntu'] else 'ca-bundle.trust.crt' }}"
#haproxy_backend_cacert_dir: "/etc/ssl/certs"

kolla_enable_tls_backend: "yes"
kolla_verify_tls_backend: "no"
#kolla_tls_backend_cert: "{{ kolla_certificates_dir }}/backend-cert.pem"
#kolla_tls_backend_key: "{{ kolla_certificates_dir }}/backend-key.pem"

# component selection
#enable_openstack_core: "yes"
#enable_glance: "{{ enable_openstack_core | bool }}"
#enable_haproxy: "yes"
#enable_keepalived: "{{ enable_haproxy | bool }}"
#enable_keystone: "{{ enable_openstack_core | bool }}"
#enable_mariadb: "yes"
#enable_memcached: "yes"
#enable_neutron: "{{ enable_openstack_core | bool }}"
#enable_nova: "{{ enable_openstack_core | bool }}"
#enable_rabbitmq: "{{ 'yes' if om_rpc_transport == 'rabbit' or om_notify_transport == 'rabbit' else 'no' }}"
enable_barbican: "yes"
enable_cinder: "yes"
enable_cinder_backup: "no"
#enable_cinder_backend_iscsi: "{{ enable_cinder_backend_lvm | bool }}"
enable_cinder_backend_lvm: "yes"
enable_fluentd: "no"
enable_grafana: "no"
#enable_grafana_external: "{{ enable_grafana | bool }}"
enable_heat: "no"
#enable_horizon: "{{ enable_openstack_core | bool }}"
#enable_horizon_octavia: "{{ enable_octavia | bool }}"
#enable_iscsid: "{{ enable_cinder | bool and enable_cinder_backend_iscsi | bool }}"
enable_neutron_dvr: "no"
enable_neutron_agent_ha: "yes"
enable_neutron_provider_networks: "yes"
#enable_nova_ssh: "yes"
enable_octavia: "yes"
enable_octavia_jobboard: "no"
#enable_octavia_driver_agent: "{{ enable_octavia | bool and neutron_plugin_agent == 'ovn' }}"
enable_redis: "no"
#enable_placement: "{{ enable_nova | bool or enable_zun | bool }}"
enable_prometheus: "no"

# component config
## glance
#glance_backend_file: "yes"

## nova
#nova_compute_virt_type: "kvm"
#nova_console: "novnc"

## octavia
octavia_auto_configure: yes
octavia_network_type: tenant
#octavia_amp_network_cidr: 10.1.0.0/24
#octavia_amp_image_tag: "amphora"
octavia_loadbalancer_topology: "ACTIVE_STANDBY"

multinode

새로 생성하거나 변경된 부분만 보여드리도록 하겠습니다.

노드 기본 설정 부분

global.yml 에서 보면 tunnel_interface, neutron_external_interface, neutron_bridge_name 가 주석 처리 되어 있는데 inventory 파일에서 각각 다르게 적용하기 위해서 입니다.
한 화면에 보이게 하기 위해 호스트별 ansible 설정 부분을 \ 으로 구분해서 다음 줄로 표시되게 했는데 이 부분이 실제 inventory 파일에 적용되는지 확인하지 않았으므로 주의가 필요합니다.

[all]
manage-control01 ansible_host=192.168.52.101 tunnel_interface="eth1.101"
manage-control02 ansible_host=192.168.52.102 tunnel_interface="eth1.101"
manage-control03 ansible_host=192.168.52.103 tunnel_interface="eth1.101"
zone01-compute11 ansible_host=192.168.52.111 tunnel_interface="eth2.102" \
  neutron_external_interface="eth3,dum01" neutron_bridge_name="br-zone01,br-zone02"
zone01-compute12 ansible_host=192.168.52.112 tunnel_interface="eth2.102" \
  neutron_external_interface="eth3,dum01" neutron_bridge_name="br-zone01,br-zone02"
zone02-compute21 ansible_host=192.168.52.121 tunnel_interface="eth2.103" \
  neutron_external_interface="dum01,eth3" neutron_bridge_name="br-zone01,br-zone02"
zone02-compute22 ansible_host=192.168.52.122 tunnel_interface="eth2.103" \
  neutron_external_interface="dum01,eth3" neutron_bridge_name="br-zone01,br-zone02"

[all:vars]
ansible_user=root
ansible_password=<password>

[zone01]
zone01-compute11
zone01-compute12

[zone02]
zone02-compute21
zone02-compute22

[control]
manage-control01
manage-control02
manage-control03

[network:children]
control

[compute:children]
zone01
zone02

[monitoring:children]
control

[storage:children]
zone01
zone02
neutron 부분

각각 따로 설정이 필요하면 neutron-dhcp-agent, neutron-l3-agent, neutron-metadata-agent 등의 그룹에 각각 따로 적용해도 되지만 필요한 설정들이 neutron 그룹을 child로 적용되어 있어서 다음과 같이 neutron 에만 적용했습니다.

[neutron:children]
network
zone01
zone02

neutron 설정 파일

AZ와 관련된 설정을 neutron.conf 및 dhcp, l3 에이전트 설정에 추가합니다.
존에 따라서 설정 파일들이 다르게 적용 됩니다.

# kolla neutron 설정 디렉토리 생성
mkdir -p /etc/kolla/config/neutron/{zone01-compute11,zone01-compute12}
mkdir -p /etc/kolla/config/neutron/{zone02-compute21,zone02-compute22}

# neutron.conf
cat << EOF > /etc/kolla/config/neutron.conf
[DEFAULT]
network_scheduler_driver = \
neutron.scheduler.dhcp_agent_scheduler.AZAwareWeightScheduler
dhcp_load_type = networks
router_scheduler_driver = \
neutron.scheduler.l3_agent_scheduler.AZLeastRoutersScheduler
EOF

# ml2_conf.ini
cat << EOF > /etc/kolla/config/neutron/ml2_conf.ini
[ml2]
type_drivers = flat,vlan,vxlan

[ml2_type_vlan]
network_vlan_ranges = physnet1,physnet2

[ml2_type_flat]
flat_networks = physnet1,physnet2
EOF

# dhcp_agent.ini
## zone01
cat << EOF > /etc/kolla/config/neutron/zone01-compute11/dhcp_agent.ini
[AGENT]
availability_zone = zone01
EOF
cat << EOF > /etc/kolla/config/neutron/zone01-compute11/l3_agent.ini
[AGENT]
availability_zone = zone01
EOF
cat << EOF > /etc/kolla/config/neutron/zone01-compute12/dhcp_agent.ini
[AGENT]
availability_zone = zone01
EOF
cat << EOF > /etc/kolla/config/neutron/zone01-compute12/l3_agent.ini
[AGENT]
availability_zone = zone01
EOF
## zone02
cat << EOF > /etc/kolla/config/neutron/zone02-compute21/dhcp_agent.ini
[AGENT]
availability_zone = zone02
EOF
cat << EOF > /etc/kolla/config/neutron/zone02-compute21/l3_agent.ini
[AGENT]
availability_zone = zone02
EOF
cat << EOF > /etc/kolla/config/neutron/zone02-compute22/dhcp_agent.ini
[AGENT]
availability_zone = zone02
EOF
cat << EOF > /etc/kolla/config/neutron/zone02-compute22/l3_agent.ini
[AGENT]
availability_zone = zone02
EOF

패스워드 설정

주로 사용하게 되는 horizon 접속을 위해 해당 패스워드만 지정하고 나머지는 랜덤 생성했습니다.

# keystone for horizon
sed -i 's/^keystone_admin_password:.*/keystone_admin_password: <password>/g' \
  /etc/kolla/passwords.yml

# random gen
kolla-genpwd

인증서 생성

kolla 에서 제공하는 셀프 사인 인증서를 사용했습니다.

# root ca, haproxy tls
kolla-ansible -i /etc/kolla/multinode certificates
# octavia tls
kolla-ansible -i /etc/kolla/multinode octavia-certificates

노드 설정

스토리지 노드 설정

lvm 스토리지를 사용하므로 해당 볼륨을 생성하고 설정해줍니다.

# lvm config
ansible -i /etc/kolla/multinode storage -m shell \
  -a "dnf -y install lvm2"
ansible -i /etc/kolla/multinode storage -m shell \
  -a "pvcreate /dev/vdb /dev/vdc /dev/vdd"
ansible -i /etc/kolla/multinode storage -m shell \
  -a "vgcreate cinder-volumes /dev/vdb /dev/vdc /dev/vdd"
네트워크 노드 설정

네트워크 매니저를 사용하기 때문에 nmcli 로 설정을 합니다.

api ip 설정
# api - ip config
ansible -i /etc/kolla/multinode baremetal -m shell \
-a "nmcli con add type vlan con-name eth1.101 \dev eth1 id 101 ip4 \
10.10.101.{{ansible_host|regex_replace('[0-9]+.[0-9]+.[0-9]+.([0-9]+)','\1')}}/24"
internal ip 설정

인벤토리 그룹에 주의하면서 진행합니다.

# tunnel - ip config
## control
ansible -i /etc/kolla/multinode control -m shell \
  -a "nmcli connection modify eth1.101 +ipv4.routes '10.10.102.0/24 10.10.101.1'"
ansible -i /etc/kolla/multinode control -m shell \
  -a "nmcli connection modify eth1.101 +ipv4.routes '10.10.103.0/24 10.10.101.1'"
ansible -i /etc/kolla/multinode control -m shell \
  -a "nmcli con down eth1.101 && nmcli con up eth1.101"
## zone01
ansible -i /etc/kolla/multinode zone01 -m shell \
-a "nmcli con add type vlan con-name eth2.102 dev eth2 id 102 ip4 \
10.10.102.{{ansible_host|regex_replace('[0-9]+.[0-9]+.[0-9]+.([0-9]+)','\1')}}/24"
## zone02
ansible -i /etc/kolla/multinode zone02 -m shell \
-a "nmcli con add type vlan con-name eth2.103 dev eth2 id 103 ip4 \
10.10.103.{{ansible_host|regex_replace('[0-9]+.[0-9]+.[0-9]+.([0-9]+)','\1')}}/24"

dummy 닉 설정

external 네트워크 생성시 매핑할 물리닉을 physnet1,2 동일하게 맞추기 위해 더미 닉을 생성한다. kolla config를 사용하여 각각 설정할 수도 있을 것 같긴 하지만 따로 해보지 않았습니다.
매핑 정보는 inventory의 neutron_external_interface, neutron_bridge_name 설정을 같이 보면 됩니다.

# add dummy nic
ansible -i /etc/kolla/multinode compute -m shell \
-a "nmcli con add type dummy con-name dum01 ifname dum01"

배포

배포 준비

지금 까지 설정한 것으로 추가 기본 설정이 필요한 부분은 추가로 설정하고 설정에 이상이 없는지에 대한 확인하는 부분입니다.

# bootstrap
kolla-ansible -i /etc/kolla/multinode bootstrap-servers
# precheck
kolla-ansible -i /etc/kolla/multinode prechecks

배포

성능에 따라 다르겠지만 설정에 이상이 없다면 20~30분 정도면 배포가 완료가 됩니다.

kolla-ansible -i /etc/kolla/multinode deploy

배포 후 기본 설정

오픈스택이 배포가 되어도 일반적으로 사용하기 위해선 추가적인 리소스 생성/설정이 필요합니다.

CLI 환경 설정 파일 생성

셀프 사인으로 생성된 인증서 정보가 배포 서버에 들어가 있지 않아 해당 인증서 정보에 대한 업데이트를 수행합니다. 또한 octavia openrc 파일에 CA 설정이 없어 추가로 설정합니다.

# post-deploy
kolla-ansible -i /etc/kolla/multinode post-deploy

# root ca update
cp /etc/kolla/certificates/ca/root.crt \
  /etc/pki/ca-trust/source/anchors/openstack-ca.crt
update-ca-trust extract

# octavia openrc update
echo "export OS_CACERT=/etc/pki/tls/certs/ca-bundle.crt" \
  >> /etc/kolla/octavia-openrc.sh

# 이하 작업들은 admin-openrc.sh 적용하여 관리자 권한으로 작업한다
source /etc/kolla/admin-openrc.sh
가용성 영역 설정

컴퓨팅 자원을 두 개의 존으로 나누고 호스트들을 할당합니다.

# compute AZ 생성
openstack aggregate create zone01 --zone zone01
openstack aggregate create zone02 --zone zone02
# AZ 노드 추가
## zone01
openstack aggregate add host zone01 zone01-compute11
openstack aggregate add host zone01 zone01-compute12
## zone02
openstack aggregate add host zone02 zone02-compute21
openstack aggregate add host zone02 zone02-compute22
프로젝트 생성

자원을 사용할 존 별로 프로젝트를 생성합니다. flavor 와 같이 프로퍼티 설정으로 세부 설정이 가능하지만 이번엔 하지 않겠습니다.

# project 생성
openstack project create --description \
  "zone01 네트워크 컴퓨트 자원을 사용하는 프로젝트" zone01-project
openstack project create --description \
  "zone02 네트워크 컴퓨트 자원을 사용하는 프로젝트" zone02-project
보안 그룹 설정

테스트를 위해 모든 프로젝트의 보안그룹 포트를 오픈하도록 하겠습니다.

# all open - admin 프로젝트
DEFSECGRP=$(openstack security group list --project admin -f value -c ID)
openstack security group rule create --protocol icmp --ingress ${DEFSECGRP}
openstack security group rule create \
  --protocol tcp --dst-port 1:65535 --ingress ${DEFSECGRP}
openstack security group rule create \
  --protocol udp --dst-port 1:65535 --ingress ${DEFSECGRP}

# all open - zone01-project 프로젝트
DEFSECGRP=$(openstack security group list --project zone01-project -f value -c ID)
openstack security group rule create --protocol icmp --ingress ${DEFSECGRP}
openstack security group rule create \
  --protocol tcp --dst-port 1:65535 --ingress ${DEFSECGRP}
openstack security group rule create \
  --protocol udp --dst-port 1:65535 --ingress ${DEFSECGRP}

# all open - zone02-project 프로젝트
DEFSECGRP=$(openstack security group list --project zone02-project -f value -c ID)
openstack security group rule create --protocol icmp --ingress ${DEFSECGRP}
openstack security group rule create \
  --protocol tcp --dst-port 1:65535 --ingress ${DEFSECGRP}
openstack security group rule create \
  --protocol udp --dst-port 1:65535 --ingress ${DEFSECGRP}
FLAVOR 생성
# 테스트용 flavor 생성
openstack flavor create --vcpus 4 --ram 8192 --disk 50 C4R8D50
네트워크 생성

존 별로 내부 네트워크 외부 네트워크, 라우터를 생성하고 각각에 AZ 적용을 합니다.

# zone 01 conifg
## zone 01 provider
openstack network create --external --project zone01-project \
  --availability-zone-hint zone01 \
  --provider-network-type vlan \
  --provider-segment 111 \
  --provider-physical-network physnet1 \
  zone01-provider
openstack subnet create --project zone01-project \
  --network zone01-provider \
  --gateway 10.10.111.1 \
  --subnet-range 10.10.111.0/24 \
  --dhcp --allocation-pool start=10.10.111.10,end=10.10.111.250 \
  zone01-provider-subnet01

## zone 01 tenant 01
openstack network create --project zone01-project \
  --availability-zone-hint zone01 \
  --provider-network-type vxlan \
  zone01-tenant01
openstack subnet create --project zone01-project \
  --network zone01-tenant01 \
  --subnet-range 172.21.0.0/16 \
  zone01-tenant01-subnet01

## zone01 router
openstack router create --ha --project zone01-project \
  --availability-zone-hint zone01 --external-gateway zone01-provider \
  zone01-router
openstack router add subnet zone01-router zone01-tenant01-subnet01

# zone 02 conifg
## zone 02 provider
openstack network create --external --project zone02-project \
  --availability-zone-hint zone02 \
  --provider-network-type vlan \
  --provider-segment 112 \
  --provider-physical-network physnet2 \
  zone02-provider
openstack subnet create --project zone02-project \
  --network zone02-provider \
  --gateway 10.10.112.1 \
  --subnet-range 10.10.112.0/24 \
  --dhcp --allocation-pool start=10.10.112.10,end=10.10.112.250 \
  zone02-provider-subnet01

## zone 02 tenant 01
openstack network create --project zone02-project \
  --availability-zone-hint zone02 \
  --provider-network-type vxlan \
  zone02-tenant01
openstack subnet create --project zone02-project \
  --network zone02-tenant01 \
  --subnet-range 172.22.0.0/16 \
  zone02-tenant01-subnet01

## zone02 router
openstack router create --ha --project zone02-project \
  --availability-zone-hint zone02 --external-gateway zone02-provider \
  zone02-router
openstack router add subnet zone02-router zone02-tenant01-subnet01

옥타비아 가용성 영역 설정

마찬가지로 옥타비아에도 가용성 영역을 설정합니다.

MGMTNET=$(openstack network show lb-mgmt-net -f value -c id)
# 옥타비아 가용성 영역 설정  - 가용성 영역 프로필
openstack loadbalancer availabilityzoneprofile create \
  --name zone01 --provider amphora \
  --availability-zone-data \
  "{\"compute_zone\": \"zone01\", \"management_network\": \"${MGMTNET}\"}"
openstack loadbalancer availabilityzoneprofile create \
  --name zone02 --provider amphora \
  --availability-zone-data \
  "{\"compute_zone\": \"zone02\", \"management_network\": \"${MGMTNET}\"}"
  
# 옥타비아 가용성 영역 설정  - 가용성 영역
openstack loadbalancer availabilityzone create \
  --availabilityzoneprofile zone01 --enable --name zone01
openstack loadbalancer availabilityzone create \
  --availabilityzoneprofile zone02 --enable --name zone02

GLANCE 이미지 업로드
OS 이미지

테스트를 위해 httpd 를 기동하고 호스트 네임을 출력하도록 설정하였습니다. 이미지 수정 부분은 포함하지 않았습니다.

# glance image 디렉토리 생성
mkdir -p /playcecloud/data/instace-images

# download
curl -L https://download.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud-Base-8.10-20240528.0.x86_64.qcow2 \
  -o /playcecloud/data/instace-images/Rocky-8.10.qcow2

# qcow2 image modify

# glance에 업로드
openstack image create --file /playcecloud/data/instace-images/Rocky-8.10.qcow2 \
  --disk-format qcow2 rocky8-httpd
OCTAVIA 이미지

amphora 이미지 생성은 다루지 않고 만들어진 것으로 가정하고 octavia 계정으로 업로드 했습니다.

# octavia 계정 권한으로 업로드
source /etc/kolla/octavia-openrc.sh

# upload
openstack image create amphora-x64-haproxy.qcow2 --container-format bare \
  --disk-format qcow2 --private --tag amphora \
  --property hw_architecture='x86_64' --property hw_rng_model=virtio \
  --file /playcecloud/src/octavia/diskimage-create/amphora-x64-haproxy.qcow2

테스트 및 확인

인스턴스 생성

테스트용으로 생성한 floating ip를 환경 변수로 저장하고 테스트때 사용할 예정입니다. zone02 에서는 OCTAVIA 테스트를 안하므로 한 개만 생성했습니다.

zone01

# zone01-project create instance
export OS_PROJECT_NAME=zone01-project

## vm11
### root volume create
openstack volume create --bootable --size 50 --image rocky8-httpd testvm11-root
### server create
openstack server create --flavor C4R8D50 --availability-zone zone01 \
  --network zone01-tenant01 --volume testvm11-root testvm11
### floating ip create
FLOATINGIP11=$(openstack floating ip create \
  zone01-provider -f value -c floating_ip_address)
### add  floating ip to server
openstack server add floating ip testvm11 ${FLOATINGIP11}

## vm12
### root volume create
openstack volume create --bootable --size 50 --image rocky8-httpd testvm12-root
### server create
openstack server create --flavor C4R8D50 --availability-zone zone01 \
  --network zone01-tenant01 --volume testvm12-root testvm12
### floating ip create
FLOATINGIP12=$(openstack floating ip create \
  zone01-provider -f value -c floating_ip_address)
### add  floating ip to server
openstack server add floating ip testvm12 ${FLOATINGIP12}

zone02

# zone02-project create instance
export OS_PROJECT_NAME=zone02-project

## vm21
### root volume create
openstack volume create --bootable --size 50 --image rocky8-httpd testvm21-root
### server create
openstack server create --flavor C4R8D50 --availability-zone zone02 \
  --network zone02-tenant01 --volume testvm21-root testvm21
### floating ip create
FLOATINGIP21=$(openstack floating ip create \
  zone02-provider -f value -c floating_ip_address)
### add  floating ip to server
openstack server add floating ip testvm21 ${FLOATINGIP21}

인스턴스 접속 확인

배포 서버 라우팅 설정

floating ip 접속 테스트를 배포 서버에서 할 예정이라 라우팅 설정을 해서 접근할 수 있도록 합니다.

# external ip 대역 접근을 위해 라우팅 설정 추가
nmcli con modify eth1.101 +ipv4.routes "10.10.111.0/24 10.10.101.1"
nmcli con modify eth1.101 +ipv4.routes "10.10.112.0/24 10.10.101.1"
nmcli con down eth1.101 && nmcli con up eth1.101

접속 확인

환경 변수로 설정된 floating ip 로 http 접근을 하면 호스트 네임과 간단한 메세지가 출력 됩니다.

(kolla-ansible) [root@manage-deploy ~]#
(kolla-ansible) [root@manage-deploy ~]# curl ${FLOATINGIP11}
testvm11.novalocal httpd index page
(kolla-ansible) [root@manage-deploy ~]# curl ${FLOATINGIP12}
testvm12.novalocal httpd index page
(kolla-ansible) [root@manage-deploy ~]#
(kolla-ansible) [root@manage-deploy ~]# curl ${FLOATINGIP21}
testvm21.novalocal httpd index page
(kolla-ansible) [root@manage-deploy ~]#

OCTAVIA 생성

zone01 에 있는 인스턴스를 멤버로 하여 octavia LB를 생성 합니다. 구성될 네트워크는 내부 네트워크를 사용하고 외부 네트워크 연결은 floating ip를 설정합니다.

# set env vm tenant ip
TENANTIP_VM11=$(openstack server show testvm11 -f table -c addresses \
  | grep "172.21" | sed "s/.*\(172\.21\.[0-9]*\.[0-9]*\).*/\1/g")
TENANTIP_VM12=$(openstack server show testvm12 -f table -c addresses \
  | grep "172.21" | sed "s/.*\(172\.21\.[0-9]*\.[0-9]*\).*/\1/g")

# lb create
openstack loadbalancer create --availability-zone zone01 --name lb-zone01-http \
  --vip-network-id zone01-tenant01
# lb listener create
openstack loadbalancer listener create --name lb-zone01-http-listener \
  --protocol HTTP --protocol-port 80 lb-zone01-http
# lb pool create
openstack loadbalancer pool create --name lb-zone01-http-pool \
--lb-algorithm ROUND_ROBIN --listener lb-zone01-http-listener --protocol HTTP
# lb member add
## instance testvm11
openstack loadbalancer member create \
  --subnet-id zone01-tenant01-subnet01 --address ${TENANTIP_VM11} \
  --protocol-port 80 lb-zone01-http-pool
## instance testvm12
openstack loadbalancer member create \
  --subnet-id zone01-tenant01-subnet01 --address ${TENANTIP_VM12} \
  --protocol-port 80 lb-zone01-http-pool

# set env lb vip port id
LB_VIP_PORT=$(openstack loadbalancer show lb-zone01-http -f value -c vip_port_id)
# create floating ip
LB_FLOATINGIP=$(openstack floating ip create \
  zone01-provider -f value -c floating_ip_address)
# add floating ip to lb vip port
openstack floating ip set --port ${LB_VIP_PORT} ${LB_FLOATINGIP}

OCTAVIA 접속 확인

round robin 방식이므로 한번 호출 할때 마다 결과값이 변경되서 출력 됩니다.

(kolla-ansible) [root@manage-deploy ~]#
(kolla-ansible) [root@manage-deploy ~]# curl ${LB_FLOATINGIP}
testvm11.novalocal httpd index page
(kolla-ansible) [root@manage-deploy ~]# curl ${LB_FLOATINGIP}
testvm12.novalocal httpd index page
(kolla-ansible) [root@manage-deploy ~]# curl ${LB_FLOATINGIP}
testvm11.novalocal httpd index page
(kolla-ansible) [root@manage-deploy ~]# curl ${LB_FLOATINGIP}
testvm12.novalocal httpd index page
(kolla-ansible) [root@manage-deploy ~]#

AZ 설정 적용 내용 확인

zone01

AZ 설정을 한 인스턴스가 compute11,12 노드에 배치된 것이 확인되고 dhcp, l3 AGENT 들이 compute11,12 번 노드에 netns 로 적용되어 있는 것이 확인 됩니다.

compute
## zone01 project instance scheduling Host
(kolla-ansible) [root@manage-deploy ~]# openstack server list --long --project zone01-project
+--------------------------------------+----------+--------+------------+-------------+---------------------------------------------+--------------------------+--------------------------+---------+-------------------+------------------+------------+-------------+
| ID                                   | Name     | Status | Task State | Power State | Networks                                    | Image Name               | Image ID                 | Flavor  | Availability Zone | Host             | Properties | Host Status |
+--------------------------------------+----------+--------+------------+-------------+---------------------------------------------+--------------------------+--------------------------+---------+-------------------+------------------+------------+-------------+
| fe8f25e7-d07c-4ab1-badd-571362e2c72c | testvm12 | ACTIVE | None       | Running     | zone01-tenant01=10.10.111.187, 172.21.0.247 | N/A (booted from volume) | N/A (booted from volume) | C4R8D50 | zone01            | zone01-compute11 |            | UP          |
| bb039077-7e39-4a31-ba55-ff9c3467fcab | testvm11 | ACTIVE | None       | Running     | zone01-tenant01=10.10.111.65, 172.21.2.61   | N/A (booted from volume) | N/A (booted from volume) | C4R8D50 | zone01            | zone01-compute12 |            | UP          |
+--------------------------------------+----------+--------+------------+-------------+---------------------------------------------+--------------------------+--------------------------+---------+-------------------+------------------+------------+-------------+
dhcp agent
### zone01 dhcp agent net namespace
(kolla-ansible) [root@manage-deploy ~]# openstack network list --project zone01-project
+--------------------------------------+-----------------+--------------------------------------+
| ID                                   | Name            | Subnets                              |
+--------------------------------------+-----------------+--------------------------------------+
| 8f277ecd-5b18-4d12-af5d-d2a5a5c67a99 | zone01-tenant01 | cf25db48-1d42-4257-93be-4ec0b1f7318c |
| d955f6bd-a162-485a-9d19-2060afd3aca9 | zone01-provider | 4c1ad554-0250-40c4-aeb3-379b2efb251f |
+--------------------------------------+-----------------+--------------------------------------+
(kolla-ansible) [root@manage-deploy ~]#
(kolla-ansible) [root@manage-deploy ~]#
(kolla-ansible) [root@manage-deploy ~]# ansible -i /etc/kolla/multinode baremetal -m shell -a "ip netns | grep -E '8f277ecd-5b18-4d12-af5d-d2a5a5c67a99|d955f6bd-a162-485a-9d19-2060afd3aca9'"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
manage-control02 | FAILED | rc=1 >>
non-zero return code
manage-control01 | FAILED | rc=1 >>
non-zero return code
zone01-compute11 | CHANGED | rc=0 >>
qdhcp-8f277ecd-5b18-4d12-af5d-d2a5a5c67a99 (id: 2)
qdhcp-d955f6bd-a162-485a-9d19-2060afd3aca9 (id: 1)
zone01-compute12 | CHANGED | rc=0 >>
qdhcp-8f277ecd-5b18-4d12-af5d-d2a5a5c67a99 (id: 0)
qdhcp-d955f6bd-a162-485a-9d19-2060afd3aca9 (id: 1)
manage-control03 | FAILED | rc=1 >>
non-zero return code
zone02-compute22 | FAILED | rc=1 >>
non-zero return code
zone02-compute21 | FAILED | rc=1 >>
non-zero return code
(kolla-ansible) [root@manage-deploy ~]#
l3 agent
### zone01 l3 agent net namespace
(kolla-ansible) [root@manage-deploy ~]# openstack router list --project zone01-project
+--------------------------------------+---------------+--------+-------+----------------------------------+-------------+------+
| ID                                   | Name          | Status | State | Project                          | Distributed | HA   |
+--------------------------------------+---------------+--------+-------+----------------------------------+-------------+------+
| 21058ce0-cd8f-4d89-b718-6de0ef6d9afb | zone01-router | ACTIVE | UP    | 45cece1bb4934a489e70dbcd66198dc7 | False       | True |
+--------------------------------------+---------------+--------+-------+----------------------------------+-------------+------+
(kolla-ansible) [root@manage-deploy ~]#
(kolla-ansible) [root@manage-deploy ~]# ansible -i /etc/kolla/multinode baremetal -m shell -a "ip netns | grep -E '21058ce0-cd8f-4d89-b718-6de0ef6d9afb'"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
manage-control01 | FAILED | rc=1 >>
non-zero return code
zone01-compute11 | CHANGED | rc=0 >>
qrouter-21058ce0-cd8f-4d89-b718-6de0ef6d9afb (id: 0)
zone01-compute12 | CHANGED | rc=0 >>
qrouter-21058ce0-cd8f-4d89-b718-6de0ef6d9afb (id: 2)
manage-control02 | FAILED | rc=1 >>
non-zero return code
manage-control03 | FAILED | rc=1 >>
non-zero return code
zone02-compute21 | FAILED | rc=1 >>
non-zero return code
zone02-compute22 | FAILED | rc=1 >>
non-zero return code

zone02

AZ 설정을 한 인스턴스가 compute21,22 노드에 배치된 것이 확인되고 dhcp, l3 AGENT 들이 compute21,22 번 노드에 netns 로 적용되어 있는 것이 확인 됩니다.

compute
## zone02 project instance scheduling Host
(kolla-ansible) [root@manage-deploy ~]# openstack server list --long --project zone02-project
+--------------------------------------+----------+--------+------------+-------------+---------------------------------------------+--------------------------+--------------------------+---------+-------------------+------------------+------------+-------------+
| ID                                   | Name     | Status | Task State | Power State | Networks                                    | Image Name               | Image ID                 | Flavor  | Availability Zone | Host             | Properties | Host Status |
+--------------------------------------+----------+--------+------------+-------------+---------------------------------------------+--------------------------+--------------------------+---------+-------------------+------------------+------------+-------------+
| d37e9d19-b9e4-4ccc-a2c1-6906484948e8 | testvm21 | ACTIVE | None       | Running     | zone02-tenant01=10.10.112.219, 172.22.1.162 | N/A (booted from volume) | N/A (booted from volume) | C4R8D50 | zone02            | zone02-compute22 |            | UP          |
+--------------------------------------+----------+--------+------------+-------------+---------------------------------------------+--------------------------+--------------------------+---------+-------------------+------------------+------------+-------------+
(kolla-ansible) [root@manage-deploy ~]#

dhcp agent
### zone02 dhcp agent net namespace
(kolla-ansible) [root@manage-deploy ~]# openstack network list --project zone02-project
+--------------------------------------+-----------------+--------------------------------------+
| ID                                   | Name            | Subnets                              |
+--------------------------------------+-----------------+--------------------------------------+
| cd04da0f-be6e-4d80-806b-2b37950a7db6 | zone02-provider | a09b850a-566c-4816-9d11-0f9e53e9d5af |
| cf05e65f-4e58-415d-96c6-01996c56407b | zone02-tenant01 | c08a80c7-b7d8-4364-b86b-7256db75c048 |
+--------------------------------------+-----------------+--------------------------------------+
(kolla-ansible) [root@manage-deploy ~]# ansible -i /etc/kolla/multinode baremetal -m shell -a "ip netns | grep -E 'cd04da0f-be6e-4d80-806b-2b37950a7db6|cf05e65f-4e58-415d-96c6-01996c56407b'"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
manage-control02 | FAILED | rc=1 >>
non-zero return code
manage-control01 | FAILED | rc=1 >>
non-zero return code
zone01-compute12 | FAILED | rc=1 >>
non-zero return code
zone01-compute11 | FAILED | rc=1 >>
non-zero return code
manage-control03 | FAILED | rc=1 >>
non-zero return code
zone02-compute21 | CHANGED | rc=0 >>
qdhcp-cf05e65f-4e58-415d-96c6-01996c56407b (id: 2)
qdhcp-cd04da0f-be6e-4d80-806b-2b37950a7db6 (id: 1)
zone02-compute22 | CHANGED | rc=0 >>
qdhcp-cf05e65f-4e58-415d-96c6-01996c56407b (id: 0)
qdhcp-cd04da0f-be6e-4d80-806b-2b37950a7db6 (id: 1)
(kolla-ansible) [root@manage-deploy ~]#
l3 agent
### zone02 l3 agent net namespace
(kolla-ansible) [root@manage-deploy ~]# openstack router list --project zone02-project
+--------------------------------------+---------------+--------+-------+----------------------------------+-------------+------+
| ID                                   | Name          | Status | State | Project                          | Distributed | HA   |
+--------------------------------------+---------------+--------+-------+----------------------------------+-------------+------+
| 022f3127-6d17-4388-98e2-a04514934285 | zone02-router | ACTIVE | UP    | 61ca70b037324bfdab87f7217e007f50 | False       | True |
+--------------------------------------+---------------+--------+-------+----------------------------------+-------------+------+
(kolla-ansible) [root@manage-deploy ~]#
(kolla-ansible) [root@manage-deploy ~]# ansible -i /etc/kolla/multinode baremetal -m shell -a "ip netns | grep -E '022f3127-6d17-4388-98e2-a04514934285'"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
manage-control01 | FAILED | rc=1 >>
non-zero return code
zone01-compute11 | FAILED | rc=1 >>
non-zero return code
manage-control03 | FAILED | rc=1 >>
non-zero return code
zone01-compute12 | FAILED | rc=1 >>
non-zero return code
manage-control02 | FAILED | rc=1 >>
non-zero return code
zone02-compute22 | CHANGED | rc=0 >>
qrouter-022f3127-6d17-4388-98e2-a04514934285 (id: 2)
zone02-compute21 | CHANGED | rc=0 >>
qrouter-022f3127-6d17-4388-98e2-a04514934285 (id: 3)
(kolla-ansible) [root@manage-deploy ~]#

마치며

지금까지 네트워크, 컴퓨트 자원을 가용성 영역을 나누고 설치하고 설정하여서 확인까지 해봤습니다. 이런 식으로 나눠서 사용하게 되는 경우가 얼마나 있을지는 모르겠지만 이 글이 도움이 되었으면 좋겠습니다.

이번 환경을 구성하며 중간 중간 어려웠던 부분도 있었는데 오히려 그래서 더 많이 배운 것 같습니다.
다른 환경 다른 컴포넌트 구성들로도 설치해보면 좋을 것 같아요.

다음에는 쿠버네티스 쪽 설치 구성하는 부분을 정리해보고 싶네요.

참고자료

많은 IT 기술들을 익히고 사용하고 적용하는 걸 좋아하는 평범한 IT 기술자입니다

Leave a Reply

Your email address will not be published. Required fields are marked *