[ English | Indonesia | Deutsch | 日本語 ]
Menyesuaikan OpenStack Compute (nova) Scheduler¶
Banyak proyek OpenStack memungkinkan penyesuaian fitur tertentu menggunakan arsitektur driver. Anda dapat menulis driver yang sesuai dengan antarmuka tertentu dan menghubungkannya melalui konfigurasi. Misalnya, Anda dapat dengan mudah memasang penjadwal baru untuk Compute. Penjadwal yang ada untuk Compute adalah fitur lengkap dan didokumentasikan dengan baik di Scheduling. Namun, tergantung pada kasus penggunaan pengguna Anda, penjadwal yang ada mungkin tidak memenuhi persyaratan Anda. Anda mungkin perlu membuat penjadwal baru.
Untuk membuat penjadwal, Anda harus mewarisi dari kelas nova.scheduler.driver.Scheduler
. Dari lima metode yang dapat Anda timpa, Anda must mengganti dua metode yang ditandai dengan tanda bintang (*) di bawah ini:
update_service_capabilities
hosts_up
group_hosts
*
schedule_run_instance
*
select_destinations
Untuk mendemonstrasikan penyesuaian OpenStack, kami akan membuat contoh penjadwal Compute yang secara acak menempatkan instance pada subset host, tergantung pada alamat IP asal permintaan dan awalan nama host. Contoh seperti itu bisa berguna ketika Anda memiliki sekelompok pengguna di subnet dan Anda ingin semua instance mereka dimulai dalam beberapa subset dari host Anda.
Peringatan
Contoh ini hanya untuk tujuan ilustrasi. Seharusnya tidak digunakan sebagai scheduler untuk Compute tanpa pengembangan dan pengujian lebih lanjut.
Ketika Anda bergabung dengan sesi layar yang stack.sh
dimulai dengan screen -r stack
, Anda akan disambut dengan banyak jendela layar (screen windows):
0$ shell* 1$ key 2$ horizon ... 9$ n-api ... 14$ n-sch ...
shell
Shell tempat Anda bisa menyelesaikan pekerjaan
key
Layanan keystone
horizon
Aplikasi web dasbor horizon
n-{name}
Layanan nova
n-sch
Layanan penjadwal nova
To create the scheduler and plug it in through configuration
Kode untuk OpenStack hidup di
/opt/stack
, jadi buka direktorinova
dan edit modul penjadwal Anda. Ubah ke direktori tempatnova
diinstal:$ cd /opt/stack/nova
Buat file kode sumber Python
ip_scheduler.py
:$ vim nova/scheduler/ip_scheduler.py
Kode yang ditunjukkan di bawah ini adalah driver yang akan menjadwalkan server ke host berdasarkan alamat IP seperti yang dijelaskan di awal bagian. Salin kode ke
ip_scheduler.py
. Setelah selesai, simpan dan tutup file.# 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)
Ada banyak informasi berguna dalam
context
,request_spec
, danfilter_properties
yang dapat Anda gunakan untuk memutuskan di mana harus menjadwalkan instance. Untuk mengetahui lebih lanjut tentang properti apa yang tersedia, Anda dapat memasukkan pernyataan log berikut ke dalam metodeschedule_run_instance
dari penjadwal di atas:LOG.debug("context = %(context)s" % {'context': context.__dict__}) LOG.debug("request_spec = %(request_spec)s" % locals()) LOG.debug("filter_properties = %(filter_properties)s" % locals())
Untuk menghubungkan penjadwal ini ke nova, edit satu file konfigurasi,
/etc/nova/nova.conf
:$ vim /etc/nova/nova.conf
Temukan konfigurasi
scheduler_driver
dan ubah seperti ini:scheduler_driver=nova.scheduler.ip_scheduler.IPScheduler
Mulai ulang layanan penjadwal nova untuk membuat nova menggunakan penjadwal Anda. Mulailah dengan beralih ke layar (screen)
n-sch
:Tekan Ctrl+A diikuti oleh 9.
Tekan Ctrl+A diikuti oleh N sampai Anda mencapai layar
n-sch
.Tekan Ctrl+C untuk membunuh layanan.
Tekan Up Arrow untuk memunculkan perintah terakhir.
Tekan Enter untuk menjalankannya.
Uji penjadwal Anda dengan nova CLI. Mulailah dengan beralih ke layar
shell
dan selesai dengan beralih kembali ke layarn-sch
untuk memeriksa output log:Teken Ctrl+A diikuti oleh 0.
Pastikan Anda berada di direktori
devstack
:$ cd /root/devstack
Sumber
openrc
untuk mengatur variabel lingkungan Anda untuk CLI:$ . openrc
Masukkan ID image untuk satu-satunya image yang diinstal ke dalam variabel lingkungan:
$ IMAGE_ID=`openstack image list | egrep cirros | egrep -v "kernel|ramdisk" | awk '{print $2}'`
Boot server uji:
$ openstack server create --flavor 1 --image $IMAGE_ID scheduler-test
Beralih kembali ke layar
n-sch
. Di antara pernyataan log, Anda akan melihat baris:2014-01-23 19:57:47.262 DEBUG nova.scheduler.ip_scheduler [req-... demo demo] Request from xx.xx.xx.xx scheduled to devstack-havana _schedule /opt/stack/nova/nova/scheduler/ip_scheduler.py:76
Peringatan
Pengujian fungsional seperti ini bukan pengganti untuk pengujian unit dan integrasi yang tepat, tetapi berfungsi untuk membantu Anda memulai.
Pola serupa dapat diikuti dalam proyek lain yang menggunakan arsitektur driver. Cukup buat modul dan kelas yang sesuai dengan antarmuka driver dan hubungkan melalui konfigurasi. Kode Anda berjalan ketika fitur itu digunakan dan dapat memanggil layanan lain yang diperlukan. Tidak ada kode core proyek yang disentuh. Cari nilai "driver" di file konfigurasi .conf
proyek di /etc/<project>
untuk mengidentifikasi proyek yang menggunakan arsitektur driver.
Ketika penjadwal Anda selesai, kami menganjurkan Anda untuk membuka sumbernya dan memberi tahu komunitas di milis OpenStack. Mungkin orang lain membutuhkan fungsi yang sama. Mereka dapat menggunakan kode Anda, memberikan umpan balik, dan mungkin berkontribusi. Jika ada cukup dukungan untuk itu, mungkin Anda dapat mengusulkan agar ditambahkan ke penjadwal Compute resmi <https://opendev.org/openstack/nova/src/branch/master/nova/scheduler> `_.