4 오픈스택 구축
4.1 컨트롤러 노드 설치
4.1.1 NTP 설치
NTP(Network Time Protocol)은 서버 간의 시간을 동기화하기 위한 프로토콜로 클라우드 시스템에서 자원을 예약/사용/삭제할 때 시간을 기록하기 위해서 사용한다.
컨트롤러 노드에는 NTP Server를 설치하고 다른 노드들은 NTP Client를 설치한다.
# 컨트롤러 노드 ntp 패키지 설치 $ sudo apt-get install ntp |
sed 명령어로 /etc/ntp.conf 파일에 로컬 호스트(127.127.0.1)를 추가한다.
※ 명령어는 한줄로 이어서 입력해야 함
※ /etc/ntp.conf 파일에 제대로 추가되었는지 확인
# ntp 설정파일 수정 $ sudo sed -i 's/server ntp.ubuntu.com/server ntp.ubuntu.com\nserver 127.127.1.0\nfudge 127.127.1.0 stratum 10/g' /etc/ntp.conf |
ntp 대몬을 재실행한다.
# ntp 대몬 재실행 $ sudo service ntp restart |
4.1.2 데이터베이스 설치
오픈스택의 모든 Nova, Keystone, Glance 등의 모든 프로젝트는 데이터베이스 정보를 저장하기 때문에 오픈스택 서비스를 설치하기 전에 가장 먼저 설치해야 한다.
또한 오픈스택의 데이터베이스는 아이스하우 이후 버전부터 MariaDB도 가능하지만 여기서는 MySQL를 설치하도록 한다.
# ntp 대몬 재실행 $ sudo apt-get install python-mysqldb mysql-server |
MySQL를 설치하다보면 root 패스워드를 물어보는 창이 나오는데 사용하고자 하는 패스워드를 입력하면 된다.
동일한 root 패스워드를 입력한다.
MySQL 설정파일을 열어서 bind-address를 컨트롤러 IP로 수정하고 48 ~ 50번 라인의 내용을 추가해 준다.
# mysql 설정파일 수정 $ sudo vi /etc/mysql/my.cnf 47 bind-address = 192.168.0.11 48 default-storage-engine = innodb 49 collation-server = utf8_general_ci 50 init-connect = 'SET NAMES utf8' 51 character-set-server = utf8 |
mysql 대몬을 재실행한다.
# mysql 대몬 재실행 $ sudo service mysql restart |
MySQL 기본 데이터베이스와 테이블을 생성한다.
# mysql 데이터베이스 및 테이블 생성 $ sudo mysql_install_db |
mysql_secure_installation 명령어를 이용해 익명 계정을 삭제한다.
# mysql 익명 계정 삭제 $ sudo mysql_secure_installation … 중략 … // 현재 root 패스워드 입력 Enter current password for root (enter for none): mysql의 root 패스워드 입력 OK, successfully used password, moving on... // root 패스워드를 변경할 것인가? Change the root password? [Y/n] n ... skipping. // 익명 계정을 삭제할 것인가? Remove anonymous users? [Y/n] y ... Success! // 원격으로 root로 접속을 제한할 것인가? Disallow root login remotely? [Y/n] n ... Success! // test 데이터베이스를 삭제할 것인가? Remove test database and access to it? [Y/n] y ... Success! // privilege 테이블을 로드할 것인가? Reload privilege tables now? [Y/n] y ... Success! All done! If you've completed all of the above steps, your MySQL installation should now be secure. Thanks for using MySQL! |
4.1.3 오픈스택 아이스하우스 패키지 설치
Python-software-properties 패키지를 먼저 설치한 후 repository에 icehouse를 추가한다.
# 아이스하우스 패키지 설치 $ sudo apt-get install python-software-properties $ sudo add-apt-repository cloud-archive:icehouse … [ENTER] 입력 |
시스템을 업데이트 및 업그레이드 수행 후에는 반드시 재부팅을 해야 한다.
# 시스템 업데이트 및 업그레이드 $ sudo apt-get update && sudo apt-get dist-upgrade && sudo reboot |
4.1.4 RabbitMQ 설치
오픈스택의 모든 서비스들을 묶어주기 위해 메시지 서비스인 RabbitMQ Server를 설치한다. 그리고 rabbitmqctl 명령어를 사용해 패스워드를 변경한다.
# RabbitMQ Server 설치 및 패스워드 변경 $ sudo apt-get install rabbitmq-server $ sudo rabbitmqctl change_password guest rabbitpass Changing password for user "guest" ... ...done. |
4.1.5 Keystone 설치
사용자들이 오픈스택의 모든 서비스를 이용하려면 인증을 거쳐야 되는데, 이러한 인증을 제공하는 서비스가 Keystone이다.
# Keystone 설치 $ sudo apt-get install keystone python-keystoneclient |
Keystone 설정파일을 열어 아래와 같이 수정한다. 해당 설정파일을 보면 데이터베이스가 sqlite로 되어 있는데 mysql를 설치하였으므로 mysql로 변경해야 한다.
# Keystone 설정파일 DB 수정 $ sudo vi /etc/keystone/keystone.conf 604 [database] 626 connection=mysql://keystone:keystonedbpass@192.168.0.11/keystone |
데이터베이스를 MySQL로 설정하였으므로 필요없는 데이터베이스 파일은 삭제한다.
# sqlite keystone.db 파일 삭제 $ sudo rm /var/lib/keystone/keystone.db |
MySQL에 접속해서 keystone 데이터베이스를 생성한 후 keystone 계정에 대한 패스워드를 생성해서 localhost 및 다른 노드에서 접근할 수 있도록 권한을 할당한다.
※ grant 명령어는 한줄로 입력해야 함
# keystone 계정 생성 및 권한 설정 $ mysql -u root –p mysql> CREATE DATABASE keystone; mysql> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'keystonedbpass'; mysql> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'keystonedbpass'; mysql> exit; |
keystone에서 사용할 테이블을 생성하고 정상적으로 생성되었는지 확인하려면 mysql에 접속해서 mysql> use keystone; mysql> show tables; 를 입력하면 된다.
# keystone 테이블 생성 $ sudo su -s /bin/sh -c "keystone-manage db_sync" keystone |
Keystone에 접근하기 위해서는 admin token이 필요한데 openssl 명령어를 사용해서 임의의 문자열을 생성한다. 그리고 생성된 문자열을 keystone 설정파일의 admin_token에 추가하고, 로그 파일 경로도 수정해준다.
# keystone admin token 생성 $ openssl rand -hex 10 b0fbbaeab465fc7429ae $ sudo vi /etc/keystone/keystone.conf 1 [DEFAULT] 13 admin_token=b0fbbaeab465fc7429ae 450 log_dir=/var/log/keystone $ sudo service keystone restart |
환경 설정 파일을 변경하였으면 항상 대몬을 재실행해야 한다.
# keystone 대몬 재실행 $ sudo service keystone restart keystone stop/waiting keystone start/running, process 4627 |
4.1.6 Keystone 사용자, 테넌트, 룰, endpoint 생성
사용자는 토큰을 통해 인증을 받고 endpoint를 통해 keystone에 접근하므로 TOKEN과 ENDPOINT를 등록한다. (OS_SERVICE_TOKEN은 위에서 생성한 admin_token 이다)
# Keystone TOKEN/ENDPOINT export $ export OS_SERVICE_TOKEN=b0fbbaeab465fc7429ae $ export OS_SERVICE_ENDPOINT=http://192.168.0.11:35357/v2.0 |
TOKEN과 ENDPOINT 정보를 export하면 Keystone 서비스를 이용할 수 있는데 keystone 명령어를 이용해서 admin 계정을 생성한다.
# Keystone admin 계정 생성 $ keystone user-create --name=admin --pass=adminpass --email=admin@email.com |
admin과 member role를 생성한다.
# Keystone admin/member role 생성 $ keystone role-create --name=admin $ keystone role-create --name=member |
Admin Tenant를 생성하고 Admin Tenant에 admin계정과 admin/member 룰을 추가한다.
# Keystone Admin Tenant 생성 및 계정 추가 $ keystone tenant-create --name=admin --description="Admin Tenant" $ keystone user-role-add --user admin --role admin --tenant admin $ keystone user-role-add --user admin --role member --tenant admin |
demo 계정을 생성한다.
# Keystone demo 계정 생성 $ keystone user-create --name=demo --pass=demopass --email=demo@email.com |
Demo Tenant를 생성하고 demo계정을 Demo Tenant에 추가하고 룰은 member로 설정한다.
# Keystone Demo Tenant 생성 $ keystone tenant-create --name=demo --description="Demo Tenant" $ keystone user-role-add --user=demo --role=member --tenant=demo |
오픈스택 서비스 인증과정을 위한 Service Tenant를 생성한다.
# Keystone Service Tenant 생성 $ keystone tenant-create --name=service --description="Service Tenant" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | Service Tenant | | enabled | True | | id | e1e79273038147b6867db1b8d73660f5 | | name | service | +-------------+----------------------------------+ |
keystone 서비스를 생성한 후 service id를 복사한다.
# Keystone Service 생성 $ keystone service-create --name=keystone --type=identity --description="OpenStack Identity" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | OpenStack Identity | | enabled | True | | id | 462b44a43f0342478f8d5d8407b3afbb | | name | keystone | | type | identity | +-------------+----------------------------------+ |
방금 전 생성한 keystone 서비스의 Endpoint URL을 정의해야 하는데 이 때 필요한 파라미터들은 keystone service id, 외부에서 접속되는 Public URL, 내부에서 접속할 Internal URL, 관리자가 접속할 Admin URL로 이루어진다.
# Keystone endpoint 생성 $ keystone endpoint-create --service_id=462b44a43f0342478f8d5d8407b3afbb --publicurl=http://192.168.0.11:5000/v2.0 --internalurl=http://192.168.0.11:5000/v2.0 --adminurl=http://192.168.0.11:35357/v2.0 |
이전에 등록했던 환경변수를 해제한 후 Token이 정상적으로 발급받는지 테스트한다.
# Keystone Token 생성 $ unset OS_SERVICE_TOKEN OS_SERVICE_ENDPOINT $ keystone --os-username=admin --os-password=adminpass --os-auth-url=http://192.168.0.11:35357/v2.0 token-get $ keystone --os-username=admin --os-password=adminpass --os-tenant-name=admin --os-auth-url=http://192.168.0.11:35357/v2.0 token-get |
환경변수 정보를 스크립트 파일에 저장한 후 실행한다.
# Keystone 환경변수 스크립트화 $ vi admin-openrc.sh export OS_USERNAME=admin export OS_PASSWORD=adminpass export OS_TENANT_NAME=admin export OS_AUTH_URL=http://192.168.0.11:35357/v2.0 $ vi demo-openrc.sh export OS_USERNAME=demo export OS_PASSWORD=demopass export OS_TENANT_NAME=demo export OS_AUTH_URL=http://192.168.0.11:35357/v2.0 $ . admin-openrc.sh |
환경변수 정보를 스크립트로 작성하니 매개변수 없이 token 뿐만 아니라 사용자 목록 룰 목록도 얻어오는 것을 알 수 있다.
# Keystone 관련 명령어 $ keystone token-get $ keystone user-list $ keystone user-role-list $ keystone service-list $ keystone tenant-list |
4.1.7 Glance 설치
인스턴스(가상서버)를 생성하려면 운영체제가 필요한데 운영체제 이미지 파일을 관리하는 서비스가 Glance이다.
# glance 설치 $ sudo apt-get install glance python-glanceclient |
glance 프로젝트 또한 다른 프로젝트들과 마찬가지로 메시지 통신을 하며 이미지 파일 관리를 위해 데이터베이스를 이용한다. 이를 위해 RabbitMQ Server 정보와 MySQL 정보를 추가한다.
※ rpc_backend와 connection 정보를 추가, sqlite_db는 주석처리, 그 외에는 수정한다.
# glance-api.conf 파일 수정 $ sudo vi /etc/glance/glance-api.conf 1 [DEFAULT] 244 rpc_backend = rabbit 245 rabbit_host = 192.168.0.11 249 rabbit_password = rabbitpass 551 [database] 553 #sqlite_db = /var/lib/glance/glance.sqlite 554 connection = mysql://glance:glancedbpass@192.168.0.11/glance 561 backend = mysql |
glance-registry.conf 파일도 데이터베이스 정보를 수정한다.
※ sqlite_db는 주석처리, connection 정보를 추가, backend 정보 수정한다.
# glance-registry.conf 파일 수정 $ sudo vi /etc/glance/glance-registry.conf 78 [database] 80 #sqlite_db = /var/lib/glance/glance.sqlite 81 connection = mysql://glance:glancedbpass@192.168.0.11/glance 88 backend = mysql |
필요없는 glance.sqlite 파일은 삭제한다.
# glance.aqlite 파일 삭제 $ sudo rm /var/lib/glance/glance.sqlite |
mysql에 접속해서 glance 데이터베이스를 생성하고나서 glance 계정에 대한 패스워드를 생성한다. 그리고 glance-manage 명령어를 이용해서 glance 테이블을 생성한다.
# glance 데이터베이스 및 테이블 생성 $ mysql -u root -p mysql> CREATE DATABASE glance; mysql> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY 'glancedbpass'; mysql> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY 'glancedbpass'; $ sudo su -s /bin/sh -c "glance-manage db_sync" glance |
keystone에 glance 계정을 생성하고 service 테넌트에 glance 계정을 추가한다.
# glance 계정 생성 및 service 테넌트 설정 $ keystone user-create --name=glance --pass=glancepass --email=glance@email.com $ keystone user-role-add --user=glance --tenant=service --role=admin |
glance-api.conf 파일에 생성된 keystone 정보를 추가한다.
# glance-api.conf파일에 keystone 정보 추가 $ sudo vi /etc/glance/glance-api.conf 648 [keystone_authtoken] 649 auth_uri = http://192.168.0.11:5000 650 auth_host = 192.168.0.11 651 auth_port = 35357 652 auth_protocol = http 653 admin_tenant_name = service 654 admin_user = glance 655 admin_password = glancepass 658 [paste_deploy] 666 flavor=keystone |
glance-registry.conf 파일에 생성된 keystone 정보를 추가한다.
# glance-registry.conf 파일에 keystone 정보 추가 $ sudo vi /etc/glance/glance-registry.conf 175 [keystone_authtoken] 176 auth_uri = http://192.168.0.11:5000 177 auth_host = 192.168.0.11 178 auth_port = 35357 179 auth_protocol = http 180 admin_tenant_name = service 181 admin_user = glance 182 admin_password = glancepass 185 [paste_deploy] 193 flavor=keystone |
사용자와 다른 서비스들이 접속할 수 있도록 glance 서비스를 생성한다.
# glance 서비스 생성 $ keystone service-create --name=glance --type=image --description="OpenStack Image Service" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | OpenStack Image Service | | enabled | True | | id | 85be2c4588e04f5995973dfe86d400b1 | | name | glance | | type | image | +-------------+----------------------------------+ |
사용자와 다른 서비스들이 접속할 수 있도록 endpoint를 생성한다.
# endpoint 생성 $ keystone endpoint-create --service-id=85be2c4588e04f5995973dfe86d400b1 --publicurl=http://192.168.0.11:9292 --internalurl=http://192.168.0.11:9292 --adminurl=http://192.168.0.11:9292 |
glance 관련 대몬를 재시작한다.
# glance 대몬 재시작 $ sudo service glance-registry restart $ sudo service glance-api restart |
glance 명령어를 이용해 cirros 이미지를 등록한다.
# glance를 이용해 cirros 이미지 등록 $ . admin-openrc.sh $ mkdir image; cd image $ wget http://download.cirros-cloud.net/0.3.2/cirros-0.3.2-x86_64-disk.img $ glance image-create --name "cirros-0.3.2-x86_64" --disk-format qcow2 --container-format bare --is-public True --progress < cirros-0.3.2-x86_64-disk.img $ glance image-list |
4.1.8 Nova Management 설치
nova는 오픈스택에서 가상 인스턴스를 생성하고 삭제하는 프로젝트이다. 아래와 같이 nova와 관련된 서비스를 설치한다.
# nova 설치 $ sudo apt-get install nova-api nova-cert nova-conductor nova-consoleauth nova-novncproxy nova-scheduler python-novaclient |
/etc/nova/nova.conf 파일에 RabbitMQ, VNC, 데이터베이스 정보를 추가한다.
# nova.conf 파일 수정 $ sudo vi /etc/nova/nova.conf 1 [DEFAULT] 17 rpc_backend=rabbit 18 rabbit_host=192.168.0.11 19 rabbit_password=rabbitpass 20 my_ip=192.168.0.11 21 vncserver_listen=192.168.0.11 22 vncserver_proxyclient_address=192.168.0.11 23 24 [database] 25 connection=mysql://nova:novadbpass@192.168.0.11/nova |
필요없는 nova.sqlite 파일은 삭제하고 nova 데이터베이스와 계정을 생성한다. 그리고 다른 노드에서 접속할 수 있도록 권한을 할당한다.
# nova 데이터베이스 및 권한 할당 $ sudo rm /var/lib/nova/nova.sqlite $ mysql -u root -p mysql> CREATE DATABASE nova; mysql> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY 'novadbpass'; mysql> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY 'novadbpass'; mysql> exit |
nova-manage 명령어를 이용해 nova 테이블을 생성한다.
# nova 테이블 생성 $ sudo su -s /bin/sh -c "nova-manage db sync" nova 2015-05-13 18:26:37.621 12548 INFO migrate.versioning.api [-] 215 -> 216... 2015-05-13 18:26:42.276 12548 INFO migrate.versioning.api [-] done … 2015-05-13 18:26:42.893 12548 INFO migrate.versioning.api [-] 233 -> 234... 2015-05-13 18:26:42.916 12548 INFO migrate.versioning.api [-] done |
keystone에 nova계정을 추가하고 서비스 테넌트에 nova를 추가한다.
# keystone에 nova 계정 추가 $ keystone user-create --name=nova --pass=novapass --email=nova@email.com $ keystone user-role-add --user=nova --tenant=service --role=admin |
/etc/nova/nova.conf 파일에 방금 생성한 keystone 정보를 추가한다.
# nova.conf 파일에 keystone 정보 추가 $ sudo vi /etc/nova/nova.conf 1 [DEFAULT] 23 auth_strategy=keystone 28 [keystone_authtoken] 29 auth_uri=http://192.168.0.11:5000 30 auth_host=192.168.0.11 31 auth_port=35357 32 auth_protocol=http 33 admin_tenant_name=service 34 admin_user=nova 35 admin_password=novapass |
사용자와 다른 서비스들이 접속할 수 있도록 nova 서비스와 endpoint를 생성한다.
# nova 서비스 및 endpoint 생성 $ keystone service-create --name=nova --type=compute --description="OpenStack Compute" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | OpenStack Compute | | enabled | True | | id | efbad43e63264753a2bb9cc051b1c208 | | name | nova | | type | compute | +-------------+----------------------------------+ $ keystone endpoint-create --service-id=efbad43e63264753a2bb9cc051b1c208 --publicurl=http://192.168.0.11:8774/v2/%\(tenant_id\)s --internalurl=http://192.168.0.11:8774/v2/%\(tenant_id\)s --adminurl=http://192.168.0.11:8774/v2/%\(tenant_id\)s |
nova 관련 서비스들을 모두 재시작한다.
# nova 서비스 재시작 $ sudo service nova-api restart; sudo service nova-cert restart; sudo service nova-consoleauth restart; sudo service nova-scheduler restart; sudo service nova-conductor restart; sudo service nova-novncproxy restart |
nova가 정상적으로 설치되었는지 nova 명령어로 이미지 목록을 확인한다.
# nova 이미지 목록 확인 $ . admin-openrc.sh $ nova image-list +--------------------------------------+---------------------+--------+--------+ | ID | Name | Status | Server | +--------------------------------------+---------------------+--------+--------+ | f29a100f-67b5-4a0c-b8e9-d3d8a5955d4c | cirros-0.3.2-x86_64 | ACTIVE | +--------------------------------------+---------------------+--------+--------+ |
4.1.9 Neutron Server 설치
Neutron은 인스턴스에게 IP를 할당하고 인스턴스간 서로 통신할 수 있게 해주는 네트워크 서비스이다.
노드별 Neutron 설치 방법은 컨트롤러 노드에는 Neutron 서버를 설치하고 네트워크 노드와 컴퓨트 노드에는 플러그인과 에이전트를 설치한다.
# neutron 데이터베이스 및 계정 생성 $ mysql -u root -p mysql> CREATE DATABASE neutron; mysql> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'neutrondbpass'; mysql> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'neutrondbpass'; |
keystone에 neutro 계정을 추가하고 서비스 테넌트에 neutron 계정을 추가한다.
# keystone/서비스테넌트에 neutron 계정 추가 $ keystone user-create --name neutron --pass neutronpass --email neutron@email.com $ keystone user-role-add --user neutron --tenant service --role admin |
keystone에 neutron 서비스를 추가하고 생성된 서비스 ID로 endpoint URL를 생성한다.
# Neutron 서비스 및 endpoint URL 생성 $ keystone service-create --name=neutron --type=network --description="OpenStack Networking" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | OpenStack Networking | | enabled | True | | id | a93f0057733a41b7b3cd35e2a2a10a17 | | name | neutron | | type | network | +-------------+----------------------------------+ $ keystone endpoint-create --service-id=a93f0057733a41b7b3cd35e2a2a10a17 --publicurl=http://192.168.0.11:9696 --adminurl=http://192.168.0.11:9696 --internalurl=http://192.168.0.11:9696 |
neutron 서버와 ml2 플러그인을 설치한다.
# neutron 서버 설치 $ sudo apt-get install neutron-server neutron-plugin-ml2 |
/etc/neutron/neutron.conf 파일을 아래와 같이 수정한다.
※ nova_admin_tenant_id는 $ keystone tenant-list에서 이름이 service인 id이다.
※ 3 ~ 16번 라인까지 붙여넣기 / 69번라인 주석처리 / 그 외 수정
# neutron.conf 파일 수정 $ sudo vi /etc/neutron/neutron.conf 1 [DEFAULT] 2 3 auth_strategy = keystone 4 rpc_backend = neutron.openstack.common.rpc.impl_kombu 5 rabbit_host = 192.168.0.11 6 rabbit_password = rabbitpass 7 notify_nova_on_port_status_changes = True 8 notify_nova_on_port_data_changes = True 9 nova_url = http://192.168.0.11:8774/v2 10 nova_admin_username = nova 11 nova_admin_tenant_id = e1e79273038147b6867db1b8d73660f5 12 nova_admin_password = novapass 13 nova_admin_auth_url = http://192.168.0.11:35357/v2.0 14 core_plugin = ml2 15 service_plugins = router 16 allow_overlapping_ips = True 69 #core_plugin = neutron.plugins.ml2.plugin.Ml2Plugin 416 [keystone_authtoken] 417 auth_uri = http://192.168.0.11:5000 418 auth_host = 192.168.0.11 419 auth_protocol = http 420 auth_port = 35357 421 admin_tenant_name = service 422 admin_user = neutron 423 admin_password = neutronpass 424 signing_dir = $state_path/keystone-signing 425 [database] 431 #connection = sqlite:////var/lib/neutron/neutron.sqlite 432 connection = mysql://neutron:neutrondbpass@192.168.0.11/neutron |
/etc/nova/nova.conf 파일에 24 ~ 35번 라인을 추가한다.
# nova.conf 파일 수정 $ sudo vi /etc/nova/nova.conf 1 [DEFAULT] 24 network_api_class=nova.network.neutronv2.api.API 25 neutron_url=http://192.168.0.11:9696 26 neutron_auth_strategy=keystone 27 neutron_admin_tenant_name=service 28 neutron_admin_username=neutron 29 neutron_admin_password=neutronpass 30 neutron_admin_auth_url=http://192.168.0.11:35357/v2.0 31 linuxnet_interface_driver=nova.network.linux_net.LinuxOVSInterfaceDriver 32 firewall_driver=nova.virt.firewall.NoopFirewallDriver 33 security_group_api=neutron 34 service_neutron_metadata_proxy=true 35 neutron_metadata_proxy_shared_secret=metadatasecret |
Nuetron의 기본 플러그인은 ML2이므로 ML2 환경설정 파일을 열어 다음과 같이 수정한다.
# ML2 설정파일 수정 $ sudo vi /etc/neutron/plugins/ml2/ml2_conf.ini 1 [ml2] 5 type_drivers = gre 12 tenant_network_types = gre 17 mechanism_drivers = openvswitch 42 [ml2_type_gre] 44 tunnel_id_ranges = 1:1000 59 [securitygroup] 62 firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver 63 enable_security_group = True |
Neutron은 nova 서비스의 인스턴스에게 IP를 할당하므로 Neutron 서비스와 nova 서비스 모두 서비스를 재시작한다.
※ 서비스를 재시작하면 neutron 테이블이 생성된다.
# neutron 및 nova 서비스 재시작 $ sudo service nova-api restart; sudo service nova-scheduler restart; sudo service nova-conductor restart; sudo service neutron-server restart |
4.1.10 Horizon 설치
오픈스택의 모든 프로젝트들은 사용자들에게 웹을 통해 쉽게 관리 및 설정할 수 있도록 제공하는데 이것이 Horizon 서비스이다. 다음은 Horizon 서비스를 설치하고 필요없는 우분투 배경을 삭제한다.
# horizon 설치 $ sudo apt-get install apache2 memcached libapache2-mod-wsgi openstack-dashboard $ sudo apt-get remove --purge openstack-dashboard-ubuntu-theme |
/etc/memcached.conf 파일에서 로컬 IP 주소를 주석처리하고 컨트롤러 IP를 추가한다.
# memcached.conf 파일 수정 $ sudo vi /etc/memcached.conf 35 #-l 127.0.0.1 36 -l 192.168.0.11 |
/etc/openstack-dashboard/local_settings.py 파일을 열어 대시보드에 접속할 수 있는 IP를 다음 그림과 같이 등록한다. 이 때 98번 라인만 새로 추가하고 나머지 부분은 컨트롤러의 IP로 수정해야 한다.
# local_settings.py 파일 수정 $ sudo vi /etc/openstack-dashboard/local_settings.py 98 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' 99 CACHES = { 100 'default': { 101 'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache', 102 'LOCATION' : '192.168.0.11:11211', 103 } 104 } 131 ALLOWED_HOSTS = ['localhost','192.168.0.11'] 151 OPENSTACK_HOST = "192.168.0.11" |
apache2와 memcached 대몬을 재시작한다.
# local_settings.py 파일 수정 $ sudo vi /etc/apache2/apache2.conf 1 ServerName localhost $ sudo service apache2 restart; sudo service memcached restart |
웹 브라우저 주소창에 http://192.168.0.11/horizon(컨트롤러IP)을 입력하면 로그인 화면이 나온다.
※ 계정 및 패스워드 확인 방법 : $ vi admin-openrc.sh / $ vi demo-openrc.sh
※ 오픈스택 로고 변경 방법 :
# cd /usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img
favicon.ico / logo.png / logo-splash.png 파일의 이미지를 변경하면 된다.
4.1.11 Cinder Server 설치
Cinder는 인스턴스가 사용하는 블록 스토리지(가상 디스크) 서비스를 관리한다. 블록 스토리지는 디스크 여러 개를 묶어서 하나의 볼륨으로 사용하는 LVM 방식와 Ceph와 같은 외부 스토리지를 연결해서 사용하는 방법이 있는데
여기서는 오픈스택의 기본 블록 스토리지인 LVM을 사용하겠다.cinder-api와 cinder-scheduler를 설치한다.
# cinder 설치 $ sudo apt-get install cinder-api cinder-scheduler |
/etc/cinder/cinder.conf 파일을 열어서 데이터베이스 항목을 추가한다.
# cinder.conf 파일 수정 $ sudo vi /etc/cinder/cinder.conf 13 [database] 14 connection = mysql://cinder:cinderdbpass@192.168.0.11/cinder |
mysql에 접속해서 cinder 데이터베이스를 생성하고 접속 권한을 설정한다.
# cinder 데이터베이스 생성 및 권한 설정 $ mysql -u root -p mysql> CREATE DATABASE cinder; mysql> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY 'cinderdbpass'; mysql> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY 'cinderdbpass'; mysql> exit |
cinder-manage 명령어를 사용해 cinder 테이블을 생성한다.
# cinder 테이블 생성 $ sudo su -s /bin/sh -c "cinder-manage db sync" cinder 2015-05-14 14:12:59.698 8410 INFO migrate.versioning.api [-] 0 -> 1... 2015-05-14 14:13:00.056 8410 INFO migrate.versioning.api [-] done . . . 2015-05-14 14:13:00.901 8410 INFO 021_add_default_quota_class [-] Added default quota class data into the DB. 2015-05-14 14:13:00.904 8410 INFO migrate.versioning.api [-] done 2015-05-14 14:13:00.904 8410 INFO migrate.versioning.api [-] 21 -> 22... 2015-05-14 14:13:00.939 8410 INFO migrate.versioning.api [-] done |
cinder 계정을 생성하고 cinder 계정에 service tenant와 admin role을 추가한다.
# cinder 계정 생성 및 service tenant/admin role 추가 $ . admin-openrc.sh $ keystone user-create --name=cinder --pass=cinderpass --email=cinder@email.com $ keystone user-role-add --user=cinder --tenant=service --role=admin |
/etc/cinder/cinder.conf 파일에 keystone 인증정보와 RabbitMQ 정보를 추가한다.
# cinder.conf 파일 설정 $ sudo vi /etc/cinder/cinder.conf 1 [DEFAULT] 12 rpc_backend = cinder.openstack.common.rpc.impl_kombu 13 rabbit_host = 192.168.0.11 14 rabbit_port = 5672 15 rabbit_userid = guest 16 rabbit_password = rabbitpass 21 [keystone_authtoken] 22 auth_uri = http://192.168.0.11:5000 23 auth_host = 192.168.0.11 24 auth_port = 35357 25 auth_protocol = http 26 admin_tenant_name = service 27 admin_user = cinder 28 admin_password = cinderpass |
cinder 서비스를 생성하고 endpoint를 설정한다.
# cinder 서비스 생성 및 endpoint 설정 $ keystone service-create --name=cinder --type=volume --description="OpenStack Block Storage" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | OpenStack Block Storage | | enabled | True | | id | 2c7a47540fec4853963d900a3244ce17 | | name | cinder | | type | volume | +-------------+----------------------------------+ $ keystone endpoint-create --service-id=2c7a47540fec4853963d900a3244ce17 --publicurl=http://192.168.0.11:8776/v1/%\(tenant_id\)s --internalurl=http://192.168.0.11:8776/v1/%\(tenant_id\)s --adminurl=http://192.168.0.11:8776/v1/%\(tenant_id\)s |
cinder 서비스를 하나 더 생성하여 endpoint를 설정한다.
# cinderv2 생성 및 endpoint 설정 $ keystone service-create --name=cinderv2 --type=volumev2 --description="OpenStack Block Storage v2" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | OpenStack Block Storage v2 | | enabled | True | | id | 5d7101a7744c405597b743c1a667785d | | name | cinderv2 | | type | volumev2 | +-------------+----------------------------------+ $ keystone endpoint-create --service-id=5d7101a7744c405597b743c1a667785d --publicurl=http://192.168.0.11:8776/v2/%\(tenant_id\)s --internalurl=http://192.168.0.11:8776/v2/%\(tenant_id\)s --adminurl=http://192.168.0.11:8776/v2/%\(tenant_id\)s |
cinder 관련 대몬을 재시작한다.
# cinder 대몬 재시작 $ sudo service cinder-scheduler restart; sudo service cinder-api restart |
4.1.12 Swift Proxy Server 설치
Swift는 오브젝트 스토리지 서비스로 파일, 문서와 같은 데이터를 저장 및 삭제하고 관리한다. 프록시 서버는 사용자 계정과 컨테이너 등 메타 데이터를 관리하며, 데이터는 분산된 스토리지 노드 여러 대에 저장된다.
swift 계정을 생성하고 생성된 swift 계정을 service tenant와 admin role에 추가한다.
# swift 계정 생성 및 service tenant/admin role 추가 $ . admin-openrc.sh $ keystone user-create --name=swift --pass=swiftpass --email=swift@email.com $ keystone user-role-add --user=swift --tenant=service --role=admin |
swift 서비스를 생성하고 생성된 id 값을 복사하여 endpoint를 추가한다.
# swift 서비스 생성 및 endpoint 추가 $ keystone service-create --name=swift --type=object-store --description="OpenStack Object Storage" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | OpenStack Object Storage | | enabled | True | | id | 4b8e14aaba3c47c9a422377b6082f96c | | name | swift | | type | object-store | +-------------+----------------------------------+ $ keystone endpoint-create --service-id=4b8e14aaba3c47c9a422377b6082f96c --publicurl='http://192.168.0.11:8080/v1/AUTH_%(tenant_id)s' --internalurl='http://192.168.0.11:8080/v1/AUTH_%(tenant_id)s' --adminurl=http://192.168.0.11:8080 |
openssl rand -hex 10 명령어를 사용해 임의의 문자을을 생성해서 /etc/swift/swift.conf 파일에 그림과 같이 적용한다.
# swift.conf 파일 설정 $ openssl rand -hex 10 15150d1b5be2d41b7d2d $ sudo mkdir -p /etc/swift $ sudo vi /etc/swift/swift.conf 1 [swift-hash] 2 # random unique string that can never change (DO NOT LOSE) 3 swift_hash_path_suffix = 15150d1b5be2d41b7d2d |
swift 패키지를 설치한다.
# swift 설치 $ sudo apt-get install swift swift-proxy memcached python-keystoneclient python-swiftclient python-webob |
/etc/swift/proxy-server.conf 파일을 새로 생성해서 그림과 같은 값들을 복사해서 붙여넣기 하자.
# proxy-server.conf 설정 $ sudo vi /etc/swift/proxy-server.conf [DEFAULT] bind_port = 8080 user = swift [pipeline:main] pipeline = healthcheck cache authtoken keystoneauth proxy-server [app:proxy-server] use = egg:swift#proxy allow_account_management = true account_autocreate = true |
# proxy-server.conf 설정 [filter:keystoneauth] use = egg:swift#keystoneauth operator_roles = member,admin,swiftoperator [filter:authtoken] paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory # Delaying the auth decision is required to support token-less # usage for anonymous referrers ('.r:*'). delay_auth_decision = true # cache directory for signing certificate # signing_dir = /home/swift/keystone-signing # auth_* settings refer to the Keystone server auth_protocol = http auth_host = 192.168.0.11 auth_port = 35357 # the service tenant and swift username and password created in Keystone admin_tenant_name = service admin_user = swift admin_password = swiftpass [filter:cache] use = egg:swift#memcache [filter:catch_errors] use = egg:swift#catch_errors [filter:healthcheck] use = egg:swift#healthcheck |
ring-builder를 이용해서 account, container, object builder를 생성한다. 이 때 생성한 ring builder 파일은 스토리지 노드의 데이터를 동기화하는데 중요한 역할을 한다.
그러나 이 부분부터는 스토리지 노드 설정을 완료한 후에 컨트롤러 노드에서 작업하는 것이 더 좋다.
※ 18은 섹터별로 나뉘어지는 파티션의 개수이며 3은 리플리카(replica) 개수를 의미한다. 따라서 스토리지 노드가 5대라면 '18 3 1'로 설정하고 3대 이하라면 '18 1 1'로 설정 한다.
※ 다른 스토리지 노드를 추가한다면 이 부분부터 설정하면 된다.
# ring builder 생성 $ cd /etc/swift $ sudo swift-ring-builder account.builder create 18 3 1 $ sudo swift-ring-builder container.builder create 18 3 1 $ sudo swift-ring-builder object.builder create 18 3 1 |
생성한 링 빌더에 스토리지 노드를 추가한다.
# 링 빌더에 스토리지 노드 추가 $ sudo swift-ring-builder account.builder add r1z1-192.168.0.31:6002/sdb1 100 $ sudo swift-ring-builder container.builder add r1z1-192.168.0.31:6001/sdb1 100 $ sudo swift-ring-builder object.builder add r1z1-192.168.0.31:6000/sdb1 100 |
링 빌더에 스토리지 노드가 잘 추가되었는지 확인한다.
# 링 빌더 테스트 $ sudo swift-ring-builder account.builder $ sudo swift-ring-builder container.builder $ sudo swift-ring-builder object.builder |
링 빌더를 리밸런싱을 하면 *.ring.gz 파일이 생성되는데 이 파일들은 모든 스토리지 노드가 설치된 후 공유되어져야 한다.
# 링 빌더 리밸런싱 $ sudo swift-ring-builder account.builder rebalance $ sudo swift-ring-builder container.builder rebalance $ sudo swift-ring-builder object.builder rebalance |
/etc/swift 디렉토리를 swift 계정이 사용할 수 있도록 권한을 설정한 후 swift-proxy 대몬을 재시작한다.
# swift 디렉토리 권한 설정 및 대몬 재시작 $ sudo chown -R swift:swift /etc/swift $ sudo service swift-proxy restart |
4.1.13 Heat 설치
Heat는 Nova 프로젝트를 통해 가상 인스턴스를 생성하고, 생성된 인스턴스의 네트워크 설정을 자동으로 해주는 서비스이다.
# Heat 설치 $ sudo apt-get install heat-api heat-api-cfn heat-engine |
/etc/heat/heat.conf 파일을 열어 822번라인을 주석처리하고 823번라인을 추가한다.
# heat.conf 파일 수정 $ sudo vi /etc/heat/heat.conf 801 [database] 822 #connection=sqlite:////var/lib/heat/$sqlite_db 823 connection=mysql://heat:heatdbpass@192.168.0.11/heat $ sudo rm /var/lib/heat/heat.sqlite |
mysql에 접속해서 heat 데이터베이스를 생성하고 접속권한을 설정한다.
# heat 데이터베이스 생성 및 권한 설정 $ mysql -u root -p mysql> CREATE DATABASE heat; mysql> GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'localhost' IDENTIFIED BY 'heatdbpass'; mysql> GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'%' IDENTIFIED BY 'heatdbpass'; mysql> exit |
heat-manage 명령어를 이용해 heat 테이블을 생성한다.
※ 경고 메시지가 나오지만 테이블을 정상적으로 생성된다.
# heat 테이블 생성 $ sudo su -s /bin/sh -c "heat-manage db_sync" heat No handlers could be found for logger "heat.common.config" 2015-05-14 16:43:15.133 11640 WARNING heat.openstack.common.db.sqlalchemy.session [-] This application has not enabled MySQL traditional mode, which means silent data corruption may occur. Please encourage the application developers to enable this mode. |
/etc/heat/heat.conf 파일을 열어 RabbitMQ와 Keystone 정보를 설정한다.
# heat.conf 파일 설정 $ sudo vi /etc/heat/heat.conf 1 [DEFAULT] 229 verbose=True 294 log_dir=/var/log/heat 415 rabbit_host=192.168.0.11 431 rabbit_password=rabbitpass 882 [ec2authtoken] 889 auth_uri=http://192.168.0.11:5000/v2.0 1005 [keystone_authtoken] 1017 auth_host=192.168.0.11 1020 auth_port=35357 1024 auth_protocol=http 1027 auth_uri=http://192.168.0.11:5000/v2.0 1052 admin_user=heat 1055 admin_password=heatpass 1059 admin_tenant_name=service |
heat 계정을 생성하고 생성된 heat 계정에 service tenant와 admin role에 추가한다.
# heat 계정 생성 및 service tenant/admin role 추가 $ . admin-openrc.sh $ keystone user-create --name=heat --pass=heatpass --email=heat@email.com $ keystone user-role-add --user=heat --tenant=service --role=admin |
heat 서비스를 생성하고 endpoint를 설정한다.
# heat 서비스 및 endpoint 생성 $ keystone service-create --name=heat --type=orchestration --description="Orchestration" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | Orchestration | | enabled | True | | id | 357c7feeb47e4fe3b328ada9eaa16826 | | name | heat | | type | orchestration | +-------------+----------------------------------+ $ keystone endpoint-create --service-id=357c7feeb47e4fe3b328ada9eaa16826 --publicurl=http://192.168.0.11:8004/v1/%\(tenant_id\)s --internalurl=http://192.168.0.11:8004/v1/%\(tenant_id\)s --adminurl=http://192.168.0.11:8004/v1/%\(tenant_id\)s |
heat-cfn에 대한 서비스를 생성한다. heat-cfn은 사용자가 속한 스택에 대한 정보를 추가/수정/검색과 같은 단순한 인터페이스를 제공하는 Command-line 프로그램이다.
# heat-cfn 서비스 생성 $ keystone service-create --name=heat-cfn --type=cloudformation --description="Orchestration CloudFormation" +-------------+----------------------------------+ | Property | Value | +-------------+----------------------------------+ | description | Orchestration CloudFormation | | enabled | True | | id | 0d6d2181334843b695246d5f8bfa0c7b | |
생성된 서비스에 대해 endpoint를 설정한다.
# endpoint 설정 $ keystone endpoint-create --service-id=0d6d2181334843b695246d5f8bfa0c7b --publicurl=http://192.168.0.11:8000/v1 --internalurl=http://192.168.0.11:8000/v1 --adminurl=http://192.168.0.11:8000/v1 |
heat 서비스를 재시작한다.
# heat 서비스 재시작 $ sudo service heat-api restart; sudo service heat-api-cfn restart; sudo service heat-engine restart |
4.1.14 Ceilometer 설치
Ceilometer는 사용자들이 오픈스택 내에 모든 서비스들에 대한 자원을 얼마나 사용하는지 모니터링 기능을 제공해주는 서비스이다.
# ceilometer 설치 $ sudo apt-get install ceilometer-api ceilometer-collector ceilometer-agent-central ceilometer-alarm-evaluator ceilometer-alarm-notifier python-ceilometerclient |
ceilometer는 다른 서비스와 달리 NoSQL인 MongoDB를 사용하므로 MongoDB를 설치한다.
# mongodb 설치 $ sudo apt-get install mongodb-server |
/etc/mongodb.conf 파일을 열어 bind_ip를 컨트롤러 IP로 변경 후 대몬을 재시작한다.
# mongodb.conf 파일 수정 $ sudo vi /etc/mongodb.conf 11 bind_ip = 192.168.0.11 $ sudo service mongodb restart |
mongodb에 사용자 계정을 추가한다.
# mongodb 사용자 추가 $ mongo --host 192.168.0.11 --eval 'db = db.getSiblingDB("ceilometer"); db.addUser({user: "ceilometer", pwd: "ceilometerdbpass", roles: ["readWrite", "dbAdmin"] })' MongoDB shell version: 2.4.9 connecting to: 192.168.0.11:27017/test { "user" : "ceilometer", "pwd" : "c8e9d18c1687378d638b2bee2138c785", "roles" : [ "readWrite", "dbAdmin" ], "_id" : ObjectId("55545c74c8efd16aa015ca6d") |
/etc/ceilometer/ceilometer.conf 파일을 열어 데이터베이스와 RabbitMQ 정보를 설정한다.
# ceilometer.conf 파일 설정 $ openssl rand -hex 10 8765919e2d0677c9556f $ sudo vi /etc/ceilometer/ceilometer.conf 1 [DEFAULT] 244 log_dir=/var/log/ceilometer 374 rabbit_host=192.168.0.11 390 rabbit_password=rabbitpass 614 [database] 634 #connection=sqlite:////var/lib/ceilometer/$sqlite_db 635 connection = mongodb://ceilometer:ceilometerdbpass@192.168.0.11:27017/ceilometer 908 [publisher] 917 metering_secret=8765919e2d0677c9556f |
ceilometer 계정을 생성하고 생성된 계정에 service tenant와 admin role을 추가한다.
# ceilometer 계정 생성 및 service tenant/admin role 추가 $ keystone user-create --name=ceilometer --pass=ceilometerpass --email=ceilometer@email.com $ keystone user-role-add --user=ceilometer --tenant=service --role=admin |
/etc/ceilometer/ceilometer.conf 파일을 열어 아래의 값들을 그대로 붙여넣는다.
# ceilometer.conf 파일 설정 $ sudo vi /etc/ceilometer/ceilometer.conf 736 [keystone_authtoken] 737 auth_host=192.168.0.11 738 auth_port=35357 739 auth_protocol=http 740 auth_uri=http://192.168.0.11:5000 741 admin_tenant_name=service 742 admin_user=ceilometer 743 admin_password=ceilometerpass 948 [service_credentials] 949 os_auth_url=http://192.168.0.11:5000/v2.0 950 os_username=ceilometer 951 os_tenant_name=service 952 os_password=ceilometerpass |
ceilometer 서비스를 생성하고 endpoint를 설정한다.
# ceilometer 서비스 생성 및 endpoint 설정 $ keystone service-create --name=ceilometer --type=metering --description="Telemetry" | id | eb20fb2f91f04249888bffcaf7079802 | $ keystone endpoint-create --service-id=eb20fb2f91f04249888bffcaf7079802 --publicurl=http://192.168.0.11:8777 --internalurl=http://192.168.0.11:8777 --adminurl=http://192.168.0.11:8777 |
ceilometer 서비스를 재시작한다.
# ceilometer 서비스 재시작 $ sudo service ceilometer-agent-central restart; sudo service ceilometer-api restart; sudo service ceilometer-collector restart; sudo service ceilometer-alarm-evaluator restart; sudo service ceilometer-alarm-notifier restart |
Glance를 Ceilometer에 적용하기 위해 /etc/glance/glance-api.conf 파일을 열어 다음과 같이 수정한 후 glance 대몬을 재시작한다.
# Glance를 Ceilometer에 적용 $ sudo vi /etc/glance/glance-api.conf 237 notification_driver = messaging $ sudo service glance-registry restart; sudo service glance-api restart |
Cinder를 Ceilometer에 적용하기 위해 /etc/cinder/cinder.conf 파일을 열어 다음과 같이 수정 후 cinder 대몬을 재시작한다.
# Cinder를 Ceilometer에 적용 $ sudo vi /etc/cinder/cinder.conf 1 [DEFAULT] 17 control_exchange = cinder 18 notification_driver = cinder.openstack.common.notifier.rpc_notifier $ sudo service cinder-api restart; sudo service cinder-scheduler restart |
Swift를 Ceilometer에 적용하기 위해 ResellerAdmin 룰을 추가한다.
# Cinder를 Ceilometer에 적용 $ keystone role-create --name=ResellerAdmin +----------+----------------------------------+ | Property | Value | +----------+----------------------------------+ | id | 10b929c5b9224251add1d7f8b4d02ce9 | | name | ResellerAdmin | +----------+----------------------------------+ $ keystone user-role-add --tenant service --user ceilometer --role 10b929c5b9224251add1d7f8b4d02ce9 |
/etc/swift/proxy-server.conf 파일을 열어 ceilometer 서비스를 추가를 하고 swift-proxy 대몬을 재시작한다.
※ swift-proxy 대몬 실행할 때 오류가 발생할 때
# swift-proxy-server /etc/swift/proxy-server.conf 명령을 실행하여 오류를 해결
# proxy-server.conf 설정 $ sudo vi /etc/swift/proxy-server.conf 5 [pipeline:main] 6 pipeline = healthcheck cache authtoken keystoneauth ceilometer proxy-server 7 8 [filter:ceilometer] 9 use = egg:ceilometer#swift $ sudo service swift-proxy restart swift-proxy stop/waiting start: Job failed to start |
▶ openstack 클라우드 구축 (네트워크 노드 설치)
▶ openstack 클라우드 구축 (컴퓨터 노드 설치)
▶ openstack 클라우드 구축 (Neutron 네트워크 생성)
▶ openstack 클라우드 구축 (클라우드 이미지 생성)
▶ openstack 클라우드 구축 (클라우드 이미지 등록)