OpenStack не может выполнять все что вам нужно делать нетривиальным способом. Чтобы добавить новую функцию, вы можете следовать разными путями.
Первый способ- вы можете напрямую изменить код OpenStack. Ознакомьтесь: как внести свой вклад, следуйте рабочим потоком пересмотра кода, сделайте необходимые изменения и внесите их в назад вверх по течению проекта OpenStack. Этот путь рекомендуется, если необходимое вам свойство требует глубокой интеграции с уже существующим проектом. Сообщество всегда открыто для вклада и приветствует новую функциональность, которая следует руководством развития новых свойств. Этот путь все еще требует от вас использования DevStack для тестирования дополняемых вами функций, так что это глава ознакомит вас со средой DevStack.
Следуя вторым подходом, вы можете написать новые функции и подключить их при помощи изменения в файле конфигурации. Если проект, в котором ваша функциональная особенность для своего размещения будет нуждаться в использовании инфраструктуры Python Paste, вы можете создать программное обеспечение промежуточного уровня для него и подключить его при помощи настройки. Также могут существовать особые способы настройки проекта, например, создание нового драйвера планировщика для вычислительной среды или пользовательские вкладки для приборной панели.
В этой главе основное внимание уделено второму способу настройки OpenStack путем демонстрации двух примеров для написания новых функциональных особенностей. Первый пример показывает как внести изменения в программное обеспечение промежуточного уровня хранилища объектов (swift) добавив новую функцию, а второй пример предоставляет новую функцию планировщика для вычислительной среды OpenStack Compute (nova). Для подобной настройки OpenStack вам вы понадобится среда разработки. Лучший способ быстро получить среду и приступить к работе- это запустить DevStack в вашем облаке.
Для создания среды разработки вы можете воспользоваться DevStack. DevStack по- существу является набором скриптов оболочки и файлами настройки, которые создают для вас среду разработки OpenStack. Вы используете их для создания подобной среды для разработки нового свойства.
Всю документацию вы можете найти на веб-сайте DevStack.
Чтобы запустить DevStack для стабильной ветви Havana в экземпляре вашего облака OpenStack:
-
Загрузите экземпляр из инструментальной панели или при помощи интерфейса командной строки (CLI) со следующими параметрами:
-
Имя: devstack-havana
-
Образ: Ubuntu 12.04 LTS
-
Объем оперативной памяти: 4ГБ
-
Дисковый размер: минимум 5ГБ
Если вы используете клиент
nova
, установите--flavor 3
для командыnova boot
для получения отвечающих требованиям объема оперативной памяти и дискового пространства. -
-
Войдите в систему и установите DevStack. Приведем пример команд, которые вы можете использовать для установки DevStack на виртуальную машину:
-
Зарегистрируйтесь в экземпляре:
$ ssh
username
@my.instance.ip.address
-
Обновите операционную систему виртуальной машины:
# apt-get -y update
-
Установите git:
# apt-get -y install git
-
Склонируйте стабильную ветвь havana из репозитория
devstack
:$ git clone https://github.com/openstack-dev/devstack.git -b stable/havana devstack/
-
Переместитесь в свой репозиторий
devstack
:$ cd devstack
-
-
(Не обязательно) Ксли вы зарегистрировались в системе как пользователь root, вы должны создать пользователя "stack"; в противном случае вы можете испытывать проблемы с разрешениями. Если вы зарегистрировались как пользователь, отличный от root, вы можете пропустить эти шаги:
-
Выполните сценарий DevStack для создания пользователя stack:
# tools/create-stack-user.sh
-
Предоставьте пользователю stack права владельца на каталог
devstack
:# chown -R stack:stack /root/devstack
-
Установите некоторые разрешения, которыми вы позже сможете воспользоваться для просмотра экрана DevStack:
# chmod o+rwx /dev/pts/0
-
Переключитесь на пользователя stack:
$ su stack
-
-
Отредактируйте файл настройки
localrc
, который управляет размещением DevStack. Скопируйте пример файлаlocalrc
в конце данного раздела (Пример 15.1, “localrc”):$ vim localrc
-
Выполните сценарий stack, который установит OpenStack:
$ ./stack.sh
-
Когда сценарий stack завершится, вы можете открыть окно стартовавшего сеанса для просмотра всех запущенных служб OpenStack:
$ screen -r stack
-
Нажмите Ctrl+A с последующим 0 для перехода к первому окну
screen
.
Замечание | |
---|---|
|
Тепер, когда вы получили среду разработки OpenStack, вы может свободно заняться хакерством без беспокойства о том, что вы можете что-то разрушить в вашем развернутом продукте. Пример 15.1, “localrc” предоставляет работающее окружение для выполнения служб OpenStack идентификации, вычислительной среды, блочного хранения, образов, инструментальной панели и хранилища объектов со стабильной ветвью havana в качестве исходной точки.
Пример 15.1. localrc
# Credentials ADMIN_PASSWORD=devstack MYSQL_PASSWORD=devstack RABBIT_PASSWORD=devstack SERVICE_PASSWORD=devstack SERVICE_TOKEN=devstack # OpenStack Identity Service branch KEYSTONE_BRANCH=stable/havana # OpenStack Compute branch NOVA_BRANCH=stable/havana # OpenStack Block Storage branch CINDER_BRANCH=stable/havana # OpenStack Image Service branch GLANCE_BRANCH=stable/havana # OpenStack Dashboard branch HORIZON_BRANCH=stable/havana # OpenStack Object Storage branch SWIFT_BRANCH=stable/havana enable_service swift # Object Storage Settings SWIFT_HASH=66a3d6b56c1f479c8b4e70ab5c2000f5 SWIFT_REPLICAS=1 # Block Storage Setting VOLUME_BACKING_FILE_SIZE=20480M # Output LOGFILE=/opt/stack/logs/stack.sh.log VERBOSE=True LOG_COLOR=False SCREEN_LOGDIR=/opt/stack/logs
Хранилище объектов OpenStack, известное как swift при чтении кодов, основано на инфраструктуре Python Paste. Лучшим введениев в ее архитектуру является A Do-It-Yourself Framework (Создайте собственную инфраструктуру). Поскольку проект swift использует эту инфраструктуру, вы можете добавлять новые функции в проект путем размещения пользовательского кода в конвейере проекта без каких- либо изменений в код ядра.
Представьте себе ситуацию, при которой у вас есть общественный доступ к одной из ваших контейнеров, однако в действительности вы хотите ограничить доступ к этому набору IP-адресов на основе белого списка. В данном примере мы создадим часть программного обеспечения промежуточного уровня для swift, которая позволяет получить доступ к контейнеру только из набора IP-адресов, которые определены элементами метаданных контейнера. Только те IP-адреса, которые вы явно занесли в белый список при помощи метаданных контейнера, смогут получить доступ к контейнеру.
Когда вы присоединитесь к экрану сеанса, который запустил
stack.sh
при помощи screen -r stack
,
вы увидите по экрану для каждой работающей службы, которых может быть немного или определенное
количество: в зависимости от того как много служб настроен выполнять ваш DevStack.
Звездочка * обозначает какое окно экрана вы наблюдаете. Данный пример демонстрирует, что мы просмативаем окно экрана key (для keystone):
0$ shell 1$ key* 2$ horizon 3$ s-proxy 4$ s-object 5$ s-container 6$ s-account
Цели для окон экрана следующие:
shell
-
Оболочка, в которой вы можете выполнять некую работу
key*
-
Служба keystone
horizon
-
Веб-приложение инструментальной панели horizon
s-{name}
-
Службы swift
Чтобы создать программное обеспечение промежуточного уровня и подключить его при помощи настройки Paste:
Все коды для OpenStack размещаются в /opt/stack
.
Перейдите в каталог swift в оболочке
экрана
и отредактируйте ваш модуль ПО промежуточного уровя.
-
Перейдите в каталог, в котором установлено хранилище объектов:
$ cd /opt/stack/swift
-
Создайте файл кода Python
ip_whitelist.py
:$ vim swift/common/middleware/ip_whitelist.py
-
Скопируйте код из Примера 15.2, “ip_whitelist.py” в ваш
ip_whitelist.py
. Следующий код является образцом промежуточного программного обеспечения, которое ограничивает доступ к контейнеру на основе IP адресов, как это объяснялось в начале данного раздела. Промежуточное ПО передает запросы другому приложению. Данный пример использует библиотеку swift "swob" для обертывания запросов и ответов Web Server Gateway Interface (WSGI) к объектам для взаимодействия со swift. По окончанию сохраните и закройте файл.Пример 15.2. ip_whitelist.py
# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright (c) 2014 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import socket from swift.common.utils import get_logger from swift.proxy.controllers.base import get_container_info from swift.common.swob import Request, Response class IPWhitelistMiddleware(object): """ IP Whitelist Middleware Middleware that allows access to a container from only a set of IP addresses as determined by the container's metadata items that start with the prefix 'allow'. E.G. allow-dev=192.168.0.20 """ def __init__(self, app, conf, logger=None): self.app = app if logger: self.logger = logger else: self.logger = get_logger(conf, log_route='ip_whitelist') self.deny_message = conf.get('deny_message', "IP Denied") self.local_ip = socket.gethostbyname(socket.gethostname()) def __call__(self, env, start_response): """ WSGI entry point. Wraps env in swob.Request object and passes it down. :param env: WSGI environment dictionary :param start_response: WSGI callable """ req = Request(env) try: version, account, container, obj = req.split_path(1, 4, True) except ValueError: return self.app(env, start_response) container_info = get_container_info( req.environ, self.app, swift_source='IPWhitelistMiddleware') remote_ip = env['REMOTE_ADDR'] self.logger.debug("Remote IP: %(remote_ip)s", {'remote_ip': remote_ip}) meta = container_info['meta'] allow = {k:v for k,v in meta.iteritems() if k.startswith('allow')} allow_ips = set(allow.values()) allow_ips.add(self.local_ip) self.logger.debug("Allow IPs: %(allow_ips)s", {'allow_ips': allow_ips}) if remote_ip in allow_ips: return self.app(env, start_response) else: self.logger.debug( "IP %(remote_ip)s denied access to Account=%(account)s " "Container=%(container)s. Not in %(allow_ips)s", locals()) return Response( status=403, body=self.deny_message, request=req)(env, start_response) def filter_factory(global_conf, **local_conf): """ paste.deploy app factory for creating WSGI proxy apps. """ conf = global_conf.copy() conf.update(local_conf) def ip_whitelist(app): return IPWhitelistMiddleware(app, conf) return ip_whitelist
В
env
иconf
существует много полезной информации которую вы можете использовать для принятия решения о том что делать с запросом. Для поиска того какие еще свойства доступны, вы можете вставить следующий оператор в метод__init__
:self.logger.debug("conf = %(conf)s", locals())
и следующий оператор протоколирования в метод
__call__
:self.logger.debug("env = %(env)s", locals())
-
Чтобы вставить это промежуточное по в конвейер swift Paste, вы редактируете один файл настройки,
/etc/swift/proxy-server.conf
:$ vim /etc/swift/proxy-server.conf
-
Найдите раздел
[filter:ratelimit]
в/etc/swift/proxy-server.conf
, и скопируйте следующий сегмент настройки после него:[filter:ip_whitelist] paste.filter_factory = swift.common.middleware.ip_whitelist:filter_factory # You can override the default log routing for this filter here: # set log_name = ratelimit # set log_facility = LOG_LOCAL0 # set log_level = INFO # set log_headers = False # set log_address = /dev/log deny_message = You shall not pass!
-
Найдите раздел
[pipeline:main]
в/etc/swift/proxy-server.conf
, и добавьте вперечень после ratelimitip_whitelist
подобный приведенному ниже. Когда завершите редактирование, сохраните и закройте файл:[pipeline:main] pipeline = catch_errors healthcheck proxy-logging cache bulk slo ratelimit ip_whitelist ...
-
Перезапустите службу
swift proxy
позволив swift использовать ваше промежуточное ПО. Начните с переключения на экранswift-proxy
:-
Нажмите Ctrl+A с последующим 3.
-
Нажмите Ctrl+C для прекращения службы.
-
Нажмитена клавишу стрелки Вверх для отображения последней команды.
-
Нажмите Enter для еевыполнения.
-
-
Проверьте свое промежуточное ПО с CLI
swift
. Начните с переключения на экран оболочки завершите переключением назад на экранswift-proxy
для проверки выдачи протокола:-
Нажмите Ctrl+A с последующим 0.
-
Убедитесь, что вы находитесь в каталоге
devstack
:$ cd /root/devstack
-
Чтобы установить переменные окружения для CLI, получите openrc:
$ source openrc
-
Создайте контейнер с названием
middleware-test
:$ swift post middleware-test
-
Нажмите Ctrl+A с последующим 3 для проверки выдачи протокола.
-
-
Среди предложений журнала вы можете увидеть строки:
proxy-server Remote IP: my.instance.ip.address (txn: ...) proxy-server Allow IPs: set(['my.instance.ip.address']) (txn: ...)
Эти два предложения выполнены нашим промежуточным ПО и показывают, что запрос был отослан из нашего экземпляра DevStack и был разрешен.
-
Проверьте наше промежуточное ПО извне DevStack на удаленной машине, которая имеет доступ к вашему экземпляру DevStack:
-
Установите клиентов
keystone
иswift
на вашу локальную машину:# pip install python-keystoneclient python-swiftclient
-
Попробуйте отобразить список объектов в контейнере
middleware-test
:$ swift --os-auth-url=http://my.instance.ip.address:5000/v2.0/ \ --os-region-name=RegionOne --os-username=demo:demo \ --os-password=devstack list middleware-test Container GET failed: http://my.instance.ip.address:8080/v1/AUTH_.../ middleware-test?format=json 403 Forbidden You shall not pass!
-
-
Нажмите Ctrl+A с последующим 3для проверки выдачи протокола. Взгляните снова на предложения swift в журнале, вы увидите строки:
proxy-server Authorizing from an overriding middleware (i.e: tempurl) (txn: ...) proxy-server ... IPWhitelistMiddleware proxy-server Remote IP: my.local.ip.address (txn: ...) proxy-server Allow IPs: set(['my.instance.ip.address']) (txn: ...) proxy-server IP my.local.ip.address denied access to Account=AUTH_... \ Container=None. Not in set(['my.instance.ip.address']) (txn: ...)
Здест вы можете увидеть, что запрос был запрещен, поскольку IP удаленного узла не был установлен в список разрешенных.
-
Вернитесь в ваш экземпляр DevStack на экран оболочки, дабавьте немного метаданных в ваш контейнер для разрешения запросов с удаленной машины:
-
Нажмите Ctrl+A с последующим 0.
-
Добавьте метаданные в контейнер для разрешения данного IP:
$ swift post --meta allow-dev:my.local.ip.address middleware-test
-
Теперь попробуйте снова повторить команды начиная с шага 10 и далее. В контейнере нет объектов, следовательно нечего отображать; однако также отсутствуют сообщения об ошибках.
-
Предостережение | |
---|---|
Функциональное тестирование подобное приведенному не замещает надлежащего тестирования блоков и интеграции, однако служит началом для вас. |
Вы можете следовать подобному шаблону в других проектах, которые используют
инфраструктуру Python Paste. Просто создайте модуль промежуточного ПО
и подключите его при помощи настройки. Промежуточное программное обеспечение
работает в последовательности как часть конвейера проекта по необходимости может вызывать
другие службы. Не затрагивается никакой код ядра проекта. Найдите значение
pipeline
в файлах настройки проекта
conf
или ini
в
/etc/<project>
для выявления проектов,
использующих.
Когда ваше промежуточное программное обеспечение готово, мы советуем вам сделать его код открытым и и оповестить о нем сообщество через список электронной почтовой рассылки OpenStack. Возможно кому-то еще требуется подобная функциональность. Люди смогут воспользоваться вашим кодом и снабдить вас обратной связью, а также, возможно, сделать пожертвования. Если для вашего кода окажется достаточно поддержки, вы сможете предложить добавить его в официальное программное обеспечение промежуточного уровня swift middleware.
Многие проекты OpenStack допускабт настройку под индивидуальные требования пользователя особенных свойств с использованием архитектуры драйверов. Вы можете написать драйвер, который соответствует определенному интерфейсу и подключить его с использованием настроек. Например, вы легко можете подключить новый планировщик к вычислительной среде. Существующие планировщики для вычислительной среды функционально полны и хорошо документированы на странице Scheduling. Однако, в зависимости от случаев использования вашими пользователями, существующие планировщики могут не отвечать вашим требованиям. Возможно, вам потребуется создать новый планировщик.
Для создания планировщика вы должны наследовать из класса
nova.scheduler.driver.Scheduler
.
Из пяти методов, которые вы можете переписывать, вы должны
переписать два метода, помеченных ниже звездочкой (*):
-
update_service_capabilities
-
hosts_up
-
group_hosts
-
*
schedule_run_instance
-
*
select_destinations
Для демонстрации настройки OpenStack под индивидуального пользователя, мы создадим пример планировщика вычислительных ресурсов, который случайным образом размещает экземпляры в подмножестве хостов в зависимости от IP адреса инициации запроса и префикса имени хоста. Данный пример может оказаться полезным для случая, когда у вас есть группа пользователей подсети и вы хотите чтобы все их экземпляры запускались в пределах некоторого подмножества ваших хостов.
Предостережение | |
---|---|
Данный пример приводится исключеительно для иллюстрации. Он не должен использоваться в планировщике для вычислительной среды без дальнейшей доработки и тестирования. |
Когда вы присоединяетесь к сеансу, который запустил stack.sh
при помощи screen -r stack
, вас встречает множество окон
экрана:
0$ shell* 1$ key 2$ horizon ... 9$ n-api ... 14$ n-sch ...
shell
-
Оболочка, в которой вы можете выполнять некоторую работу
key
-
Служба keystone
horizon
-
Веб- приложение инструментальной панели horizon
n-{name}
-
Службы nova
n-sch
-
Служба планировщика nova
Чтобы создать планировщик и вставить его в конфигурацию:
-
Код для OpenStack расположен в
/opt/stack
, следовательно, перейдите в каталогnova
и отредактируйте ваш модуль планировщика. Перейдитев каталог, в котором установленnova
:$ cd /opt/stack/nova
-
Создайте исходный файл кода Python
ip_scheduler.py
:$ vim nova/scheduler/ip_scheduler.py
-
Код в Примере 15.3, “ip_scheduler.py” является драйвером, который будет управлять серверами для размещения на основе IP адресов, как это объяснялось в начале раздела. Скопируйте код в
ip_scheduler.py
. По окончанию сохраните и закройте файл.Пример 15.3. ip_scheduler.py
# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright (c) 2014 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ IP Scheduler implementation """ import random from oslo.config import cfg from nova.compute import rpcapi as compute_rpcapi from nova import exception from nova.openstack.common import log as logging from nova.openstack.common.gettextutils import _ from nova.scheduler import driver CONF = cfg.CONF CONF.import_opt('compute_topic', 'nova.compute.rpcapi') LOG = logging.getLogger(__name__) class IPScheduler(driver.Scheduler): """ Implements Scheduler as a random node selector based on IP address and hostname prefix. """ def __init__(self, *args, **kwargs): super(IPScheduler, self).__init__(*args, **kwargs) self.compute_rpcapi = compute_rpcapi.ComputeAPI() def _filter_hosts(self, request_spec, hosts, filter_properties, hostname_prefix): """Filter a list of hosts based on hostname prefix.""" hosts = [host for host in hosts if host.startswith(hostname_prefix)] return hosts def _schedule(self, context, topic, request_spec, filter_properties): """Picks a host that is up at random.""" elevated = context.elevated() hosts = self.hosts_up(elevated, topic) if not hosts: msg = _("Is the appropriate service running?") raise exception.NoValidHost(reason=msg) remote_ip = context.remote_address if remote_ip.startswith('10.1'): hostname_prefix = 'doc' elif remote_ip.startswith('10.2'): hostname_prefix = 'ops' else: hostname_prefix = 'dev' hosts = self._filter_hosts(request_spec, hosts, filter_properties, hostname_prefix) if not hosts: msg = _("Could not find another compute") raise exception.NoValidHost(reason=msg) host = random.choice(hosts) LOG.debug("Request from %(remote_ip)s scheduled to %(host)s" % locals()) return host def select_destinations(self, context, request_spec, filter_properties): """Selects random destinations.""" num_instances = request_spec['num_instances'] # NOTE(timello): Returns a list of dicts with 'host', 'nodename' and # 'limits' as keys for compatibility with filter_scheduler. dests = [] for i in range(num_instances): host = self._schedule(context, CONF.compute_topic, request_spec, filter_properties) host_state = dict(host=host, nodename=None, limits=None) dests.append(host_state) if len(dests) < num_instances: raise exception.NoValidHost(reason='') return dests def schedule_run_instance(self, context, request_spec, admin_password, injected_files, requested_networks, is_first_time, filter_properties, legacy_bdm_in_spec): """Create and run an instance or instances.""" instance_uuids = request_spec.get('instance_uuids') for num, instance_uuid in enumerate(instance_uuids): request_spec['instance_properties']['launch_index'] = num try: host = self._schedule(context, CONF.compute_topic, request_spec, filter_properties) updated_instance = driver.instance_update_db(context, instance_uuid) self.compute_rpcapi.run_instance(context, instance=updated_instance, host=host, requested_networks=requested_networks, injected_files=injected_files, admin_password=admin_password, is_first_time=is_first_time, request_spec=request_spec, filter_properties=filter_properties, legacy_bdm_in_spec=legacy_bdm_in_spec) except Exception as ex: # NOTE(vish): we don't reraise the exception here to make sure # that all instances in the request get set to # error properly driver.handle_schedule_error(context, ex, instance_uuid, request_spec)
Существует много полезной информации в
context
,request_spec
иfilter_properties
, которую вы можете использовать для принятия решения о том где запланировать экземпляр. Для ознакомления с дополнительной информацией о доступных свойствах вы можете вставить следующие операторы протоколирования в методschedule_run_instance
приведенного выше планировщика:LOG.debug("context = %(context)s" % {'context': context.__dict__}) LOG.debug("request_spec = %(request_spec)s" % locals()) LOG.debug("filter_properties = %(filter_properties)s" % locals())
-
Для вставки этого планировщика в nova, отредактируйте один файл настройки, а именно,
/etc/nova/nova.conf
:$ vim /etc/nova/nova.conf
-
Найдите настройку
scheduler_driver
и змените ее примерно так:scheduler_driver=nova.scheduler.ip_scheduler.IPScheduler
-
Перезапустите службу планировщика nova, чтобы позволить nova использовать ваш планировщик. Начните с переключения на экран
n-sch
:-
Нажмите Ctrl+A с последующим 9.
-
Нажимайте Ctrl+A с последующим N пока не достигните экрана
n-sch
. -
Нажмите Ctrl+C для прекращения службы.
-
Нажмите клавишу со стрелкой Вверх для вызова последней команды.
-
Yf;vbnt Enter для ее запуска.
-
-
Проверьте свой новый планировщик с применением nova CLI. Начните со переключения на экран
shell
и завершите переключением на экранn-sch
для проверки выдачи протоколов:-
Нажмите Ctrl+A с последующим 0.
-
Убедитесь что вы находитесь в каталоге
devstack
:$ cd /root/devstack
-
Чтобы получить переменные окружения для CLI, установите источник
openrc
:$ source openrc
-
Поместите ID образа для единственного установленного образа в переменную окружения:
$ IMAGE_ID=`nova image-list | egrep cirros | egrep -v "kernel|ramdisk" | awk '{print $2}'`
-
Загрузите пробный сервер:
$ nova boot --flavor 1 --image $IMAGE_ID scheduler-test
-
-
Переключитесь назад на экран
n-sch
. Среди предложений журнала вы увидите строку:2014-01-23 19:57:47.262 DEBUG nova.scheduler.ip_scheduler \ [req-... demo demo] Request from 162.242.221.84 \ scheduled to devstack-havana \ _schedule /opt/stack/nova/nova/scheduler/ip_scheduler.py:76
Предостережение | |
---|---|
Функциональное тестирование подобно приведенному не подменяет соответствующее тестирование блоков и интеграции, однако служит отправной точкой. |
Аналогичным образом можно следовать в других проектах, которые используют
архитектуру драйвера. Просто создайте модуль и класс, которые соответствуют
интерфейсу драйвера и вставьте его при помощи настройки. Ваш код работает при использовании
данной функциональной особенности и, по необходимости, может вызывать другие службы.
Никакой код ядра проекта не затрагивается. Осуществите поиск значения "driver"
в файлах настройки .conf
проекта в /etc/<project>
для выявления проектов, которые используют
архитектуру драйвера.
Когда ваш планировщик завершен, мы рекомендуем вам открытьего код и дать знать о нем сообществу через список рассылки электронной почты OpenStack. Возможно кому-то еще требуется подобная функциональность. Люди смогут воспользоваться вашим кодом и снабдить вас обратной связью, а также, возможно, сделать пожертвования. Если для вашего кода окажется достаточно поддержки, возможно, вы сможете предложить его добавление в официальное программное обеспечение промежуточного уровня вычислительной среды schedulers.
Инструментальная панель основана на инфраструктуре веб-приложения Python Django Лучшееруководствопо индивидуальной настройке ужебыло написано и его можно найти по ссылке Building on Horizon (Построение Horizon).
При эксплуатации облака OpenStack, вы можете обнаружить, что ваши пользователи могут оказаться довольно требовательными. Если OpenStack не выполняет что-то, в чем нуждаются ваши пользователи, по вашему усмотрению, можно выполнить эти требования. Данная глава предоставляет вам некоторые параметры для индивидуальной настройки и снабжает вас инструментарием, необходимым вам для начала.