在openstack中,消息的传递一共有两种方式,分别是:服务之间的传递调用Restful api,服务中模块之间的传递使用消息队列。每一个模块在启动是都会启动消息队列,等待队列中的有消息到来。所以模块的启动是openstack运行起来最早做的工作。以nova-compute模块为例,说明该服务模块是如何启动并运行的。
nova的架构设计图如下:
nova启动时使用service命令,如下图:
service命令实际上是调用/etc/init.d/nova-compute来实现的。在/etc/init.d/文件下有一个nova-compute脚本,负责nova-compute的启动,停止,状态查询等。
/etc/init.d/nova-compute脚本的执行是通过/etc/init/nova-compute.conf中的配置项来完成的,下面看看nova-compute.conf文件中的内容。
/etc/init/nova-compute.conf
1 #!/bin/sh 2 ### BEGIN INIT INFO 3 # Provides: nova-compute 4 # Required-Start: $network $local_fs $remote_fs $syslog 5 # Required-Stop: $remote_fs 6 # Should-Start: libvirt-bin postgresql mysql keystone rabbitmq-server ntp neutron-ovs-cleanup 7 # Should-Stop: libvirt-bin postgresql mysql keystone rabbitmq-server ntp 8 # Default-Start: 2 3 4 5 9 # Default-Stop: 0 1 6 10 # Short-Description: Nova Compute server 11 # Description: Provides compute server resources for the 12 # OpenStack cloud computing system 13 ### END INIT INFO 14 15 # Author: Julien Danjou <acid@debian.org> 16 17 # PATH should only include /usr/* if it runs after the mountnfs.sh script 18 PATH=/sbin:/usr/sbin:/bin:/usr/bin 19 DESC="OpenStack Compute" 20 PROJECT_NAME=nova 21 NAME=${PROJECT_NAME}-compute 22 DAEMON_ARGS="" 23 if [ -f '/etc/nova/nova-compute.conf' ] ; then 24 DAEMON_ARGS="--config-file=/etc/nova/nova-compute.conf" 25 fi 26 27 #!/bin/sh 28 # The content after this line comes from openstack-pkg-tools 29 # and has been automatically added to a .init.in script, which 30 # contains only the descriptive part for the daemon. Everything 31 # else is standardized as a single unique script. 32 33 # Author: Thomas Goirand <zigo@debian.org> 34 35 # PATH should only include /usr/* if it runs after the mountnfs.sh script 36 PATH=/sbin:/usr/sbin:/bin:/usr/bin 37 38 if [ -z "${DAEMON}" ] ; then 39 DAEMON=/usr/bin/${NAME} 40 fi 41 PIDFILE=/var/run/${PROJECT_NAME}/${NAME}.pid 42 if [ -z "${SCRIPTNAME}" ] ; then 43 SCRIPTNAME=/etc/init.d/${NAME} 44 fi 45 if [ -z "${SYSTEM_USER}" ] ; then 46 SYSTEM_USER=${PROJECT_NAME} 47 fi 48 if [ -z "${SYSTEM_GROUP}" ] ; then 49 SYSTEM_GROUP=${PROJECT_NAME} 50 fi 51 if [ "${SYSTEM_USER}" != "root" ] ; then 52 STARTDAEMON_CHUID="--chuid ${SYSTEM_USER}:${SYSTEM_GROUP}" 53 fi 54 if [ -z "${CONFIG_FILE}" ] ; then 55 CONFIG_FILE=/etc/${PROJECT_NAME}/${PROJECT_NAME}.conf 56 fi 57 LOGFILE=/var/log/${PROJECT_NAME}/${NAME}.log 58 if [ -z "${NO_OPENSTACK_CONFIG_FILE_DAEMON_ARG}" ] ; then 59 DAEMON_ARGS="--config-file=${CONFIG_FILE} ${DAEMON_ARGS}" 60 fi 61 62 # Exit if the package is not installed 63 [ -x $DAEMON ] || exit 0 64 65 # If ran as root, create /var/lock/X, /var/run/X, /var/lib/X and /var/log/X as needed 66 if [ `whoami` = "root" ] ; then 67 for i in lock run lib ; do 68 mkdir -p /var/$i/${PROJECT_NAME} 69 chown ${SYSTEM_USER}:${SYSTEM_GROUP} /var/$i/${PROJECT_NAME} 70 done 71 for i in log ; do 72 mkdir -p /var/$i/${PROJECT_NAME} 73 chown ${SYSTEM_USER}:adm /var/$i/${PROJECT_NAME} 74 done 75 fi 76 77 # This defines init_is_upstart which we use later on (+ more...) 78 . /lib/lsb/init-functions 79 80 # Manage log options: logfile and/or syslog, depending on user's choosing 81 [ -r /etc/default/openstack ] && . /etc/default/openstack 82 [ -r /etc/default/$NAME ] && . /etc/default/$NAME 83 [ "x$USE_SYSLOG" = "xyes" ] && DAEMON_ARGS="$DAEMON_ARGS --use-syslog" 84 if [ -z "${NO_OPENSTACK_LOGFILE_DAEMON_ARG}" ] ; then 85 [ "x$USE_LOGFILE" != "xno" ] && DAEMON_ARGS="$DAEMON_ARGS --log-file=$LOGFILE" 86 fi 87 88 do_start() { 89 start-stop-daemon --start --quiet --background ${STARTDAEMON_CHUID} --make-pidfile --pidfile ${PIDFILE} --chdir /var/lib/${PROJECT_NAME} --startas $DAEMON \ 90 --test > /dev/null || return 1 91 start-stop-daemon --start --quiet --background ${STARTDAEMON_CHUID} --make-pidfile --pidfile ${PIDFILE} --chdir /var/lib/${PROJECT_NAME} --startas $DAEMON \ 92 -- $DAEMON_ARGS || return 2 93 } 94 95 do_stop() { 96 start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE 97 RETVAL=$? 98 rm -f $PIDFILE 99 return "$RETVAL" 100 } 101 102 do_systemd_start() { 103 exec $DAEMON $DAEMON_ARGS 104 } 105 106 case "$1" in 107 start) 108 init_is_upstart > /dev/null 2>&1 && exit 1 109 log_daemon_msg "Starting $DESC" "$NAME" 110 do_start 111 case $? in 112 0|1) log_end_msg 0 ;; 113 2) log_end_msg 1 ;; 114 esac 115 ;; 116 stop) 117 init_is_upstart > /dev/null 2>&1 && exit 0 118 log_daemon_msg "Stopping $DESC" "$NAME" 119 do_stop 120 case $? in 121 0|1) log_end_msg 0 ;; 122 2) log_end_msg 1 ;; 123 esac 124 ;; 125 status) 126 status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? 127 ;; 128 systemd-start) 129 do_systemd_start 130 ;; 131 restart|force-reload) 132 init_is_upstart > /dev/null 2>&1 && exit 1 133 log_daemon_msg "Restarting $DESC" "$NAME" 134 do_stop 135 case $? in 136 0|1) 137 do_start 138 case $? in 139 0) log_end_msg 0 ;; 140 1) log_end_msg 1 ;; # Old process is still running 141 *) log_end_msg 1 ;; # Failed to start 142 esac 143 ;; 144 *) log_end_msg 1 ;; # Failed to stop 145 esac 146 ;; 147 *) 148 echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload|systemd-start}" >&2 149 exit 3 150 ;; 151 esac 152 153 exit 0
/etc/init/nova-compute.conf
1 # vim: set ft=upstart et ts=2: 2 description "Nova compute worker" 3 author "Soren Hansen <soren@linux2go.dk>" 4 5 start on runlevel [2345] 6 stop on runlevel [!2345] 7 8 chdir /var/run 9 10 env MAX_STATUS_CHECK_RETRIES=20 11 12 pre-start script 13 mkdir -p /var/run/nova 14 chown nova:root /var/run/nova/ 15 16 mkdir -p /var/lock/nova 17 chown nova:root /var/lock/nova/ 18 19 # Only try to modprobe if not running within a container 20 if [ ! -f /run/container_type ]; then 21 modprobe nbd 22 fi 23 24 # If libvirt-bin is installed, always wait for it to start first 25 if status libvirt-bin; then 26 start wait-for-state WAIT_FOR=libvirt-bin WAIT_STATE=running WAITER=nova-compute 27 fi 28 29 # If installed, wait for neutron-ovs-cleanup to complete prior to starting 30 # nova-compute. 31 if status neutron-ovs-cleanup; then 32 # See LP #1471022 for explanation of why we do like this 33 retries=$MAX_STATUS_CHECK_RETRIES 34 delay=1 35 while true; do 36 # Already running? 37 s=`status neutron-ovs-cleanup` 38 echo $s 39 `echo $s| grep -qE "\sstart/running"` && break 40 if retries=`expr $retries - 1`; then 41 # Give it a push 42 echo "Attempting to start neutron-ovs-cleanup" 43 start neutron-ovs-cleanup || : 44 # Wait a bit to avoid hammering ovs-cleanup (which itself may be waiting 45 # on dependencies) 46 echo "Recheck neutron-ovs-cleanup status in ${delay}s" 47 sleep $delay 48 if _=`expr $retries % 2`; then 49 delay=`expr $delay + 2` 50 fi 51 else 52 echo "Max retries ($MAX_STATUS_CHECK_RETRIES) reached - no longer waiting for neutron-ovs-cleanup to start" 53 break 54 fi 55 done 56 fi 57 end script 58 59 exec start-stop-daemon --start --chuid nova --exec /usr/bin/nova-compute -- --config-file=/etc/nova/nova.conf --config-file=/etc/nova/nova-compute.conf
其中最后一行代码是关键代码,这个脚本之所以能启动是执行了nova-compute的可执行脚本,位置在/usr/bin/nova-compute。
/usr/bin/nova-compute
1 #!/usr/bin/python 2 # PBR Generated from u'console_scripts' 3 4 import sys 5 6 from nova.cmd.compute import main 7 8 9 if __name__ == "__main__": 10 sys.exit(main())
该脚本导入了/nova/cmd/compute中的main函数来完成启动任务。
/nova/nova/cmd/compute
1 # Copyright 2010 United States Government as represented by the 2 # Administrator of the National Aeronautics and Space Administration. 3 # All Rights Reserved. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 # not use this file except in compliance with the License. You may obtain 7 # a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 # License for the specific language governing permissions and limitations 15 # under the License. 16 17 """Starter script for Nova Compute.""" 18 19 import shlex 20 import sys 21 22 import os_vif 23 from oslo_log import log as logging 24 from oslo_privsep import priv_context 25 from oslo_reports import guru_meditation_report as gmr 26 27 from nova.cmd import common as cmd_common 28 from nova.conductor import rpcapi as conductor_rpcapi 29 import nova.conf 30 from nova import config 31 from nova import objects 32 from nova.objects import base as objects_base 33 from nova import service 34 from nova import utils 35 from nova import version 36 37 CONF = nova.conf.CONF 38 LOG = logging.getLogger('nova.compute') 39 40 41 def main(): 42 config.parse_args(sys.argv) 43 logging.setup(CONF, 'nova') 44 priv_context.init(root_helper=shlex.split(utils.get_root_helper())) 45 utils.monkey_patch() 46 objects.register_all() 47 # Ensure os-vif objects are registered and plugins loaded 48 os_vif.initialize() 49 50 gmr.TextGuruMeditation.setup_autorun(version) 51 52 cmd_common.block_db_access('nova-compute') 53 objects_base.NovaObject.indirection_api = conductor_rpcapi.ConductorAPI() 54 55 server = service.Service.create(binary='nova-compute', 56 topic=CONF.compute_topic) 57 service.serve(server) 58 service.wait()
1 # Copyright 2010 United States Government as represented by the 2 # Administrator of the National Aeronautics and Space Administration. 3 # All Rights Reserved. 4 # Copyright 2012 Red Hat, Inc. 5 # 6 # Licensed under the Apache License, Version 2.0 (the "License"); you may 7 # not use this file except in compliance with the License. You may obtain 8 # a copy of the License at 9 # 10 # http://www.apache.org/licenses/LICENSE-2.0 11 # 12 # Unless required by applicable law or agreed to in writing, software 13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 # License for the specific language governing permissions and limitations 16 # under the License. 17 18 from oslo_log import log 19 20 from nova.common import config 21 import nova.conf 22 from nova.db.sqlalchemy import api as sqlalchemy_api 23 from nova import rpc 24 from nova import version 25 26 27 CONF = nova.conf.CONF 28 29 30 def parse_args(argv, default_config_files=None, configure_db=True, 31 init_rpc=True): 32 log.register_options(CONF) 33 # We use the oslo.log default log levels which includes suds=INFO 34 # and add only the extra levels that Nova needs 35 if CONF.glance.debug: 36 extra_default_log_levels = ['glanceclient=DEBUG'] 37 else: 38 extra_default_log_levels = ['glanceclient=WARN'] 39 log.set_defaults(default_log_levels=log.get_default_log_levels() + 40 extra_default_log_levels) 41 rpc.set_defaults(control_exchange='nova') 42 config.set_middleware_defaults() 43 44 CONF(argv[1:], 45 project='nova', 46 version=version.version_string(), 47 default_config_files=default_config_files) 48 49 if init_rpc: 50 rpc.init(CONF) 51 52 if configure_db: 53 sqlalchemy_api.configure(CONF)
/nova/nova/service.py
1 class Service(service.Service): 2 """Service object for binaries running on hosts. 3 4 A service takes a manager and enables rpc by listening to queues based 5 on topic. It also periodically runs tasks on the manager and reports 6 its state to the database services table. 7 """ 8 9 def __init__(self, host, binary, topic, manager, report_interval=None, 10 periodic_enable=None, periodic_fuzzy_delay=None, 11 periodic_interval_max=None, db_allowed=True, 12 *args, **kwargs): 13 super(Service, self).__init__() 14 self.host = host 15 self.binary = binary 16 self.topic = topic 17 self.manager_class_name = manager 18 self.servicegroup_api = servicegroup.API() 19 manager_class = importutils.import_class(self.manager_class_name) 20 self.manager = manager_class(host=self.host, *args, **kwargs) 21 self.rpcserver = None 22 self.report_interval = report_interval 23 self.periodic_enable = periodic_enable 24 self.periodic_fuzzy_delay = periodic_fuzzy_delay 25 self.periodic_interval_max = periodic_interval_max 26 self.saved_args, self.saved_kwargs = args, kwargs 27 self.backdoor_port = None 28 self.conductor_api = conductor.API(use_local=db_allowed) 29 self.conductor_api.wait_until_ready(context.get_admin_context())
/nova/nova/service.py
1 @classmethod 2 def create(cls, host=None, binary=None, topic=None, manager=None, 3 report_interval=None, periodic_enable=None, 4 periodic_fuzzy_delay=None, periodic_interval_max=None, 5 db_allowed=True): 6 """Instantiates class and passes back application object. 7 8 :param host: defaults to CONF.host 9 :param binary: defaults to basename of executable 10 :param topic: defaults to bin_name - 'nova-' part 11 :param manager: defaults to CONF.<topic>_manager 12 :param report_interval: defaults to CONF.report_interval 13 :param periodic_enable: defaults to CONF.periodic_enable 14 :param periodic_fuzzy_delay: defaults to CONF.periodic_fuzzy_delay 15 :param periodic_interval_max: if set, the max time to wait between runs 16 17 """ 18 if not host: 19 host = CONF.host 20 if not binary: 21 binary = os.path.basename(sys.argv[0]) 22 if not topic: 23 topic = binary.rpartition('nova-')[2] 24 if not manager: 25 manager_cls = ('%s_manager' % 26 binary.rpartition('nova-')[2]) 27 manager = CONF.get(manager_cls, None) 28 if report_interval is None: 29 report_interval = CONF.report_interval 30 if periodic_enable is None: 31 periodic_enable = CONF.periodic_enable 32 if periodic_fuzzy_delay is None: 33 periodic_fuzzy_delay = CONF.periodic_fuzzy_delay 34 35 debugger.init() 36 37 service_obj = cls(host, binary, topic, manager, 38 report_interval=report_interval, 39 periodic_enable=periodic_enable, 40 periodic_fuzzy_delay=periodic_fuzzy_delay, 41 periodic_interval_max=periodic_interval_max, 42 db_allowed=db_allowed) 43 44 return service_obj
/nova/nova/service.py
1 def serve(server, workers=None): 2 global _launcher 3 if _launcher: 4 raise RuntimeError(_('serve() can only be called once')) 5 6 _launcher = service.launch(CONF, server, workers=workers)
未完待续。。。。。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/194316.html