SERVER SIDE / OPENSTACK
cloud.z.com에서 메모리 16기가의 가상머신을 준비했다.
on cloud.z.com, I prepared a virtual machine with 16GB RAM 50G disk.
네트웍은 글로벌 넷트웍하나, 프라이빗네트웍 하나를 준비했다. 글로벌이 eth0, 프라이빗이 eth1로 제공된다.
The network interfaces are two. one for global network and one for private network. the global is provided as eth0 and the private as eth1.
kolla-ansible을 사용해서 가상머신에 openstack 컴포넌트들을 설치했다. 순서는 다음의 qiita를 참고했는데,
I used kolla-ansible to install the openstack components on my virtual machine. I referred following qiita post;
kolla-ansibleでOpenStack(stable/queens)を構築する
여러번 반복해서 하다보니 ansible로 만들었다. 처음에 yum install python-pip -y && pip install ansible
로 시작하면 된다.
as I repeated the installation several times and made it ansible script finally. Start with yum install python-pip -y && pip install ansible
.
anible파일을 kolla-rocky.yml로 저장한 다음 ansible-playbook kolla-rocky.yml
로 실행한다.
You can save the anible file as kolla-rocky.yml and run it as ansible-playbook kolla-rocky.yml
.
# yum install python-pip -y
# pip install ansible
---
- hosts: localhost
vars:
- hoge: ""
tasks:
- name: yum update
yum: name=* state=latest
- name: install kolla rockey
yum:
name: ['epel-release', 'python-pip', 'python-devel', 'libffi-devel', 'gcc', 'openssl-devel', 'libselinux-python', 'git', 'byobu', 'ansible']
- name: edit ansible.cfg
lineinfile:
path: /etc/ansible/ansible.cfg
insertafter: "[defaults]"
line: "{{ item }}"
with_items:
- 'host_key_checking=False'
- 'pipelining=True'
- 'forks=100'
- 'validate_certs=False'
- name: git clone kolla-ansible
git:
repo: 'https://github.com/openstack/kolla-ansible'
dest: /opt/kolla-ansible
version: stable/rocky
- name: install requirements
pip:
requirements: /opt/kolla-ansible/requirements.txt
extra_args: --ignore-installed
- name: install kolla-ansible
command: chdir=/opt/kolla-ansible python setup.py install
- name: copy deploy files
command: cp -r /opt/kolla-ansible/etc/kolla /etc/kolla/
- name: copy deploy inventory files
command: cp -r /opt/kolla-ansible/ansible/inventory/{{item}} /opt
with_items:
- 'all-in-one'
- 'multinode'
- name: generate password filfiles
command: /usr/bin/kolla-genpwd
- name: edit /etc/kolla/globals.yml
lineinfile:
path: /etc/kolla/globals.yml
regexp: "{{ item.regexp }}" # find line
state: present # replace
line: "{{ item.line}}"
with_items:
- { regexp: "^#?kolla_base_distro:", line: 'kolla_base_distro: "centos"'}
- { regexp: "^#?kolla_install_type:", line: 'kolla_install_type: "source"'}
- { regexp: "^#?openstack_release:", line: 'openstack_release: "rocky"'}
- { regexp: "^#?kolla_internal_vip_address:", line: 'kolla_internal_vip_address: "{{ansible_eth0.ipv4.address}}"'}
- { regexp: "^#?docker_registry:", line: 'docker_registry: ""'}
- { regexp: "^#?docker_namespace:", line: 'docker_namespace: "kolla"'}
- { regexp: "^#?network_interface:", line: 'network_interface: "eth0"'}
- { regexp: "^#?neutron_external_interface:", line: 'neutron_external_interface: "eth1"'}
- { regexp: "^#?enable_haproxy:", line: 'enable_haproxy: "no"'}
- { regexp: "^#?nova_compute_virt_type:", line: 'nova_compute_virt_type: "qemu"'}
- name: print message
vars:
msg: |
now you can do following;
cd /opt && kolla-ansible -i all-in-one bootstrap-servers && kolla-ansible -i all-in-one prechecks && kolla-ansible -i all-in-one deploy && kolla-ansible post-deploy && source /etc/kolla/admin-openrc.sh && source /usr/share/kolla-ansible/init-runonce
or
kolla-ansible destroy --yes-i-really-really-mean-it
debug:
msg: "{{ msg.split('\n') }}"
- name: install openstack command
pip:
name: python-openstackclient,python-glanceclient,python-neutronclient
state: latest
- name: print openstack command to create a server
debug:
msg: "openstack server create --image cirros --flavor m1.tiny --key-name mykey --network demo-net demo1"
위의 ansible은 kolla-ansible을 준비하고, 설정을 잡는 것 까지만 한다. 실제로 실행하는 kolla-ansible을 구동하는 코드는 다음과 같다.
The above is for preparation of kolla-ansible environment and configuration. Here is the code to run kolla-ansible which actually executes:
cd /opt && kolla-ansible -i all-in-one bootstrap-servers && kolla-ansible -i all-in-one prechecks && kolla-ansible -i all-in-one deploy && kolla-ansible post-deploy && source /etc/kolla/admin-openrc.sh && source /usr/share/kolla-ansible/init-runonce
OPENSTACK CLIENT SIDE
이쪽은 가상머신으로 윈도우즈를 선택했고, IDE는 pycharm을 설치했다.
I set a Windows virtual machine, and Pycharm IDE.
우선 conda 로 설치할 수 있는 것은 먼저 설치하고, 그렇지 못한 것들은 pip로 라이브러리를 설치했다.
I worked on the things I can install with conda first, and I installed the others with pip.
python code
"""Simple Python script for querying the status of P3 instances.
This script assumes that the following Python 2 packages are installed.
python-openstackclient>=3.12.0
This can be done with the following commands
virtualenv alaska-venv
source alaska-venv/bin/activate
pip install -U pip setuptools
pip install python-openstackclient
This script assumes that the openstack RC file v3 (downloaded from the
OpenStack Hoirizon dashboard) has been sourced, eg.
source p3-openrc.sh
"""
from __future__ import print_function
import sys
import os
import time
import datetime
import logging
from collections import defaultdict
from keystoneauth1.identity import v3
from keystoneauth1 import session
from keystoneclient.v3 import client as keystone_client
from novaclient import client as nova_client
def get_session():
"""Return keystone session"""
# Extract environment variables set when sourcing the openstack RC file.
user_domain = os.environ.get('OS_USER_DOMAIN_NAME')
user = os.environ.get('OS_USERNAME')
password = os.environ.get('OS_PASSWORD')
project_id = os.environ.get('OS_PROJECT_ID')
auth_url = os.environ.get('OS_AUTH_URL')
# Create user / password based authentication method.
# https://goo.gl/VxD2FQ
auth = v3.Password(user_domain_name=user_domain,
username=user,
password=password,
project_id=project_id,
auth_url=auth_url)
# Create OpenStack keystoneauth1 session.
# https://goo.gl/BE7YMt
sess = session.Session(auth=auth)
return sess
def get_user_map(keystone_session):
"""Get map of users from keystone"""
# FIXME(BM) It would be good to get a map of user names - user id
# from keystone but this doenst seem to work...
keystone = keystone_client.Client(session=keystone_session)
print(type(keystone))
projects = keystone.projects.list()
print(projects)
users = keystone.users.list()
print(users)
def get_flavor_map(nova_client):
"""Get a map of flavours"""
log = logging.getLogger(__name__)
flavors = defaultdict()
log.info('Flavours (index | id (short) | name):')
log.info('-' * 80)
for idx, flavor in enumerate(nova_client.flavors.list()):
log.info('%03i | %.8s | %s', idx, flavor.id, flavor.human_id)
flavors[flavor.id] = flavor.human_id
log.info('-' * 80)
log.info('')
return flavors
def query_servers(nova_client):
"""Query list of servers.
Returns a dictionary of server dictionaries with the key being the
server name
"""
log = logging.getLogger(__name__)
log.info('Servers (index | id (short) | name):')
log.info('-' * 80)
servers = defaultdict()
for idx, server in enumerate(nova_client.servers.list()):
log.info('%03i | %.8s | %s', idx, server.id, server.human_id)
server_dict = server.to_dict()
servers[server.human_id] = server_dict
log.info('-' * 80)
log.info('')
return servers
def server_flavour_summary(servers, flavours):
"""Log a summary of servers by flavor."""
log = logging.getLogger(__name__)
log.info('Summary (index | flavour | instance count):')
log.info('-' * 80)
for idx, flavor_id in enumerate(flavours):
count = 0
for key in servers:
if servers[key]['flavor']['id'] == flavor_id:
count += 1
log.info('%03i | %-20s | %i', idx, flavours[flavor_id], count)
log.info('-' * 80)
log.info('')
def user_summary(servers, users):
"""Log a summary of the servers by user."""
log = logging.getLogger(__name__)
user_info = defaultdict()
for idx, key in enumerate(servers):
user_id = servers[key]['user_id']
if user_id not in users:
users[user_id] = 'user-{:02d}'.format(len(users))
if user_id not in user_info:
user_info[user_id] = defaultdict(count=0, server_ids=[])
user_info[user_id]['count'] += 1
user_info[user_id]['server_ids'].append(key)
log.info('Users (index | user id (short) | user name | instance count):')
log.info('-' * 80)
for idx, key in enumerate(user_info):
count = user_info[key]['count']
log.info('%03i | %.8s | %-12s | %-3i',
idx, key, users[key], count)
for server in user_info[key]['server_ids']:
created = time.strptime(servers[server]['created'],
'%Y-%m-%dT%H:%M:%SZ')
age = time.mktime(time.localtime()) - time.mktime(created)
age = datetime.timedelta(seconds=age)
log.debug(' |-> (age: %3id) %-20s', age.days, server)
log.info('-' * 80)
log.info('')
def main():
"""Main function."""
# Get a keystone session.
sess = get_session()
# Create a OpenStack nova client.
# https://goo.gl/ryuyzF
nova = nova_client.Client(version=2, session=sess)
users = defaultdict(str)
users['1d6abb726dd04d4eb4b894e19c397d0e'] = 'Vlad'
flavors = get_flavor_map(nova)
servers = query_servers(nova)
server_flavour_summary(servers, flavors)
user_summary(servers, users)
if __name__ == '__main__':
LOG = logging.getLogger(__name__)
LOG.setLevel(logging.INFO)
LOG.addHandler(logging.StreamHandler(sys.stdout))
main()
conda install -c conda-forge cryptography PyYAML SQLAlchemy bcrypt paramiko
pip install --ignore-installed osc-lib osc-placement python-openstackclient python-glanceclient python-neutronclient python-novaclient kombu kolla Tempest ceilometer keystone shade
실행할 때 환경변수를 넘기는 화면
a screen passing environment variables when running the test