Giter VIP home page Giter VIP logo

openstack-note's People

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

openstack-note's Issues

windows server 2012 R2 镜像制作

kvm制作链接
系统安装链接
如果用vmware做,虚拟磁盘类型为IDE, 若为其他,如SATA,需要手动修改为IDE
要先下载镜像virtio和,cloudbase_init
sudo virt-install --name=ws2012r2 --ram=2048 --vcpus=2 --os-type=windows --os-variant=win2k12r2 --disk /images/win2012/win2012_r2.qcow2,bus=virtio --disk /images/win2012/winserver2012.ISO,device=cdrom --disk /images/win2012/virtio-win-0.1.141.iso,device=cdrom,bus=ide --network network=default,model=virtio --graphics vnc,listen=0.0.0.0 --noautoconsole
problem: ioctl(KVM_CREATE_VM) failed: 12 Cannot allocate memory ---宿主机内存不够了
image
设置MTU


    进入系统盘:\Windows\System32\找到cmd.exe,右键“以管理员身份运行”;
    在出现的“命令提示符”窗口中输入“netsh interface ipv4 show subinterfaces”并回车来查看当前的MTU值
    接下来输入“netsh interface ipv4 set subinterface “需修改的连接名” mtu=你得出的合理值 store=persistent”并回车即可 例如:“netsh interface ipv4 set subinterface “本地连接” mtu=1450 store=persistent”

设置远程桌面rdp
remote settings

设置用户自动登陆----能极大的提高实例创建速度
control userpasswords2
https://jingyan.baidu.com/article/7e440953eabd742fc0e2efae.html
改默认密码

改配置文件
virsh edit winserver
把下面的参数:

 <input type='mouse' bus='ps2'/> 
<input type='keyboard' bus='ps2'/>

改为
    <input type='tablet' bus='usb'>
      <address type='usb' bus='0' port='1'/>
    </input>

关闭开机之后的服务器管理器

docker file sample

FROM ubuntu:16.04                  

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

RUN mkdir /home/attack


RUN apt install -y vim
RUN apt install -y python
RUN apt install -y python-pip


 proxy_pip='--trusted-host mirrors.aliyun.com -i http://mirrors.aliyun.com/pypi/simple/'
RUN pip install --upgrade pip $proxy_pip
RUN pip install pwntools scapy zio $proxy_pip

COPY run_attack.sh /home/
COPY ./attack /home/attack

#ENTRYPOINT service ssh start && bash
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

说明: FROM 是源,定义了docker image的位置,
RUN 一般用来系统安装程序和执行的命令
EXPOSE 是指开放的端口
CMD 一般为系统某服务的命令

qemu用法及快照链

qemu

qemu-img命令:

  1. check 对磁盘镜像文件进行一致性检查,查找镜像文件中的错误
    qemu-img check g1.img

2.create
create [-f fmt] [-o options] filename [size]

创建一个格式为fmt大小为size文件名为filename的镜像文件
  	 qemu-img create -f qcow2 /data/centos6.qcow2 6G

3.commit
commit [-f fmt] filename

提交filename文件中的更改到后端支持镜像文件(创建时通过backing_file指定的)中去。
qemu-img commit -f qcow2 centos.snap0 
     将快照的内容恢复(提交)到原镜像

4.convert 镜像文件格式转换
qemu-img convert -O qcow2 rhel6u3.img rhel6u3-a.img
5.info 查看文件信息
qemu-img info rhel6u3-a.img
image: rhel6u3-a.img

file format: qcow2

virtual size: 8.0G (8589934592 bytes)

disk size: 6.8G

cluster_size: 65536
  1. resize为centos6.qcow2增加2G空间
# qemu-img resize centos6.qcow2 +2G

# qemu-img resize rhel6u3-b.img -1G

Image resized.

快照链

qemu的内置快照和外置快照
https://www.cnblogs.com/jython/p/4301954.html
内置快照
快照数据和base磁盘数据放在一个qcow2文件中。
qemu-img snapshot -c 快照名称 centos6.qcow2
外置快照
快照数据单独的qcow2文件存放。
virsh snapshot-create-as cirros extsnap2 --disk-only –atomic
在多次快照之后会形成一个外部快照链,新的快照使用前一个快照的镜像文件作为backing file

image

Qemu-kvm

Qemu是一个模拟器,它向Guest OS模拟CPU和其他硬件,Guest OS认为自己和硬件直接打交道,其实是同Qemu模拟出来的硬件打交道,Qemu将这些指令转译给真正的硬件。

Qemu将KVM整合进来,通过ioctl调用/dev/kvm接口,将有关CPU指令的部分交由内核模块来做。kvm负责cpu虚拟化+内存虚拟化,实现了cpu和内存的虚拟化,但kvm不能模拟其他设备。qemu模拟IO设备(网卡,磁盘等),kvm加上qemu之后就能实现真正意义上服务器虚拟化。因为用到了上面两个东西,所以称之为qemu-kvm。

virsh blockcommit 快照的变更往镜像合并
virsh blockpull 镜像的变更往快照合并

查看qemu的版本qemu-img --help | grep version

将多个vmdk合并为一个
/usr/bin/vmware-vdiskmanager -r source.vmdk -t 0 desc.vmdk
将vmdk格式转为qow2格式qemu-img convert -f vmdk -O qcow2 BT5.vmdk blackTrack.qcow2

kvm:

qemu-kvm:主要的KVM程序包,该软件包主要包含KVM内核模块和基于KVM重构后的QEMU模拟器。KVM模块作为整个虚拟化环境的核心工作在系统空间,负责CPU和内存的调度。QEMU作为模拟器工作在用户空间,负责虚拟机I/O模拟。
qemu-img:主要用来QEMU磁盘镜像的管理,如新建一块磁盘镜像给虚拟机。
libvirt:提供Hypervisor和虚拟机管理的API。
libvirt-client:KVM客户端命令行管理工具virsh,负责虚拟机的启动、停止和管理等。

libvirt-daemon:libvirtd守护进程,作为客户端管理工具跟Hypervisor和虚拟机之间的桥梁。
libvirt-daemon-driver-xxx:从名字来看属于libvirtd服务的驱动文件,作为libvirtd服务跟Hypervisor不同对象(如qemu模拟器,网络,存储等)间的接口。

libvirt-python:python的libvirt库
python-virtinst:创建虚拟机所需要的命令行工具和程序库

virt-install:创建和克隆虚拟机的命令行工具包。
virt-manager:图形界面的KVM管理工具。
virt-top:虚拟机统计命令
virt-viewer:GUI连接程序,连接到已配置好的虚拟机

bridge-utils:网桥管理工具包,负责桥接网络的创建、配置和管理等工作。

openstack 常见模块启动(重启)命令

#systemctl enable chronyd.service
systemctl restart chronyd.service
##数据库服务##
#systemctl enable mariadb.service
systemctl restart mariadb.service
##消息队列##
#systemctl enable rabbitmq-server.service
systemctl restart rabbitmq-server.service
##Memcached##
#systemctl enable memcached.service
systemctl restart memcached.service
##Apache服务##
#systemctl enable httpd.service
systemctl restart httpd.service
##镜像glance服务##
#systemctl enable openstack-glance-api.service openstack-glance-registry.service
systemctl restart openstack-glance-api.service openstack-glance-registry.service
##计算服务nova nova-api##
#systemctl enable openstack-nova-api.service openstack-nova-consoleauth.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service openstack-nova-compute.service
systemctl restart openstack-nova-api.service openstack-nova-consoleauth.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service
systemctl restart openstack-nova-compute.service
##网络服务neutron##
#systemctl enable neutron-server.service neutron-linuxbridge-agent.service neutron-dhcp-agent.service neutron-metadata-agent.service
systemctl restart neutron-server.service neutron-linuxbridge-agent.service neutron-dhcp-agent.service neutron-metadata-agent.service
#systemctl enable neutron-l3-agent.service
systemctl restart neutron-l3-agent.service

openstack 各组件去keystone

说明:
去keystone不是指去掉这个组件
1.nova 组建

  nova.conf 中 auth_strategy = keystone 改为 auth_strategy = noauth2
  nova.api.openstack.auth:NoAuthMiddleware这个方法:

将base_call函数中
    token = req.headers['X-Auth-Token']  
    user_id, _sep, project_id = token.partition(':')  
    project_id = project_id or user_id  

修改为
    token = req.headers['X-Auth-Token']  
    user_id = req.headers.get('X-Auth-User', 'admin')  
    project_id = req.headers.get('X-Auth-Project-Id', None)  
    if not project_id:  
        raise webob.exc.HTTPInternalServerError(  
                _('Invalid project id.'))  

2.neutron
neutron.conf 中 auth_strategy = keystone 改为auth_strategy = noauth

3.cinder
cinder.conf 中 auth_strategy = keystone 改为auth_strategy = noauth

4.glance (待尝试)

各模块paste-deploy文件路径(pike)

nova :
/etc/nova/api-paste.ini
glance:

 /usr/share/glance/glance-api-dist-paste.ini
 /usr/share/glance-registry-dist-paste.ini 

cinder:
/etc/cinder/api-paste.ini
neutron:
/usr/share/neutron/api-paste.ini

openstack 各模块api

可以在火狐上装RESTClient来调试
keystone

 获取token    
参数:{"auth": {"passwordCredentials": {"username": username, "password": password}, "tenantName":  tenantName}}
            url = http://controller:35357/v2.0/tokens   
            username = admin
            password = ADMIN_PASS
            tenantName = admin
            values = {"auth": {"passwordCredentials": {"username": username, "password": password}, "tenantName": tenantName}}
            params = json.dumps(values)
            headers = {"Content-type": "application/json", "Accept": "application/json"}
            req = urllib2.Request(url, params, headers)
            response = urllib2.urlopen(req)
            data = response.read()

NOVA:

instance

 获取所有实例                       http://controller:8774/v2.1/servers(method --get)
 获取某个实例的详情             http://controller:8774/v2.1/servers/instance_id (method --get)
 删除某个实例                         http://controller:8774/v2.1/servers/instance_id (method --delete)
 启动暂停等
  url = 'http://controller:8774/v2.1/servers/' + id + '/action'
     data ={
        'pause': 'null'
     }
     data=json.dumps(data)
     req = urllib2.Request(url,data )
     req.add_header('X-Auth-Token', token)
     req.get_method = lambda: 'POST'

flavor

 获取所有flavor    http://controller:8774/v2.1/flavors
 获取某个flavor详情    http://controller:8774/v2.1/flavors/id
 删除某个flavor    http://controller:8774/v2.1/flavors/id (delete)

images

获取所有images    http://controller:9292/v2/images
获取某个images详情    http://controller:9292/v2/images/id
删除某个images    http://controller:9292/v2/images/id (delete)

ZUN

获取所有docker镜像       http://controller:9517/v1/images
  获取所有docker实例       http://controller:9517/v1/containers
  删除某个docker实例      http://controller:9517/v1/containers/id(delete)
 暂停/停止/restart某个docker实例      http://controller:9517/v1/containers/操作(post)

NEUTRON

network

查看所有网络      http://controller:9696/v2.0/networks
  查看某个网络详情      http://controller:9696/v2.0/networks/id
  删除某个网络      http://controller:9696/v2.0/networks/id(delete)

subnet

  查看所有子网     http://controller:9696/v2.0/subnets
  查看某个子网详情      http://controller:9696/v2.0/subnets/id
   删除某个子网      http://controller:9696/v2.0/subnets/id(delete)

router

查看所有路由      http://controller:9696/v2.0/routers/
 查看某个路由详情      http://controller:9696/v2.0/routers/id
 删除某个路由      http://controller:9696/v2.0/routers/id(delete)

floatingip

 查看所有浮动IP    http://controller:9696/v2.0/floatingips
  查看某个浮动IP详情    http://controller:9696/v2.0/floatingips/id
  删除某个浮动IP    http://controller:9696/v2.0/floatingips/id(delete)

fwaas_v2

firewall_groups

 查看所有firewall_groups           http://controller:9696/v2.0/fwaas/firewall_groups
  查看某个firewall_groups详情    http://controller:9696/v2.0/fwaas/firewall_groups/id
  删除某个firewall_groups           http://controller:9696/v2.0/fwaas/firewall_groups/id(delete)

firewall_policies

 查看所有firewall_policies      http://controller:9696/v2.0/fwaas/firewall_policies
  查看某个firewall_policies详情    http://controller:9696/v2.0/fwaas/firewall_policies/id
  删除某个firewall_policies    http://controller:9696/v2.0/fwaas/firewall_policies/id(delete)

firewall_rules

 查看所有firewall_rules      http://controller:9696/v2.0/fwaas/firewall_rules
  查看某个firewall_rules详情    http://controller:9696/v2.0/fwaas/firewall_rules/id
  删除某个firewall_rules    http://controller:9696/v2.0/fwaas/firewall_rules/id(delete)

markdown_test

  1. Item 1
  2. Item 2
  3. Item 3
    1. Item 3a
    2. Item 3b
  • Item 1
  • Item 2
    • Item 2a
    • Item 2b

This is an

tag

This is an

tag

This is an
tag

This text will be italic
This will also be italic

This text will be bold
This will also be bold

You can combine them

cinder nfs 配置lnt_create: RPC: Program not registered

nfs环境搭建报错clnt_create: RPC: Program not registered

有时候搭建完成后,使用showmount -e ip检测服务端服务器情况的是,会出现clnt_create: RPC: Program not registered

这个错误,表示rpc程序为注册成功,解决方案就是:

以此关闭nfs和rpcbind

命令:

/etc/init.d/nfs stop

/etc/init.d/rpcbind stop

再依次启动服务:

命令:(注意先启动rpc)

/etc/init.d/rpcbind start

/etc/init.d/nfs start

openstack pdb调试

pdb的用法

[break 或 b 设置断点
continue 或 c 继续执行程序, 或是跳到下个断点
list 或 l 查看当前行的代码段
step 或 s 进入函数
return 或 r 执行代码直到从当前函数返回
exit 或 q 中止并退出
next 或 n 执行下一行
p 或! 打印变量的值,例如p a
help 或 h 帮助](url)

在要调试的代码前面加上 import pdb; pdb.set_trace()

然后在命令行(不能通过systemd执行)直接运行服务即可。
假如想跟踪nova创建虚拟机的过程,首先在nova/api/openstack/compute/servers.py模块的create方法打上断点,如下:


```python
@wsgi.response(202)
    @extensions.expected_errors((400, 403, 409, 413))
    @validation.schema(schema_server_create_v20, '2.0', '2.0')
    @validation.schema(schema_server_create, '2.1', '2.18')
    @validation.schema(schema_server_create_v219, '2.19')
    def create(self, req, body):
        """Creates a new server for a given user."""

        import pdb; pdb.set_trace() # 设置断点
        context = req.environ['nova.context']
        server_dict = body['server']
        password = self._get_server_admin_password(server_dict)
        name = common.normalize_name(server_dict['name'])

        if api_version_request.is_supported(req, min_version='2.19'):
            if 'description' in server_dict:
                # This is allowed to be None
                description = server_dict['description']
            else:
                # No default description
                description = None
        else:
            description = name
        ...

然后注意需要通过命令行直接运行,而不是通过systemd启动:

su -c 'nova-api' nova

此时调用创建虚拟机API,nova-api进程就会马上弹出pdb shell,此时你可以通过s或者n命令一步一步执行了。
在执行su -c 'nova-api' nova可能会报错
This account is currently not available
解决办法

cat /etc/passwd | grep nova

发现它的shell是“/sbin /nologin”,需要将起改成“/bin/bash”

vi /etc/passwd

修改完毕后,保存退出

oslo_config.cfg.ConfigFilesPermissionDeniedError: Failed to open some config files:

Nov 14 12:01:48 compute2 systemd[1]: Started OpenStack Compute.
Nov 14 12:01:49 compute2 nova-compute[3222]: Traceback (most recent call last):
Nov 14 12:01:49 compute2 nova-compute[3222]:   File "/usr/bin/nova-compute", line 10, in <module>
Nov 14 12:01:49 compute2 nova-compute[3222]:     sys.exit(main())
Nov 14 12:01:49 compute2 nova-compute[3222]:   File "/usr/lib/python2.7/dist-packages/nova/cmd/compute.py", line 42, in main
Nov 14 12:01:49 compute2 nova-compute[3222]:     config.parse_args(sys.argv)
Nov 14 12:01:49 compute2 nova-compute[3222]:   File "/usr/lib/python2.7/dist-packages/nova/config.py", line 52, in parse_args
Nov 14 12:01:49 compute2 nova-compute[3222]:     default_config_files=default_config_files)
Nov 14 12:01:49 compute2 nova-compute[3222]:   File "/usr/lib/python2.7/dist-packages/oslo_config/cfg.py", line 2355, in __call__
Nov 14 12:01:49 compute2 nova-compute[3222]:     self._namespace._files_permission_denied)
Nov 14 12:01:49 compute2 nova-compute[3222]: oslo_config.cfg.ConfigFilesPermissionDeniedError: Failed to open some config files: /etc/nova/nova.conf
Nov 14 12:01:49 compute2 systemd[1]: nova-compute.service: Main process exited, code=exited, status=1/FAILURE

Which shows that my /etc/nova/nova.conf file was unreadable. It turns out this was because I used scp to copy the nova.conf from my first compute to my new machine, and the file was read-only to the root user. The solution was to (on my new compute)

cd /etc/nova/
chown nova:nova nova.conf
service nova-compute restart

openstack 问题集锦

  1. there is not available-zone
    nova availability-zone-list 查看所有zone及其状态
    进入admin目录查看Host Aggregates中zone的状态,发现zone nova的状态被关闭了
    进入hypervisor打开zone
    一个openstack问题记录博客

2.分配浮动IP 问题
External network is not reachable from subnet
在为内部网络机器分配浮动IP 的时候报错
解决办法: 为这两个网络建路由,就可以成功分配浮动IP

openstack 的数据库操作(以nova为例)

在较老的版本中,nova 是通过nova-compute直接操作数据库的,因为解偶和安全性等原因在后来的版本中新开发了nova-conductor专门操作数据库。

nova-conductor服务,该服务的一个重要作用就是访问数据库,其它服务访问数据库时需要向nova-conductor发起RPC请求,由nova-conductor代理请求数据库。

以上方式基本解决了服务与数据库访问解耦,并且防止其它服务直接访问数据库,但仍然没有解决对象模型的版本控制。从I版本开始引入了对象模型的概念,所有的对象模型定义在nova/objects。在此之前访问数据库是直接调用数据库的model的,比如更新一个flavor一个字段,调用Flavor的update方法(由sqlalchemy)实现。引入对象模型后,相当于在服务与数据库之间又添加了一级对象层,各个服务直接和资源对象交互,资源对象再和数据库接口交互,数据库返回时也会相应的转化为对象模型中的对象。

源码分析
3.1 nova-compute源码分析

本小节主要以删除虚拟机为例,分析nova-compute在删除虚拟机时如何操作数据库的。删除虚拟机的API入口为nova/compute/manager.py的_delete_instance方法,方法原型为:

_delete_instance(self, context, instance, bdms, quotas)

该方法有4个参数,context是上下文信息,包含用户、租户等信息,instance就是我们上面提到的对象模型中Instance对象实例,bdms是blockDeviceMappingList对象实例,保存着block设备映射列表,quotas是nova.objects.quotas.Quotas对象实例,保存该租户的quota信息。

该方法涉及的数据库操作代码为:

instance.vm_state = vm_states.DELETED
instance.task_state = None
instance.power_state = power_state.NOSTATE
instance.terminated_at = timeutils.utcnow()
instance.save()
system_meta = instance.system_metadata
instance.destroy()

从代码中可以看到,首先更新instance的几个字段,然后调用save()方法保存到数据库中,最后调用destroy方法删除该实例(注意,这里的删除并不一定是真的从数据库中删除记录,也有可能仅仅做个删除的标识)。

我们先找到以上的save()方法,它位于nova/object/instance.py模块中,方法原型为:

@base.remotable save(self, expected_vm_state=None, expected_task_state=None, admin_state_reset=False)

save方法会记录需要更新的字段,并调用db接口保存到数据库中。关键是该方法的wrapper remotable,这个注解(python不叫注解,不过为了习惯这里就叫注解吧)非常重要,该方法在oslo中定义:

def remotable(fn):
    """Decorator for remotable object methods."""
    @six.wraps(fn)
    def wrapper(self, *args, **kwargs):
        ctxt = self._context
        if ctxt is None:
            raise exception.OrphanedObjectError(method=fn.__name__,
                                                objtype=self.obj_name())
        if self.indirection_api:
            updates, result = self.indirection_api.object_action(
                ctxt, self, fn.__name__, args, kwargs)
            for key, value in six.iteritems(updates):
                if key in self.fields:
                    field = self.fields[key]
                    # NOTE(ndipanov): Since VersionedObjectSerializer will have
                    # deserialized any object fields into objects already,
                    # we do not try to deserialize them again here.
                    if isinstance(value, VersionedObject):
                        setattr(self, key, value)
                    else:
                        setattr(self, key,
                                field.from_primitive(self, key, value))
            self.obj_reset_changes()
            self._changed_fields = set(updates.get('obj_what_changed', []))
            return result
        else:
            return fn(self, *args, **kwargs)

    wrapper.remotable = True
    wrapper.original_fn = fn
    return wrapper

从代码看到,当indirection_api不为None时会调用indirection_api的object_action方法,由前面我们知道这个值由配置项use_local决定,当use_local为False时indirection_api为conductor_rpcapi.ConductorAPI。从这里了解到对象并不是通过一堆if-else来判断是否使用use_local的,而是通过@Remotable注解实现的,remotable封装了if-else,当使用local时直接调用原来对象实例的save方法,否则调用indirection_api的object_action方法。

注意: 除了@Remotable注解,还定义了@remotable_classmethod注解,该注解功能和@Remotable类似,仅仅相当于又封装了个@classmethod注解。
3.2 RPC调用

前面我们分析到调用conductor_rpcapi.ConductorAPI的object_action方法,该方法在nova/conductor/rpcapi.py中定义:

def object_action(self, context, objinst, objmethod, args, kwargs):
        cctxt = self.client.prepare()
        return cctxt.call(context, 'object_action', objinst=objinst,
                          objmethod=objmethod, args=args, kwargs=kwargs)

rpcapi.py封装了client端的所有RPC调用方法,从代码上看,发起了RPC server端的object_action同步调用。此时nova-compute工作顺利转接到nova-conductor,并堵塞等待nova-conducor返回。
3.3 nova-conductor源码分析

nova-conductor RPC server端接收到RPC请求后调用manager.py的object_action方法(nova/conductor/manager.py):

def object_action(self, context, objinst, objmethod, args, kwargs):
     """Perform an action on an object."""
     oldobj = objinst.obj_clone()
     result = self._object_dispatch(objinst, objmethod, args, kwargs)
     updates = dict()
     # NOTE(danms): Diff the object with the one passed to us and
     # generate a list of changes to forward back
     for name, field in objinst.fields.items():
         if not objinst.obj_attr_is_set(name):
             # Avoid demand-loading anything
             continue
         if (not oldobj.obj_attr_is_set(name) or
                 getattr(oldobj, name) != getattr(objinst, name)):
             updates[name] = field.to_primitive(objinst, name,
                                                getattr(objinst, name))
     # This is safe since a field named this would conflict with the
     # method anyway
     updates['obj_what_changed'] = objinst.obj_what_changed()
     return updates, result

该方法首先调用obj_clone()方法备份原来的对象,主要为了后续统计哪些字段更新了。然后调用了_object_dispatch方法:

def _object_dispatch(self, target, method, args, kwargs):
        try:
            return getattr(target, method)(*args, **kwargs)
        except Exception:
            raise messaging.ExpectedException()

该方法利用反射机制通过方法名调用,这里我们的方法名为save方法,因此显然调用了target.save()方法,即最终还是调用的instance.save()方法,不过此时已经是在conductor端调用了.

又回到了nova/objects/instance.py的save方法,有人会说难道这不会无限递归RPC调用吗?显然不会,这是因为nova-conductor的indirection_api为None,在@Remotable中肯定走else分支。

openstack各模块常用命令(pike版)

openstack命令行手册
NOVA
查看所有的域及其状态 nova availability-zone-list

   openstack server list 查看所有的虚拟机
   openstack image list 查看所有的镜像
   openstack network list 查看所有的网络
   openstack floating ip list 查看所有浮动IP 
   openstack router list 查看所有路由
   openstack firewall group list 查看所有防火墙分组
   openstack user list 查看所有用户
   openstack endpoint list  查看所有endpoint 
   openstack service list   查看所有服务
   openstack console  log show serverid 查看某个实例的启动日志
   
Flavor
 查看所有flavor               nova flavor-list   openstack flavor list
 创建Flavor                    nova flavor-create test.flavor 2 2048 20 1(默认是public)
     说明 : 第一个为ID ,第二个为内存memory单位MB, 第三个是DISK 磁盘大小 单位G,第四个是Vcpu
 删除Flavor                   nova flavor-delete flavor_id

查看所有服务及其状态  nova service-list
Instance
查看所有实例       nova list
创建实例               nova boot  --flavor flavor名  --image 镜像名  --nic net-id=网络ID    --security-group default   实例名(falvor,image,网络,实例名为必选)
删除实例       nova delete 实例名或者ID 
nova 操作名   实例名或者ID (可以暂停,删除等等)
nova volume-list查看volume列表
nova volume-attach 主机名 volume_id 将volume挂载到demo-instance1虚机
nova get-vnc-console 主机名 novnc   获取到VNC的web登录地址,直接输入获取到的http地址到浏览器即可登录虚机

Neutron
查看所有网络 neutron net-list
查看一个网络的详细信息: neutron net-show
列出所有的agent neutron agent-list
删除一个网络: neutron net-delete

ZUN
zun image-list 查看所有docker 镜像 docker images
zun list 和docker ps对应,查看所有容器
zun add-security-group Add security group for specified container.


      attach                     Attach to a running container.
          commit                   Create a new image from a container's changes.
          cp                           Copy files/tars between a container and the local filesystem.
          create                    Create a container.
          delete                   Delete specified containers.
          exec                     Execute command in a running container.
          kill                         Kill one or more running container(s).
          list                           Print a list of available containers.
         logs                       Get logs of a container.
         network-attach      Attach a network to the container.
        network-detach      Detach a network from the container.
        pause                    Pause specified containers.
        remove-security-group
                                         Remove security group for specified container.
        rename                     Rename a container.
       restart                       Restart specified containers.
       run                             Run a command in a new container.
       show                           Show details of a container.
       start                           Start specified containers.
       stats                           Display stats snapshot of the container.
       stop                           Stop specified containers.
       top                              Display the running processes inside the container.
       unpause                     Unpause specified containers.
       update                        Update one or more attributes of the container.
       image-list                    Print a list of available images.
       image-search              Print list of available images from repository based
                        on user query.
       image-show                Describe a specific image.
       pull                              Pull an image.
       service-delete             Delete the Zun binaries/services.
       service-disable           Disable the Zun service.
      service-enable            Enable the Zun service.
      service-force-down     Force Zun service to down or unset the force state.
      service-list                   Print a list of zun services.
      host-list                       Print a list of available host.
      host-show                  Show details of a host.

在命令中间加‘--debug’ 可以看到命令执行流程
例子:
openstack --debug server list
nova --debug list

GET call to compute for http://controller:8774/v2.1/flavors/detail used request id req-d88e14db-873e-46b7-b76a-d9ba827d604a
+--------------------------------------+--------------------------------------+--------+-------------------------------------+--------------------+--------------+
| ID                                   | Name                                 | Status | Networks                            | Image              | Flavor       |
+--------------------------------------+--------------------------------------+--------+-------------------------------------+--------------------+--------------+
| abb8f6a0-bcc9-441c-a0e9-757dcbfa340f | XOJ_ENV.test.得到的.wanggw-test-win7 | ACTIVE | External=10.98.98.23                | wanggw-test-win7   | m3.4c-4g-20g |
| e6299955-64b5-4c98-b67b-0ad07764176f | test_sf                              | ACTIVE | External=10.98.98.33                | win2000            | m3.1c-1g-20g |
| f56b3768-5748-4395-a37a-b199844699a0 | glb-prof-1                           | ACTIVE | External=10.98.98.12                | openSUSE-Leap-42.3 | m2.2c-2g-10g |
| 498035f0-104c-48b7-8fd8-8df77c23eaaa | glb-1                                | ACTIVE | External=10.98.98.3                 | ubuntukylin-18.04  | m4.4c-4g-40g |
| 4116eb6d-0f69-4f81-b3c5-b84063e2c5b2 | oj2222                               | ACTIVE | External=10.98.98.21                | OJ-0716            | OJ-large     |
| 06e5a956-d1c1-4a4a-bc8b-0586289e2280 | 漏洞库                               | ACTIVE | External=10.98.98.13                | vulhub             | m2.2c-2g-50g |
| 849b9b85-bd0a-47eb-9224-3f9ce48be53f | OJ                                   | ACTIVE | admin-net=192.168.200.9, 10.98.98.4 | OJ_snap0607        | OJ-large     |
+--------------------------------------+--------------------------------------+--------+-------------------------------------+--------------------+--------------+
clean_up ListServer: 

连接openstack 创建的虚拟机

如何远程链接openstack上启动的虚拟机(vnc,spice)
首先到计算节点执行命令:ps -ef|grep nova,找到对应的虚拟机信息,比如uuid,vnc或者spice端口
然后打开vnc viewer或者 spice的客户端,或者remote viewer,在VNC中输入命令:计算节点IP:VNC端口
  或者在remote viewer上输入spice://计算节点IP:spice端口(spice比vnc清楚)

linux远程连接Windows
rdesktop -f -a 16 windows IP

keystone role、user、project

openstack Keystone权限
User:指使用Openstack service的用户,可以是人、服务、系统,但凡使用了Openstack service的对象都可以称为User。

Project(Tenant):可以理解为一个人、或服务所拥有的 资源集合 。在一个Project(Tenant)中可以包含多个User,每一个User都会根据权限的划分来使用Project(Tenant)中的资源。比如通过Nova创建虚拟机时要指定到某个Project中,在Cinder创建卷也要指定到某个Project中。User访问Project的资源前,必须要与该Project关联,并且指定User在Project下的Role。

Role:用于划分权限。可以通过给User指定Role,使User获得Role对应的操作权限。Keystone返回给User的Token包含了Role列表,被访问的Services会判断访问它的User和User提供的Token中所包含的Role。系统默认使用管理Role admin和成员Role member

Policy:OpenStack对User的验证除了OpenStack的身份验证以外,还需要鉴别User对某个Service是否有访问权限。Policy机制就是用来控制User对Tenant中资源(包括Services)的操作权限。对于Keystone service来说,Policy就是一个JSON文件,默认是/etc/keystone/policy.json。通过配置这个文件,Keystone Service实现了对User基于Role的权限管理。

Token:是一个字符串表示,作为访问资源的令牌。Token包含了在 指定范围和有效时间内 可以被访问的资源。EG. 在Nova中一个tenant可以是一些虚拟机,在Swift和Glance中一个tenant可以是一些镜像存储,在Network中一个tenant可以是一些网络资源。Token一般被User持有。

Credentials:用于确认用户身份的凭证

Authentication:确定用户身份的过程

Service:Openstack service,即Openstack中运行的组件服务。

Endpoint:一个可以通过网络来访问和定位某个Openstack service的地址,通常是一个URL。比如,当Nova需要访问Glance服务去获取image 时,Nova通过访问Keystone拿到Glance的endpoint,然后通过访问该endpoint去获取Glance服务。我们可以通过Endpoint的region属性去定义多个region。Endpoint 该使用对象分为三类:

admin url –> 给admin用户使用,Post:35357

internal url –> OpenStack内部服务使用来跟别的服务通信,Port:5000

public url –> 其它用户可以访问的地址,Post:5000

创建完service后创建API EndPoint. 在openstack中,每一个service都有三种end points. Admin, public, internal。 Admin是用作管理用途的,如它能够修改user/tenant(project)。 public 是让客户调用的,比如可以部署在外网上让客户可以管理自己的云。internal是openstack内部调用的。三种endpoints 在网络上开放的权限一般也不同。Admin通常只能对内网开放,public通常可以对外网开放internal通常只能对安装有openstack对服务的机器开放。

各模块相关服务及状态查看命令

NOVA
总的查看命令 systemctl status openstack-nova-*

     nova console-log 实例ID  可以查看实例的日志
     nova-compute         systemctl  status openstack-nova-compute
     nova-novncproxy    systemctl  status openstack-nova-novncproxy
     nova-conductor       systemctl  status openstack-nova-conductor
     nova-consoleauth   systemctl  status openstack-nova-consoleauth
     nova-api                  systemctl  status openstack-nova-api
     nova-scheduler       systemctl  status openstack-nova-scheduler

Neutron

systemctl status neutron-* 这个查不全

neutron-server         systemctl status neutron-server
 l3-agent                   systemctl status neutron-l3-agent
 dhcp-agent              systemctl status neutron-dhcp-agent
 linux-bridge-agent   systemctl status neutron-linuxbridge-agent 
 metadata-agent       systemctl status neutron-metadata-agent

Glance

glance-api systemctl status openstack-glance-api
glance-registry systemctl status openstack-glance-registry

Keystone

  httpd                      systemctl status httpd
  memcached          systemctl status memcached

Rabbitmq

` rabbitmq-server      systemctl status rabbitmq-server`

zun
systemctl status zun-* 这个查不全

 zun-api               systemctl status  zun-api
 zun-compute      systemctl status  zun-compute
 zun-wsproxy       systemctl status  zun-wsproxy
 docker                systemctl status  docker
 kuryr                   systemctl status  kuryr-libnetwork

pike 脚本安装

##########################################
#参数

#获取第一块网卡名、ip地址
Net=ip add|egrep global|awk '{ print $NF }'|head -n 1
IP=ip add|grep global|awk -F'[ /]+' '{ print $3 }'|head -n 1
echo "网卡名称:$Net"
echo "IP地址: $IP"

#安装wget
yum -y install wget

#添加pike源
echo '添加openstack库'
yum -y install centos-release-openstack-pike

yum -y upgrade
echo '安装openstack客户端'
yum -y install python-openstackclient
echo '安装openstack selinux'

yum -y install openstack-selinux

#参数
DBPass=root #SQL root密码
Node=controller #节点名(controller不要改动)
Netname=$Net #网卡名称
MyIP=$IP #IP地址
VncProxy=$IP #VNC代理外网IP地址
Imgdir=/home/glance #自定义glance镜像目录
VHD=/home/nova #自定义Nova实例路径
Kvm=qemu #QEMU或KVM ,KVM需要硬件支持

##########################################
#1、设置

echo '关闭selinux、防火墙'
systemctl stop firewalld.service
systemctl disable firewalld.service
firewall-cmd --state
sed -i '/^SELINUX=./c SELINUX=disabled' /etc/selinux/config
sed -i 's/^SELINUXTYPE=./SELINUXTYPE=disabled/g' /etc/selinux/config
grep --color=auto '^SELINUX' /etc/selinux/config
setenforce 0

echo '设置hostname'
hostnamectl set-hostname $Node
echo "$MyIP $Node">>/etc/hosts

#安装mariadb

echo '安装mariadb'
yum -y install mariadb mariadb-server python2-PyMySQL
echo '修改mariadb配置'
#cp /etc/my.cnf.d/openstack.cnf{,.bak}
touch /etc/my.cnf.d/openstack.cnf
echo "#
[mysqld]
bind-address = 0.0.0.0
default-storage-engine = innodb
innodb_file_per_table
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8
#">/etc/my.cnf.d/openstack.cnf

echo '启动数据库服务'
systemctl enable mariadb.service
systemctl start mariadb.service
sleep 5
netstat -antp|grep mysqld

echo 'mysql_secure_installation 初始化设置密码,自动交互'
#mysql_secure_installation #初始化设置密码,自动交互
[[ -f /usr/bin/expect ]] || { yum install expect -y; } #若没expect则安装
/usr/bin/expect << EOF
set timeout 30
spawn mysql_secure_installation
expect {
"enter for none" { send "\r"; exp_continue}
"Y/n" { send "Y\r" ; exp_continue}
"password:" { send "$DBPass\r"; exp_continue}
"new password:" { send "$DBPass\r"; exp_continue}
"Y/n" { send "Y\r" ; exp_continue}
eof { exit }
}
EOF

#测试
mysql -u root -p$DBPass -e "show databases;"
[ $? = 0 ] || { echo "mariadb初始化失败";exit; }

echo '创建数据库、用户授权'
mysql -u root -p$DBPass -e "
create database keystone;
grant all privileges on keystone.* to 'keystone'@'localhost' identified by 'root';
grant all privileges on keystone.* to 'keystone'@'%' identified by 'root';
create database glance;
grant all privileges on glance.* to 'glance'@'localhost' identified by 'root';
grant all privileges on glance.* to 'glance'@'%' identified by 'root';

create database nova;
grant all privileges on nova.* to 'nova'@'localhost' identified by 'root';
grant all privileges on nova.* to 'nova'@'%' identified by 'root';
create database nova_api;
grant all privileges on nova_api.* to 'nova'@'localhost' identified by 'root';
grant all privileges on nova_api.* to 'nova'@'%' identified by 'root';
create database nova_cell0;
grant all privileges on nova_cell0.* to 'nova'@'localhost' identified by 'root';
grant all privileges on nova_cell0.* to 'nova'@'%' identified by 'root';

create database neutron;
grant all privileges on neutron.* to 'neutron'@'localhost' identified by 'root';
grant all privileges on neutron.* to 'neutron'@'%' identified by 'root';

flush privileges;
select user,host from mysql.user;
show databases;
"

echo 'mariadb 配置完毕'
echo '安装rabbitmq'

yum -y install rabbitmq-server

echo '配置rabbitmq'
systemctl enable rabbitmq-server.service
systemctl start rabbitmq-server.service

rabbitmqctl add_user openstack ADMIN_PASS
rabbitmqctl set_permissions openstack "." "." ".*"

rabbitmqctl add_user admin ADMIN_PASS
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions admin "." "." ".*"

sleep 3
echo '启动web插件端口15672'
rabbitmq-plugins enable rabbitmq_management #启动web插件端口15672

echo '安装memcached'
yum -y install memcached python-memcached
cp /etc/sysconfig/memcached{,.bak}

systemctl enable memcached.service
systemctl start memcached.service
netstat -antp|grep 11211

echo '安装httpd'
yum -y install openstack-keystone httpd mod_wsgi
echo 'Keystone 配置'
cp /etc/keystone/keystone.conf{,.bak} #备份默认配置

echo "
[database]
connection = mysql+pymysql://keystone:root@controller/keystone
[token]
provider = fernet
">/etc/keystone/keystone.conf

echo '初始化身份认证服务的数据库'
su -s /bin/sh -c "keystone-manage db_sync" keystone
echo '检查表是否创建成功'
mysql -h controller -ukeystone -proot -e "use keystone;show tables;"
echo '初始化密钥存储库'
keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
keystone-manage credential_setup --keystone-user keystone --keystone-group keystone
echo '设置admin用户(管理用户)和密码'
keystone-manage bootstrap --bootstrap-password ADMIN_PASS
--bootstrap-admin-url http://controller:35357/v3/
--bootstrap-internal-url http://controller:5000/v3/
--bootstrap-public-url http://controller:5000/v3/
--bootstrap-region-id RegionOne

echo 'apache配置'
cp /etc/httpd/conf/httpd.conf{,.bak}
echo "ServerName controller">>/etc/httpd/conf/httpd.conf
ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/

echo 'Apache HTTP 启动并设置开机自启动'
systemctl enable httpd.service
systemctl restart httpd.service
sleep 3
netstat -antp|egrep ':5000|:35357|:80'

echo '创建 OpenStack 客户端环境脚本'
#admin环境脚本
touch /admin-openrc
echo "
export OS_PROJECT_DOMAIN_NAME=default
export OS_USER_DOMAIN_NAME=default
export OS_PROJECT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=ADMIN_PASS
export OS_AUTH_URL=http://controller:35357/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
">/admin-openrc

echo '测试脚本是否生效'
source /admin-openrc
openstack token issue

source /admin-openrc

echo '创建service项目,创建glance,nova,neutron用户,并授权'
openstack project create --domain default --description "Service Project" service
openstack user create --domain default --password=ADMIN_PASS glance
openstack role add --project service --user glance admin
openstack user create --domain default --password=ADMIN_PASS nova
openstack role add --project service --user nova admin
openstack user create --domain default --password=ADMIN_PASS neutron
openstack role add --project service --user neutron admin
echo '创建demo项目(普通用户密码及角色)'
openstack project create --domain default --description "Demo Project" demo
openstack user create --domain default --password=ADMIN_PASS demo
openstack role create user
openstack role add --project demo --user demo user

#------------------#####################

echo 'Glance镜像服务'
echo '安装glance'
yum -y install openstack-glance

keystone上服务注册 ,创建glance服务实体,API端点(公有、私有、admin)

source /admin-openrc || { echo "加载前面设置的admin-openrc环境变量脚本";exit; }
openstack service create --name glance --description "OpenStack Image" image
openstack endpoint create --region RegionOne image public http://controller:9292
openstack endpoint create --region RegionOne image internal http://controller:9292
openstack endpoint create --region RegionOne image admin http://controller:9292

cp /etc/glance/glance-api.conf{,.bak}
cp /etc/glance/glance-registry.conf{,.bak}

images默认/var/lib/glance/images/

#Imgdir=/date/glance
mkdir -p $Imgdir
chown glance:nobody $Imgdir
echo "镜像目录: $Imgdir"

echo "#
[database]
connection = mysql+pymysql://glance:root@controller/glance
[keystone_authtoken]
auth_uri = http://controller:5000/v3
auth_url = http://controller:35357/v3
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = glance
password = ADMIN_PASS
[paste_deploy]
flavor = keystone
[glance_store]
stores = file,http
default_store = file
filesystem_store_datadir = $Imgdir
#">/etc/glance/glance-api.conf

echo "#
[database]
connection = mysql+pymysql://glance:root@controller/glance
[keystone_authtoken]
auth_uri = http://controller:5000/v3
auth_url = http://controller:35357/v3
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = glance
password = ADMIN_PASS
[paste_deploy]
flavor = keystone
#">/etc/glance/glance-registry.conf

echo '同步数据库,检查数据库'
su -s /bin/sh -c "glance-manage db_sync" glance
mysql -h controller -u glance -proot -e "use glance;show tables;"

echo '启动服务并设置开机自启动'
systemctl enable openstack-glance-api openstack-glance-registry
systemctl start openstack-glance-api openstack-glance-registry
netstat -antp|egrep '9292|9191' #检测服务端口

source /admin-openrc

echo 'keystone上服务注册 ,创建nova用户、服务、API'

nova用户前面已建

openstack service create --name nova --description "OpenStack Compute" compute
openstack endpoint create --region RegionOne compute public http://controller:8774/v2.1
openstack endpoint create --region RegionOne compute internal http://controller:8774/v2.1
openstack endpoint create --region RegionOne compute admin http://controller:8774/v2.1
echo '创建placement用户、服务、API'
openstack user create --domain default --password=ADMIN_PASS placement
openstack role add --project service --user placement admin
openstack service create --name placement --description "Placement API" placement
openstack endpoint create --region RegionOne placement public http://controller:8778
openstack endpoint create --region RegionOne placement internal http://controller:8778
openstack endpoint create --region RegionOne placement admin http://controller:8778

mkdir -p $VHD
chown -R nova:nova $VHD

echo 'nova配置'
yum -y install openstack-nova-api openstack-nova-conductor
yum -y install openstack-nova-console openstack-nova-novncproxy
yum -y install openstack-nova-scheduler openstack-nova-placement-api
yum -y install openstack-nova-compute
echo '#
[DEFAULT]
instances_path='$VHD'
enabled_apis = osapi_compute,metadata
transport_url = rabbit://openstack:ADMIN_PASS@controller
my_ip = '$MyIP'
use_neutron = True
firewall_driver = nova.virt.firewall.NoopFirewallDriver
resume_guests_state_on_host_boot=True
compute_driver=libvirt.LibvirtDriver

[libvirt]
virt_type ='$Kvm'
[api_database]
connection = mysql+pymysql://nova:root@controller/nova_api
[database]
connection = mysql+pymysql://nova:root@controller/nova

[api]
auth_strategy = keystone
[keystone_authtoken]
auth_uri = http://controller:5000
auth_url = http://controller:35357
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = nova
password = ADMIN_PASS

[vnc]
enabled = true
vncserver_listen = $my_ip
vncserver_proxyclient_address = $my_ip
novncproxy_base_url = http://'$VncProxy':6080/vnc_auto.html

[glance]
api_servers = http://controller:9292
[oslo_concurrency]
lock_path = /var/lib/nova/tmp

[placement]
os_region_name = RegionOne
project_domain_name = Default
project_name = service
auth_type = password
user_domain_name = Default
auth_url = http://controller:35357/v3
username = placement
password = ADMIN_PASS

[scheduler]
discover_hosts_in_cells_interval = 300

#'>/etc/nova/nova.conf

echo "

#Placement API
<Directory /usr/bin>
= 2.4>
Require all granted

<IfVersion < 2.4>
Order allow,deny
Allow from all


">>/etc/httpd/conf.d/00-nova-placement-api.conf

systemctl restart httpd
sleep 5

echo '同步数据库'
su -s /bin/sh -c "nova-manage api_db sync" nova
su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova
su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova
su -s /bin/sh -c "nova-manage db sync" nova

echo '检测数据'
nova-manage cell_v2 list_cells
mysql -h controller -u nova -proot -e "use nova_api;show tables;"
mysql -h controller -u nova -proot -e "use nova;show tables;"
mysql -h controller -u nova -proot -e "use nova_cell0;show tables;"

#------------------#####################

systemctl enable openstack-nova-api.service openstack-nova-consoleauth.service
systemctl enable openstack-nova-scheduler.service
systemctl enable openstack-nova-conductor.service openstack-nova-novncproxy.service
systemctl enable libvirtd.service openstack-nova-compute.service
systemctl start openstack-nova-api.service openstack-nova-consoleauth.service
systemctl start openstack-nova-scheduler.service
systemctl start openstack-nova-conductor.service openstack-nova-novncproxy.service

systemctl start libvirtd.service openstack-nova-compute.service

echo '配置neutron'
yum -y install openstack-neutron openstack-neutron-ml2 openstack-neutron-linuxbridge ebtables
source /admin-openrc

openstack service create --name neutron --description "OpenStack Networking" network
openstack endpoint create --region RegionOne network public http://controller:9696
openstack endpoint create --region RegionOne network internal http://controller:9696
openstack endpoint create --region RegionOne network admin http://controller:9696

#Neutron 备份配置
cp /etc/neutron/neutron.conf{,.bak2}
cp /etc/neutron/plugins/ml2/ml2_conf.ini{,.bak}
ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini
cp /etc/neutron/plugins/ml2/linuxbridge_agent.ini{,.bak}
cp /etc/neutron/dhcp_agent.ini{,.bak}
cp /etc/neutron/metadata_agent.ini{,.bak}
cp /etc/neutron/l3_agent.ini{,.bak}

#echo '配置neutron'
echo '

[neutron]
url = http://controller:9696
auth_url = http://controller:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = neutron
password = ADMIN_PASS
service_metadata_proxy = true
metadata_proxy_shared_secret = METADATA_SECRET
#'>>/etc/nova/nova.conf

echo '
[DEFAULT]
nova_metadata_ip = controller
metadata_proxy_shared_secret = METADATA_SECRET
#'>/etc/neutron/metadata_agent.ini

echo '#
[ml2]
tenant_network_types = vxlan
type_drivers = vlan,flat,vxlan
mechanism_drivers = linuxbridge,l2population
extension_drivers = port_security
[ml2_type_flat]
flat_networks = provider
[ml2_type_vxlan]
vni_ranges = 1:1000
[securitygroup]
enable_ipset = True
#'>/etc/neutron/plugins/ml2/ml2_conf.ini
echo '#
[linux_bridge]
physical_interface_mappings = provider:'$Netname'
[vxlan]
enable_vxlan = True
local_ip = '$MyIP'
l2_population = True
[agent]
prevent_arp_spoofing = True
[securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
enable_security_group = True
#'>/etc/neutron/plugins/ml2/linuxbridge_agent.ini

echo '#
[DEFAULT]
interface_driver = linuxbridge
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
enable_isolated_metadata = true
#'>/etc/neutron/dhcp_agent.ini

echo '
[DEFAULT]
core_plugin = ml2
service_plugins = router
allow_overlapping_ips = True
transport_url = rabbit://openstack:ADMIN_PASS@controller
auth_strategy = keystone
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true

[keystone_authtoken]
auth_uri = http://controller:5000
auth_url = http://controller:35357
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = ADMIN_PASS

[nova]
auth_url = http://controller:35357
auth_type = password
project_domain_id = default
user_domain_id = default
region_name = RegionOne
project_name = service
username = nova
password = ADMIN_PASS

[database]
connection = mysql://neutron:root@controller/neutron

[oslo_concurrency]
lock_path = /var/lib/neutron/tmp
#'>/etc/neutron/neutron.conf

echo '
[DEFAULT]
interface_driver = linuxbridge
#'>/etc/neutron/l3_agent.ini
#创建网络服务初始化脚本超链接
ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini
#同步数据库
su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf
--config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron
#检测数据
mysql -h controller -u neutron -proot -e "use neutron;show tables;"

#------------------#####################

#dashboard

echo '配置openstack Dashboard'
yum -y install openstack-dashboard
cp /etc/openstack-dashboard/local_settings{,.bak}
Setfiles=/etc/openstack-dashboard/local_settings
sed -i 's#member#user#g' $Setfiles
sed -i 's#OPENSTACK_HOST = "127.0.0.1"#OPENSTACK_HOST = "controller"#' $Setfiles
##允许所有主机访问#
sed -i "/ALLOWED_HOSTS/cALLOWED_HOSTS = ['', ]" $Setfiles
#去掉memcached注释#
sed -in '153,158s/#//' $Setfiles
sed -in '160,164s/.
/#&/' $Setfiles
sed -i 's#UTC#Asia/Shanghai#g' $Setfiles
sed -i 's#%s:5000/v2.0#%s:5000/v3#' $Setfiles
sed -i '/ULTIDOMAIN_SUPPORT/cOPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True' $Setfiles
sed -i "s@^#OPENSTACK_KEYSTONE_DEFAULT@OPENSTACK_KEYSTONE_DEFAULT@" $Setfiles
echo '
#set
OPENSTACK_API_VERSIONS = {
"identity": 3,
"image": 2,
"volume": 2,
}
#'>>$Setfiles
systemctl restart httpd
sleep 5

##########################################

echo '启动服务'
#Apache
systemctl enable httpd.service
#systemctl restart httpd haproxy
#netstat -antp|egrep 'httpd'

echo 'glance服务'
systemctl enable openstack-glance-api openstack-glance-registry
systemctl restart openstack-glance-api openstack-glance-registry

echo 'nova服务'
systemctl enable openstack-nova-api.service
openstack-nova-consoleauth.service openstack-nova-scheduler.service
openstack-nova-conductor.service openstack-nova-novncproxy.service
libvirtd.service openstack-nova-compute.service
echo '启动nova'
systemctl start openstack-nova-api.service
openstack-nova-consoleauth.service openstack-nova-scheduler.service
openstack-nova-conductor.service openstack-nova-novncproxy.service
libvirtd.service openstack-nova-compute.service

#neutron服务
systemctl enable neutron-server.service
neutron-linuxbridge-agent.service neutron-dhcp-agent.service
neutron-metadata-agent.service neutron-l3-agent.service
systemctl start neutron-server.service
neutron-linuxbridge-agent.service neutron-dhcp-agent.service
neutron-metadata-agent.service neutron-l3-agent.service
openstack network agent list
openstack compute service list
openstack catalog list
echo '安装完毕'

用这个脚本安装之后出现的问题:

image
发现是nova.conf问题
启动实例报错:
image
在nova.conf中加一行

[libvirt]
virt_type =qemu

解决问题

openstack 虚拟化可分为两种类型

1.型
Hypervisor 直接安装在物理机上,多个虚拟机在 Hypervisor 上运行。Hypervisor 实现方式一般是一个特殊定制的 Linux 系统。Xen 和 VMWare 的 ESXi 都属于这个类型。

2.型
物理机上首先安装常规的操作系统,比如 Redhat、Ubuntu 和 Windows。Hypervisor 作为 OS 上的一个程序模块运行,并对管理虚拟机进行管理。KVM、VirtualBox 和 VMWare Workstation 都属于这个类型。

Openstack Restful api: Paste+PasteDepoly+Routes+webob

一.Paste和PasteDeploy
使用Paste和PasteDeploy模块来实现 WSGI Services 时,都需要加载一个 paste.ini 文件。这个文件也是 Paste 模块的精髓
Paste.ini文件:
paste.ini 文件的格式类似于INI格式,每个 Section 的格式均[type:name]。
Composite:这种Section用于将HTTP URL Request分发到指定的Application
例:[composite:metadata]
use = egg:Paste#urlmap
use 是一个关键字,指定处理请求的代码,表明了具体处理请求的分发方式。
egg:Paste#urlmap 表示使用 Paste 包中的 urlmap 模块来分发请求。
#/v2.0 /v3 / , 是 urlmap 进行分发时,需要使用到的参数。
[composite:main]
use = egg:Paste#urlmap
/v2.0 = public_api # /v2.0 开头的请求会路由给 public_api 处理
/v3 = api_v3 # /v3 开头的请求会路由给 api_v3 处理
/ = public_version_api # / 开头的请求会路由给 public_version_api 处理# public_api/api_v3/public_version_api 这些路由的对象就是 paste.ini 中的其他 Secion Name,而且Section Type 必须是 app 或者 pipeline。

pipeline : 用来把一系列的 filter 过滤器和 app 串起来。

pipeline 关键字指定了很多个名字,这些名字也是 paste.ini 文件中其他的 section Name。

HTTP Request 从 Sectin composite 被转发到 Section pipeline 之后,该请求会从第一个的 section 开始处理,一直向后传递直到结束。

pipeline 指定的 section 有如下要求:

1. 最后一个名字对应的 section 一定要是一个 app 类型的 Section。

2. 非最后一个名字对应的 section 一定要是一个 filter 类型的 Section。

filter: 实现一个过滤器中间件。
filter(以WSGI中间件的方式实现)是用来过滤请求和响应的,应该不同的中间件的过滤,该请求就具有了不同的功能。

app: 一个 app 就是一个实现主要功能的具体的 WSGI Application 。

paste.ini 配置文件中这一大堆配置的作用就是把我们用 Python 写的 WSGI Application 和 Middleware 串起来,规定好 HTTP Request 处理的路径。
当 Paste + PasteDeploy 模块提供的 WSGI Server(Web Server) 接受到 URL_Path 形式的 HTTP Request 时,这些 Request 首先会被 Paste 按照配置文件 paste.ini 进行处理,处理的过程为:composite(将Request转发到pipeline或app) ==> pipeline(包含了filter和app) ==> filter(调用Middleware对Request进行过滤) ==> app(具体的Application来实现Request的操作) 。这个过程就是将 Application 和 Middleware 串起来的过程 。

举个例子:
一般情况下,如果希望从 Keystone service 获取一个 token 时,会使到 http://hostname:35357/v3/auth/tokens 这个 API。
我们根据 Keystone 的 paste.ini 配置文件来说明这个 API 是如何被处理的:

Step1. (hostname:35357): 这一部分是由 Apache Web Server 来获取并处理的。然后,请求会被 Web Server 转到 WSGI Application 的入口,也就是 keystone/httpd/keystone.py 中的 application 对象取处理。

Step2. (/v3/auth/tokens): application 对象根据 paste.ini 中的配置来对剩下的(/v3/auth/tokens)部分进行处理。首先请求的 Post=35357 决定了会经过 [composite:admin] section 。(一般是admin监听35357端口,main监听5000端口,也会受到 name 变量的影响)

Step3. (/v3): 决定将请求路由到哪一个 pipeline secion,[composite:admin] 发现请求的 URL_Path 是 /v3 开头的,于是就把请求转发给[pipeline:api_v3]处理,转发之前,会把 /v3 这个部分去掉。
Step4. (/auth/tokens) : [pipeline:api_v3]收到请求,URL_Path是 (/auth/tokens),然后开始调用各个 filter(中间件) 来处理请求。最后会把请求交给[app:service_v3]进行处理。
Step5. (/auth/tokens): [app:service_v3] 收到请求,URL_Path是 (/auth/tokens),最后交由的 WSGI Application 去处理。
到此为止,paste.ini 中的配置的所有工作都已经做完了。下面请求就要转移到最终的 Application 内部去处理了

二. Routes
对于URL_Path是以 /v3 开头的请求,在 paste.ini 中会被路由到 [app:service_v3] 这个 app section,并且交给 keystone.service:v3_app_factory 这个函数生成的 application 处理。最后这个 application 需要根据 URL_Path 中剩下的部分(/auth/tokens),来实现 URL 路由。这需要使用 Routes 模块。
Routes Module:是用 Python 实现的类似 Rails 的 URL 路由系统,它的主要功能就是把接收到的 URL_Path 映射到对应的操作。Routes 的一般用法是创建一个 Mapper 对象,然后调用该 Mapper 对象的 connect() 方法把 URL_Path 和 HTTP 内建方法映射到一个 Controller 的某个 Action 上。
这里 Controller 是一个自定义的类实例,每一个资源都对应一个 Controller,是对资源操作方法的集合。Action 表示 Controller 对象提供的操作方法(EG. index/show/delect/update/create )。一般调用这些 Action 的时候会把这个 Action 映射到 HTTP 的内置方法中去。EG. GET/POST/DELETE/PUT 。
总结:URL_Path(/auth/tokens) 和 HTTP 内建的方法,在 Routes Module 中被 Mapper 对象的 connect 方法映射到某一个 Controller 的 Action 操作函数中。实现了调用 URL_Path 即调用 Action 操作函数的效果,而且因为 HTTP 的内建方法也被映射在其中,所以可以很容易的使用 HTTP 协议来实现操作。
三.WebOb
WebOb 有两个重要的对象:
一个是 Webob.Request,对 WSGI Request 的 environ 参数进行封装。
一个是 webob.Response ,包含了标准 WSGI Response 的所有元素。
此外,还有一个 webob.exc,针对 HTTP 错误代码进行封装。
除了这三种对象,WebOb还提供了一个装饰器webob.dec.wsgify,以便我们可以不使用原始的 WSGI 参数传递和返回格式,而全部使用 WebOb 替代。
四. RPC的机制
def init(self):
super(SchedulerAPI, self).init()
target = messaging.Target(topic=RPC_TOPIC, version='4.0')
version_cap = self.VERSION_ALIASES.get(CONF.upgrade_levels.scheduler,
CONF.upgrade_levels.scheduler)
serializer = objects_base.NovaObjectSerializer()
self.client = rpc.get_client(target, version_cap=version_cap,
serializer=serializer)
cctxt = self.client.prepare(version=version)
return cctxt.call(ctxt, 'select_destinations', **msg_args)
Service对象
Service位于nova.service.py
该对象继承于nova.openstack.common.service.py中的Service

__init__方法
初始化几个重要的成员
        self.host = host
        self.binary = binary
        self.topic = topic
        self.manager_class_name = manager

参数有启动命令提供。host如果没有传入,从配置文件读取。host = CONF.host
start方法:
该方法用来启动rpc server。
该方法的主要功能就是创建RPC队列并绑定到exchang上

target = messaging.Target(topic=self.topic, server=self.host)

endpoints = [
self.manager,
baserpc.BaseRPCAPI(self.manager.service_name, self.backdoor_port)
]
RPC服务其实就是一个RPC server,client(客户)可以通过RPC API进行调用。以nova为例,nova中的多数服务(service)都是一个RPC server。比如nova-conductor,nova-compute,nova-consoleauth,nova-scheduler...等

实现一个rpc server需要几个部分:
1)启动命令代码
2)Service定义
3)Manager定义
4)功能实现代码
其中1)2)3)属于框架性代码,每个rpc server的实现都差不多;4)和rpc server要实现的功能相关。

以nova为例,来分析这些部分的实现。
nova.cmd package中定义了所有服务的启动代码,包括rpc server和rest api服务。api.py,api_ec2.py,api_metadata.py,api_os_compute.py是rest api服务。这个目录中还包含了一些命令工具(utility command),如manage.py。读者可自行查看。

rpc server的启动代码基本类似:
1)定义main
2) 加载配置文件
3) 配置log
4) 创建server对象
5)启动service.

步骤4的代码compute:
    server = service.Service.create(binary='nova-compute',
                                    topic=CONF.compute_topic,
                                    db_allowed=CONF.conductor.use_local)
步骤4的代码schduler:
    server = service.Service.create(binary='nova-scheduler',
                                    topic=CONF.scheduler_topic)
步骤4的代码conductor:
    server = service.Service.create(binary='nova-conductor',
                                    topic=CONF.conductor.topic,
                                    manager=CONF.conductor.manager)
步骤5的代码,3者一致
    service.serve(server)
    service.wait()

Service对象
Service位于nova.service.py
该对象继承于nova.openstack.common.service.py中的Service

__init__方法
初始化几个重要的成员
        self.host = host
        self.binary = binary
        self.topic = topic
        self.manager_class_name = manager

参数有启动命令提供。host如果没有传入,从配置文件读取。host = CONF.host

start方法:
该方法用来启动rpc server。
该方法的主要功能就是创建RPC队列并绑定到exchang上。
        target = messaging.Target(topic=self.topic, server=self.host)
        endpoints = [
            self.manager,
            baserpc.BaseRPCAPI(self.manager.service_name, self.backdoor_port)
        ]
        endpoints.extend(self.manager.additional_endpoints)

target用来指定该rpc server监听在哪些队列上。
target指定了2个参数:topic和server。查看target代码(olso.messaging: oslo.messaging.target.py)
    :param server: Clients can request that a message be directed to a specific
      server, rather than just one of a pool of servers listening on the topic.
    :param topic: A name which identifies the set of interfaces exposed by a
      server. Multiple servers may listen on a topic and messages will be
      dispatched to one of the servers in a round-robin fashion.

底层如何使用target创建RPC队列并绑定到exchang上,可以查看代码
transport._listen
  self._driver.listen(target)
amqpdriver.listen
  conn.declare_topic_consumer(target.topic, listener)
  conn.declare_topic_consumer('%s.%s' % (target.topic, target.server),
                                    listener)
  conn.declare_fanout_consumer(target.topic, listener)
从代码中可以看到创建了3个队列,这个3个系列用来实现《openstack学习之RPC》提到的3种RPC场景
随机调用某server上的一个方法: 通过第一个队列实现
调用某特定server上的一个方法: 通过第二个队列实现,这个队列通过server参数来唯一标识一个队列
调用所有server上的一个方法:通过第三个队列实现,exchange type为fantout类型
关于队列的概念可以参考另一篇博文《openstack学习之RPC》

endpoints用来定义该rpc server支持哪些API。
manager中部分方法其实就是RPC API的方法,比如ComputeManager中有reboot_instance,这个方法就是一个RPC API。

client调用RCP API时会给出topic,方法名,方法参数等信息。oslo.messaging中的RPCDispatch会根据这些信息将该请求直接转化为对manager的相应方法的调用,并将方法参数准备好。

还可以看到openstack会给每个rpc server加一个额外的API(BaseRPCAPI),这个API目前只有一个ping方法。openstack内部会用这个方法检测一个服务是否已经启动完毕,如果启动完毕,就可以相应ping调用。

Service对象还提供了另外一个功能,定时任务。
            self.tg.add_dynamic_timer(self.periodic_tasks,
                                     initial_delay=initial_delay,
                                     periodic_interval_max=
                                        self.periodic_interval_max)
self.periodic_tasks会调用manager.periodic_tasks。

综上,Service对象的核心功能就是创建监听队列,并将收到的消息转化为对manager对象的方法调用。每个openstack项目实现都有定义一个自己的Service对象(如nova.service.py,cinder.service.py,neutron.service.py),这些对象的代码基本类似,相信后边社区会对这些代码进行重构。

Manager对象
如前所述,Manager对象其实就是RPC API的入口。每个RPC API最终会转化为对Manger相应方法的调用,这个方法就是该RPC API的最终实现。
每个服务都会有一个相应的Manager对象,因为一般每个服务所提供的API都是不同的。每个服务的实现都会有一个相应的python package(文件系统中的目录),如conductor,compute,consoleauth,scheduler等。每个package中又会有一个manager.py。这个manager.py就定义了这个服务的Manager对象。如compute.manager.py定义了ComputeManager。nova boot命令最终会调用这个对象中的run_instance方法。
要想进一步看懂Manager中的代码,就需要对相应问题领域(problem domain,也就是我们常说的业务流程)比较熟悉了。ComputeManager是处理虚拟机生命周期的,我们要对虚拟机有了解,才能读懂其中的代码。

掌握了Service + Manager,基本上就了解了RPC server是如何工作的,学习openstack代码就比较直观了。

openstack 字符问题

问题描述
ERROR nova.compute.manager [instance: b437936f-1758-4ad9-b4a5-a7f70d41f279] UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)

解决办法:

/usr/lib/python2.7/site-packages/nova/compute/manager.py,开头地方加入

import sys

default_encoding = 'utf-8'

if sys.getdefaultencoding() != default_encoding:

    reload(sys)

    sys.setdefaultencoding(default_encoding) 

rabbitmq消息队列

openstack 源码中以xxx_rpcapi.yyy()命名的对象的意思是
向 xxx的消息队列发送执行yyy操作的命令

linux 常用网络工具

traceroute

ping命令用于探测两个主机间连通性以及响应速度,而traceroute会统计到目标主机的每一跳的网络状态(print the route packets trace to network host),这个命令常常用于判断网络故障,比如本地不通,可使用该命令探测出是哪个路由出问题
traceroute www.baidu.com

traceroute to www.baidu.com (180.97.33.108), 30 hops max, 60 byte packets
 1  192.168.100.254 (192.168.100.254)  3.430 ms  3.677 ms  3.948 ms
 2  192.168.100.253 (192.168.100.253)  0.707 ms  0.745 ms  0.802 ms
 3  10.101.50.1 (10.101.50.1)  5.244 ms  5.439 ms  5.428 ms
 4  10.50.0.33 (10.50.0.33)  5.513 ms  5.612 ms  6.465 ms
 5  10.50.0.245 (10.50.0.245)  5.637 ms  6.904 ms  7.126 ms
 6  221.226.9.49 (221.226.9.49)  9.957 ms  10.523 ms  10.466 ms
 7  222.190.3.137 (222.190.3.137)  10.431 ms  4.342 ms  4.935 ms
 8  * * *
 9  202.102.73.94 (202.102.73.94)  5.104 ms  5.100 ms  5.519 ms

brctl

brctl是linux网桥管理工具,可用于查看网桥、创建网桥、把网卡加入网桥等。

brctl show

mtr

mtr是常用的网络诊断工具(a network diagnostic tool),它把ping和traceroute并入一个程序的网络诊断工具中并实时刷新。
image

iptables

iptables是强大的包过滤工具,Docker、Neutron都网络配置都离不开iptables。iptables通过一系列规则来实现数据包过滤、处理,能够实现防火墙、NAT等功能。当一个网络数据包进入到主机之前,先经过Netfilter检查,即iptables规则,检查通过则接受(Accept)进入本机资源,否则丢弃该包(Drop)。规则是有顺序的,如果匹配第一个规则,则执行该规则的Action,不会执行后续的规则。iptables的规则有多个表构成,每个表又由链(chain)构成,每个表的功能不一样,本文只涉及两个简单的表,即Filter表和NAT表,望文生义即可了解,Filter表用于包过滤,而NAT表用来进行源地址和目的地址的IP或者端口转换。

pike安装中的问题

Openstack 使用遇到的问题

1.glance-api无法启动问题 1
2.最大连接数问题 1
3.安装fwass的问题(防火墙) 2
4. Nova-compute无法启动报错 4
5. 更换nova,glance存储路径的方法: 5
6. 官网ZUN的安装问题 5
7. 将fwaas加到openstack-dashboard配置 5
8. container(zun-ui)dashboard配置 6
9. 关于docker 6
10. Openstack 性能测试工具rally(依赖heat) 8
11.openstack功能测试工具tempest 10
12. 将openstack中对虚拟机的连接从VNC改为spice 11

查看某个服务启动错误日志:
journalctl -u openstack-nova-compute.service|grep -i error

1.glance-api无法启动问题

Journalctl -xe|grep xxx查看启动日志

ERROR: Unable to locate paste config file for glance-registry
解决办法:
· vim /etc/glance/glance-registry.conf‘ 在[paste_deploy]下面加上
config_file=/usr/share/glance/glance-registry-dist-paste.ini

2.最大连接数问题
OperationalError: (pymysql.err.OperationalError) (1040, u'Too many connections')
原因:openstack服务连接数超出mysql的max_connections(在my.cnf的[mysqld]里面)
解决方法:
Nova,glance,neutron等服务每个请求默认所占连接数为其CPU内核数,CPU的核数越多每个请求所占的连接数就越多
更改各个组件的配置文件里的worker属性值,可以设为3(默认worker的是CPU核数,如果是40核,默认worker数为40),
Nova的 api-paste.ini nova.conf
Glance的glance-api.conf ,glance-registry.conf,glance-cache.conf
Neutron的metadata_agent.ini plugin.ini
dhcp_agent.ini l3_agent.ini neutron.conf
然后更改数据库配置:
mariab修改最大连接数永久生效:
    编辑/usr/lib/systemd/system/mariadb.service,在[Service]项最后加上以下两行:
    LimitNOFILE=65535
    LimitNPROC=65535
   编辑/etc/my.cnf和/etc/my.cnf.d/mariadb-server.cnf,在[mysqld]项最后加上下面一行:
    max_connections=1024
   编辑/etc/my.cnf和/etc/my.cnf.d/openstack.cnf,在[mysqld]项最后加上下面一行:
    max_connections=1024
    重启服务
     systemctl daemon-reload
     service mariadb restart
    查看支持最大连接数:
    MariaDB [(none)]> show variables like "max_connections";
文件句柄数改为最大65535永久生效
    编辑文件vim /etc/security/limits.conf,在最末加上:
    * soft nofile 65535
    * hard nofile 65535
    保存退出,reboot后ulimit -n查看是否生效
修改连接释放机制,防止timewait数过多:
    编辑文件vim /etc/sysctl.conf,在最末加上:
   net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_fin_timeout = 30
保存退出,执行sysctl -p

3.安装fwass的问题(防火墙)
fwaas_v2安装相关
安装的防火墙是fwaas v2版本的
官网上的教程为
Enable the FWaaS plug-in in the /etc/neutron/neutron.conf file:
service_plugins = firewall_v2[service_providers]...service_provider = FIREWALL:Iptables:neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver:default
[fwaas]driver = neutron_fwaas.services.firewall.drivers.linux.iptables_fwaas_v2.IptablesFwaasDriverenabled = True
 
Note
On Ubuntu, modify the [fwaas] section in the /etc/neutron/fwaas_driver.ini file instead of /etc/neutron/neutron.conf.
· Configure the FWaaS plugin for the L3 agent.
· In the AGENT section of l3_agent.ini, make sure the FWaaS extension is loaded:
· [AGENT]
extensions = fwaas_v2
· Edit the FWaaS section in the /etc/neutron/neutron.conf file to indicate the agent version and driver:
· [fwaas]agent_version = v2
driver = iptables_v2
enabled = True
· · Create the required tables in the database:
· # neutron-db-manage --subproject neutron-fwaas upgrade head
不准确,正确配置为
Fwaas
A 安装fwaas
yum -y install openstack-neutron-fwaas

B 添加fwaas服务
vi /etc/neutron/neutron.conf
service_plugins = router,firewall_v2
再加上
[service_providers]...这块原文件中没有
service_provider = FIREWALL:Iptables:neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver:default

C 配置fwaas
vi /etc/neutron/fwaas_driver.ini
driver = neutron_fwaas.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver
enabled = True

D dashboard启用fwaas
vi /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.py
OPENSTACK_NEUTRON_NETWORK = {
    ...
    'enable_firewall' = True,
    ...
}

systemctl restart httpd

E 数据库建表
neutron-db-manage --subproject neutron-fwaas upgrade head

F 重启服务
Systemctl restart neutron-server.service
Systemctl restart neutron-l3-agent.service

4. Nova-compute无法启动报错
在更改nova和glance存储路径之后,glance正常启动但是nova-compute无法正常启动,报错 ERROR nova.virt.driver [req-5fc6908a-9b3f-478e-9a0e-c073e7690697 - - - - -] Compute driver option required, but not specified
然后将/etc/nova/nova.conf中# compute_driver设置为
compute_driver=libvirt.LibvirtDriver重新启动之后报错
10:40:19 controller nova-compute[1953]: 2018-02-08 10:40:19.727 1953 ERROR nova self.volume_drivers = self._get_volume_drivers()
2月 08 10:40:19 controller nova-compute[1953]: 2018-02-08 10:40:19.727 1953 ERROR nova File "/usr/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 391, in _get_volume_drivers
2月 08 10:40:19 controller nova-compute[1953]: 2018-02-08 10:40:19.727 1953 ERROR nova driver_registry[driver_type] = driver_class(self._host)
2月 08 10:40:19 controller nova-compute[1953]: 2018-02-08 10:40:19.727 1953 ERROR nova File "/usr/lib/python2.7/site-packages/nova/virt/libvirt/volume/drbd.py", line 29, in init
2月 08 10:40:19 controller nova-compute[1953]: 2018-02-08 10:40:19.727 1953 ERROR nova connector.DRBD, utils.get_root_helper())
2月 08 10:40:19 controller nova-compute[1953]: 2018-02-08 10:40:19.727 1953 ERROR nova AttributeError: 'module' object has no attribute 'DRBD'
推断问题和DRDB有关,最后看nova源码,将/usr/lib/python2.7/site-packages/nova/virt/libvirt/driver.py 中libvirt_volume_drivers下的'drbd=nova.virt.libvirt.volume.drbd.LibvirtDRBDVolumeDriver',
注释掉,重新编译,重启libvirt,然后重启nova-compute成功

5. 更换nova,glance存储路径的方法:
NOVA 更改etc/nova/nova.conf的state_path的路径(默认为/var/lib/nova),注意该路径文件夹的权限和所有权要和默认路径一样,改完重启nova各服务
GLANCE 更改/etc/glance/glance-api.conf中
filesystem_store_datadir = 路径(默认为/var/lib/glance/images),注意该路径文件夹的权限和所有权要和默认路径一样,改完重启glance各服务

6. 官网ZUN的安装问题
[Service]
ExecStart = /usr/local/bin/zun-compute
里面所有/usr/local/bin的地方都要改为/usr/bin
新建容器:### 从镜像创建容器
zun run --name ubuntu-web --net network=df94a80d-62a9-4551-ae6b-8d0af3f44fc2 ubuntu-webbb tail -f /etc/hosts(后面需要加一个命令否则可能会自动关闭)
查看所有启动的容器 zun list
查看所有的docker镜像 zun image-list
连接容器:zun exec --interactive 容器名 /bin/sh
停止容器 zun stop 容器名
删除 zun delete
注意:docker的镜像和openstack的镜像不一样,中间需要转换
Docker 下载镜像
Docker pull 镜像名

7. 将fwaas加到openstack-dashboard配置
官网教程不准确
装完之后要注意neutron_fwaas_dashboard的版本,版本过高对导致新建防火墙报错(更换版本直接替换/usr/lib/python2/site-packages/neutron_fwaas_dashboard和neutron_fwaas_dashboard-xxx版本这两个文件就行)
具体正确步骤
$ git clone https://git.openstack.org/openstack/neutron-fwaas-dashboard
$ cd neutron-fwaas-dashboard
$ sudo pip install .
$ cp neutron_fwaas_dashboard/enabled/70*.py /usr/share/openstack-dashboard/openstack_dashboard/local/enabled
将neutron-fwaas-dashboard/etc/neutron-fwaas-policy.json拷贝到/etc/openstack-dashboard
Cp neutron-fwaas-dashboard/etc/neutron-fwaas-policy.json /etc/openstack-dashboard
改/usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.py文件,在
OPENSTACK_NEUTRON_NETWORK = {
加上
'enable_firewall': True,
8. container(zun-ui)dashboard配置--选pike分支
***
Yum install zun-ui安装zun-ui(git clone -b stable/pike https://github.com/openstack/zun-ui.git
cd zun-ui
pip install -r requirement.txt
python setup.py install
)
找到zun-ui的安装路径/usr/lib/python2.7/site-packages/zun_ui
将/usr/lib/python2.7/site-packages/zun_ui/enabled下的
_1330_project_container_panelgroup.py
_1331_project_container_containers_panel.py
_2330_admin_container_panelgroup.py
_2331_admin_container_images_panel.py
拷贝到/usr/share/openstack-dashboard/openstack_dashboard/enabled/目录下,然后重启httpd
Service httpd restart
在装zunclient时,要指定客户端的版本
pip install python-zunclient==1.1.0

9. 关于docker
Docker中最重要的三个概念就是:镜像、容器、库。
镜像:是一个包含了应用程序和其运行时依赖环境的只读文件。
容器:它是构建容器的模板,通过一个镜像我们可以构造出很多相互独立但运行环境一样的容器。
库:Docker提供了Hub来保存公有或私有的镜像,也允许第三方搭建。

docker search centos #搜索容器

docker pull centos #下载容器

docker images #查看当前存在的镜像

docker run centos /bin/echo 'hello world' #运行一条命令后直接退出

docker run --name mydocker -it centos /bin/bash #进入docker容器

-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,
-i 则让容器的标准输入保持打开。
–name 使用一个自定义的名字

docker run -d --name mynginx nginx #启动nginx镜像,没有会自动pull

docker stop bfd094233f96 #停止一个容器,根据容器 id 进行删除

docker rm bfd094233f96 #删除一个容器

docker attach d20f3dc6cd92 #进入一个正在运行的容器

此命令不太好用,建议使用以下命令进入容器:

[root@localhost docker]# docker inspect --format "{{.State.Pid}}" mynginx #获取容器pid
19769
[root@localhost docker]# nsenter --target 19769 --mount --uts --ipc --net --pid #进入容器(推荐方法)

docker run -d -p 91:80 --name mynginx2 nginx # -p 指定端口映射,将80映射为host的91

存储镜像:

docker save -o ubuntu_14.04.tar ubuntu:14.04

载入镜像:

docker load < ubuntu_14.04.tar 或者使用

cat ubuntu.tar | docker import - test/ubuntu:v1.0

移除本地镜像:

docker rmi training/sinatra

清理所有未打过标签的本地镜像:

docker rmi $(docker images -q -f "dangling=true")

其中 -q 和 -f 是 quiet,–filter 的缩写, 完整的命令其实可以写着下面这样,是不是更容易理解一点?

docker rmi $(docker images --quiet --filter "dangling=true")

注: 容器是否会长久运行,是和docker run指定的命令有关,和 -d 参数无关。
要获取容器的输出信息,可以通过 docker logs 命令。

docker logs [container ID or NAMES]

删除容器:

docker rm 默认并不会删除运行中的容器

有关容器和镜像的底层信息:

docker inspect container/image

docker run -d -it -p 8009:8000 django /bin/bash
docker run - 运行一个容器 -d - 后台运行 -t - 分配一个(伪)tty (link is external) -i - 交互模式 (so we can interact with it) -p - 端口映射 django - 使用django镜像 /bin/bash - 运行命令 bash shell
查看docker日志 docker logs -f dockerID

Docker是用GO写的

10. Openstack 性能测试工具rally(依赖heat)
安装方法 http://blog.csdn.net/jiahaojie1984/article/details/52043274
执行测试单元rally  task start 测试的文件(里面是操作)
rally task start create-and-delete-user.json

Rally task list 查看所有任务
rally task abort taskID 停止测试
将测试结果导出到html
rally task report taskID --out=report.html

查看web报告问题错误排查:
在查看测试报告文件时,遇到了一个奇怪的现象,我发现在公司电脑上面打不开report.html文件,但是在另外一个同事Mac电脑上面却可以正常打开。后来我在家里用个人电脑上查看report.html文件,发现当打开翻墙功能就可以查看,但是关闭翻墙功能就不能正常查看。于是查看html源代码,发现report.html文件中使用了一些css、js库,而这些库放在了google网站上,因此才会出现这么奇怪的现象。
需要将report.html里面如下四行中的libs网址:
  <link rel="stylesheet"href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.15-beta/nv.d3.min.css">
  <script type="text/javascript"src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
  <script type="text/javascript"src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3.min.js"></script>
  <script type="text/javascript"src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.15-beta/nv.d3.min.js"></script>
替换为可以访问的bootcss静态库的libs网址,如下:
  <link rel="stylesheet"href="http://cdn.bootcss.com/nvd3/1.1.15-beta/nv.d3.css">
  <script type="text/javascript"src="http://cdn.bootcss.com/angular.js/1.3.3/angular.min.js"></script>
  <script type="text/javascript"src="http://cdn.bootcss.com/d3/3.4.13/d3.min.js"></script>
  <script type="text/javascript"src="http://cdn.bootcss.com/nvd3/1.1.15-beta/nv.d3.min.js"></script>
之后就可以打开了。或者直接将report.html模板文件的对应行修改掉,这样生成的报告web页面都会自动替换。
模板文件位置:/usr/lib/python2.7/site-packages/rally/ui/templates/task/report.html

11.openstack功能测试工具tempest
教程http://blog.csdn.net/liujiong63/article/details/70037598
Tempest.conf配置文件模板

https://github.com/SUSE-Cloud/qa-openstack-tempest/blob/master/tempest.conf.sample

12. 将openstack中对虚拟机的连接从VNC改为spice
教程
https://github.com/bspeng922/notes/blob/master/config_openstack_to_use_spice.md
具体步骤:

  1. 下载spice
  2. 改/etc/nova/nova.conf配置,disable vnc ,enable spice,对spice进行设置
  3. 关VNC,disable VNCservice ,启spice, enable spice ,重启nova相关服务和httpd
    使用spice
    Controller
    wget http://dl.fedoraproject.org/pub/epel/7/x86_64/s/spice-html5-0.1.7-1.el7.noarch.rpm
    rpm -ivh spice-html5-0.1.7-1.el7.noarch.rpm

yum install spice-server spice-protocol openstack-nova-spicehtml5proxy -y

vim /etc/nova/nova.conf
[default]
vnc_enabled=false
[spice]
html5proxy_host=10.10.52.31
html5proxy_port=6082
keymap=en-us

systemctl stop openstack-nova-novncproxy.service
systemctl disable openstack-nova-novncproxy.service

systemctl enable openstack-nova-spicehtml5proxy.service
systemctl start openstack-nova-spicehtml5proxy.service

systemctl restart httpd.service
Compute
wget http://dl.fedoraproject.org/pub/epel/7/x86_64/s/spice-html5-0.1.7-1.el7.noarch.rpm
rpm -ivh spice-html5-0.1.7-1.el7.noarch.rpm

yum install spice-server spice-protocol

vim /etc/nova/nova.conf
[default]
vnc_enabled=false
[spice]
html5proxy_base_url=http://10.10.52.31:6082/spice_auto.html
server_listen=0.0.0.0
server_proxyclient_address=10.10.52.32 <当前compute节点IP>
enabled=true
keymap=en-us

systemctl restart openstack-nova-compute.service
安装完成后,需要硬重启虚拟机才能正常使用spice协议
[root@controller ~]# nova get-spice-console 123123 spice-html5
+-------------+------------------------------------------------------------------------------------+
| Type | Url |
+-------------+------------------------------------------------------------------------------------+
| spice-html5 | http://10.10.52.31:6082/spice_auto.html?token=17671c6b-fcaf-484f-8311-a128d6428c8a |
+-------------+------------------------------------------------------------------------------------+
Newton 版本需要修改horizon 的local_setting 配置文件,否则页面上还会引用vnc路径,控制台页面提示控制节点“拒绝了我们的连接请求”。
需要将
CONSOLE_TYPE = "AUTO"
改为
CONSOLE_TYPE = "SPICE"

vnc 地址需要配置为IP地址,配置为controller,页面上会提示无法连接
13 tacker组件
组件的依赖
https://docs.openstack.org/keystone/latest/install/index.html
https://docs.openstack.org/mistral/latest/install/index.html
https://docs.openstack.org/barbican/latest/install/install.html
https://docs.openstack.org/horizon/latest/install/index.html

14 zun zun-ui版本和pike版本不一致问题
按照官网教程,在安装zun和zun ui时,官网提供的链接默认为maste分支的代码而不是pike的版本,直接下载下来会导致zun和openstack不兼容,所以要切换到pike分支,再下载
git clone -b stable/pike https://github.com/openstack/zun.git pike_zun
切换分支的方法 git clone -b stable/pike https://github.com/openstack/zun.git pike_zun
说明: -b代表brunch 后面跟你要下载的分支名
15 dashboard安装之后 无法访问dashboard
Apache Error: No matching DirectoryIndex (index.html) found
解决办法:编辑:/etc/httpd/conf.d/openstack-dashboard.conf
在WSGISocketPrefix run/wsgi下面加一行代码:
WSGIApplicationGroup %{GLOBAL}

16。用spice客户端取代vnc
其中spice-html5无法正常安装,要先装epel (yum -y install epel-release)
输入命令yum repolist刷新,然后就可以装spice-html5了

dashboard 开发环境搭建

参考网址
官网地址
方法一
1.取得源代码:
git clone https://github.com/openstack/horizon.git

2.create a virtual environment:
python tools/install_venv.py 时间很长
3. 进入虚拟环境
source .venv/bin/activate(source /home/sf/horizon/.venv/bin/activate)
4.启动server
tools/with_venv.sh ./manage.py runserver 0.0.0.0:8080 (python manage.py runserver 127.0.0.1:8080)
5.注意要改local_settings.py的配置

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
CACHES = {
   'default': {
       'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
       'LOCATION': 'controller:11211',
   },
}
OPENSTACK_HOST = "controller"
OPENSTACK_KEYSTONE_URL = "http://%s:5000/v3" % OPENSTACK_HOST
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user"

方法二:

事先安装 virtualenv
 pip install virtualenv
$ pip install virtualenvwrapper
$ export WORKON_HOME=~/Envs
$ source /usr/local/bin/virtualenvwrapper.sh

1.取得源代码:
git clone https://github.com/openstack/horizon.git
2.create a virtual environment:

mkvirtualenv venv
workon venv

3.pycharm配置

点击file settings---进入project interpreter---show all-----点击+号---all local ----existing environment
选择/home/sf/horizon/.venv/bin/python(新增的python2.7)
点击edit configurations
 点击‘+’号,然后选择python  
 配置 scripts path /home/sf/horizon/manage.py
        peremeters: runserver 127.0.0.1:8888
选择python interperater 为刚刚新增的python2.7(dashboard)

4.安装requirement.txt,编译项目

pip install -r requirement.txt
 python setup.py install 
  1. 启动
    python manage.py runserver 127.0.0.1:8888(或者直接debug)

在界面访问登陆时要重启controller 的httpd 和 memcached

SQLAlchemy 使用

参考链接
SQLAlchemy的是Python的SQL工具包和对象关系映射,给应用程序开发者提供SQL的强大功能和灵活性。它提供了一套完整的企业级的持久性模式,专为高效率和高性能的数据库访问,改编成简单的Python的领域语言。
SQLAlchemy是Python界的ORM(Object Relational Mapper)框架,它两个主要的组件: SQLAlchemy ORM 和 SQLAlchemy Core 。
安装 SQLAlchemy
pip install SQLAlchemy
安装MySQLdb
pip install MySQL-Python

使用:

import SQLAlchemy
import MySQLdb
url ='mysql+mysqldb://root:password@localhost/test?charset=utf8'
engine类似一个mysql连接,create_engine方法返回一个Engine实例,Engine实例只有直到触发数据库事件时才真正去连接数据库。 
echo参数是设置 SQLAlchemy 日志记录,这通过 Python 的标准logging模块的快捷方式。启用它,我们会看到产生的所有生成的 SQL,sqlalchemy与数据库通信的命令都将打印出来
engine =  SQLAlchemy.create_engine(url,echo=True)
执行查询
queryset = engine.execute(‘select * from table_name’)

映射(declare a Mapping)
declarative_base类维持了一个从类到表的关系,通常一个应用使用一个base实例,所有实体类都应该继承此类对象

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

定义映射的表,表名称、 数据类型的列,在这里定义一个User类:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine

DB_CONNECT_STRING = 'mysql+mysqldb://root:hengtian@localhost/test?charset=utf8'
engine = create_engine(DB_CONNECT_STRING,echo=True)

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer,primary_key=True)
    name = Column(String(10))
    fullname = Column(String(20))
    password = Column(String(20)) #可以设定长度

    def __init__(self,name,fullname,password):
        self.name = name
        self.fullname = fullname
        self.password = password

    def __repr(self):
        return "<User('%s','%s','%s')>"%(self.name,self.fullname,self.password)

Base.metadata.create_all(engine)

类使用声明式至少需要一个tablename属性定义数据库表名字,并至少一Column是主键。User类定义一个repr()方法,但请注意,是可选;
sqlalchemy 就是把Base子类转变为数据库表,定义好User类后,会生成Table和mapper(),分别通过User.table 和User.mapper返回这两个对象,对于主键,象oracle没有自增长的主键时,要使用:

from sqlalchemy import Sequence
Column(Integer,Sequence('user_idseq'),prmary_key=True)

engine 和 Session的绑定

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
这个定制的Session类将创建新的Session对象绑定到我们的数据库。 
无论何时你需要与数据库连接,你实例化一个Session:

session = Session()

Session
Session 使用 connection发送query,把返回的result row 填充到一个object中,该对象同时还会保存在Session中,Session内部有一个叫 Identity Map的数据结构,为每一个对象维持了唯一的副本。primary key 作为 key ,value就是该object。session刚开始无状态,直到有query发起时。对象的变化会被session的跟踪维持着,在数据库做下一次查询后者当前的事务已经提交了时,it fushed all pendings changes to the database.
这就是传说中的 Unit of work 模式
例如:

def unit_of_work():
    session = Session()
    album = session.query(Album).get(4)
    album.name = "jun"   
    #这里不会修改album的name属性,不会触发update语句

def unit_of_work():
    session = Session()
    album = session.query(Album).get(4)
    album.name = "jun"   
    #这里修改了album的name属性,会触发一个update语句
    session.query(Artist).get(11)
    session.commit()

添加多个的User对象,使用add_all() :

session.add_all([
User(name='wendy', fullname='Wendy Williams', password='foobar'),
User(name='mary', fullname='Mary Contrary', password='xxg527'),
User(name='fred', fullname='Fred Flinstone', password='blah')])

提交事务:
session.commit()

在Session上使用query()方法,创建了一个Query对象。此函数接受数目可变的参数,可以是任意组合的类和类表的描述符
Query对象通过Session.query获取,query接收类或属性参数,以及多个类

常用过滤操作:

equals:
query.filter(User.name == 'ed')
not equal:
query.filter(User.name !='ed')

LIKE:
query.filter(User.name.like('%d%')

IN:
query.filter(User.name.in_(['a','b','c'])

NOT IN:
query.filter(~User.name.in_(['ed','x'])

IS NULL:
filter(User.name==None)

IS NOT NULL:
filter(User.name!=None)

AND:
from sqlalchemy import and_
filter(and_(User.name == 'ed',User.fullname=='xxx'))    

查询返回结果:

query.all(): all()返回列表
query.first(): 返回第一个元素
query.one(): 有且只有一个元素时才正确返回。
count() 数量

一个sqlalchemy在cinder 中的应用
class SQLAlchemyStorage(StorageBackend):
"""
A :class:.StorageBackend using SQLAlchemy.
"""

def __init__(self, uri):
     self.engine = sqlalchemy.create_engine(uri)
     Base.metadata.bind = self.engine
     Base.metadata.create_all()
     Session.configure(bind=self.engine)

 def pre_build(self):
     self.build_session = Session()

 def has_node(self, id):
     session = Session()
     node = session.query(Node).filter(Node.id == id).first()
     session.close()
     return bool(node)

 def add_node(self, id, document, source):
     node = Node(id, document, source)
     self.build_session.add(node)
     self.build_session.flush()

 def post_build(self):
     self.build_session.commit()
     self.build_session.close()

nova创建虚拟机的底层代码分析(调用libvirt)

openstack中创建虚拟机的底层实现是nova使用了libvirt,代码在nova/virt/libvirt/driver.py。
流程链接
底层driver分析

    #image_meta:镜像的相关内容,#injected_files:要注入到VM的文件  
    #network_info:网络相关信息,block_device_info:磁盘相关信息  
    def spawn(self, context, instance, image_meta, injected_files,  
                  admin_password, network_info=None, block_device_info=None):  
            #确定客户机的磁盘映射关系  
            disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,  
                                                instance,  
                                                block_device_info,  
                                                image_meta)  
            #创建VM的磁盘文件  
            self._create_image(context, instance,  
                               disk_info['mapping'],  
                               network_info=network_info,  
                               block_device_info=block_device_info,  
                               files=injected_files,  
                               admin_pass=admin_password)  
            #综合各方面的信息,拼装一个define VM的XML文件  
            xml = self.to_xml(context, instance, network_info,  
                              disk_info, image_meta,  
                              block_device_info=block_device_info,  
                              write_to_disk=True)  
            #向neutron请求IP,然后使用xml创建domain  
            self._create_domain_and_network(context, xml, instance, network_info,  
                                            block_device_info)  

dashboard模块结构

Horizon的特点
将页面上所有元素模块化,网页中一些常见元素,表单,表格,标签页,全部封装成Python类,每个组件有自己对应的一小块html模板.当渲染整个页面的时候,Horizon先找到当前页面有多少组件,将各个组件分别进行渲染变成一段html片段,最后拼装成一个完整的html页面,返回浏览器。


简单总结Horizon的特点:

页面元素模块化
子面板可插拔
All in One(从部署上来说,Horizon只有它自己这一个组件)


openstack的界面相关的代码有三部分:

1.各类控件的基类,页面的通用模板等
/usr/lib/python2.7/site-packages/horizon

2.界面具体样式,数据获取等
/usr/share/openstack-dashboard

3.还有个容易被忽略的,登录认证界面
/usr/lib/python2.7/site-packages/openstack_auth

Horizon这套面板的设计分成三层:Dashboard -> PanelGroup -> Panel

每一个dashboard都是django中的一个app,django中的app可以理解成对业务逻辑模块化的一种手段,里面可以包含自己独有的url设定,模板,和业务逻辑代码。每个dashboard下定义了一系列的PanelGroup,虚拟机管理对应到界面上就是一个PanelGroup(ManageCompute), 里面有一系列的子panel(Overview, Instances, Volumes…)。Swift,heat,neutron的管理面板各自都是一个PanelGroup,底下有各自的子panel。


Horizon文件夹:
Horizon这个包是一些在django基础上写的通用组件,表格(table),标签页(tab),表单(form),面包屑导航 (browser),工作流(workflow),这些代码和openstack的具体业务逻辑没有什么关系,如果做一个新的django项目,理论上可以复用Horizon这个包中的代码
openstack_dashboard文件夹
openstack_dashboard/dashboards/中是各个面板的具体实现代码,其中包括各个面板的模板文件, 和后端service交互的业务逻辑代码等。


文件夹整体层次结构:


以下对重要目录做一个介绍,有些目录目前还没有接触到还不清楚具体的作用:

horizon

             ./doc: horizon相关帮助性文档

             ./horizon:horizon通用组件库

                                ./browsers:

                                ./conf:Horizon配置文件

                                ./contrib:

                                ./forms:form表单基类包

                               ./locale:国际化语言包

                               ./management:manage.py startdash/startpanel命令

                               ./static:horizon静态文件包

                               ./tables:table基类包

                               ./tabs:tab基类包

                               ./templates:模板文件基类

                               ./templatetags:模板标签基类

                               ./test:测试包

                               ./utils:工具包

                               ./workflows:工作流机制包

             ./openstack_dashboard:horizon各个面板的具体实现代码

                             ./api:调用nova、swift、glance等接口封装

                             ./conf:nova、cinder等API访问权限控制,叫 xxx_policy.json,里  面定义了鉴权用的rules。

                            ./dashboards:Horizon界面展示各个模块实现目录。

                                   ./admin:管理员界面

                                            ./instances:云主机管理界面

Neutron 相关技术

Neutron 主要有两种驱动: 1.linuxbridge 2.openvswitch
一个很好的博客
网络类型有: local
FLAT 要求宿主机的网卡和linuxbridge直接相连,一个flat占用一个网卡
如果要创建多个flat就要创建多个物理网卡
vlan
vxlan
GRE

一个tap对应一个port,
每个网络都有一个linuxbridge(相当于一个交换机), bridge之间没有连通则无法通信,如果bridge没有和物理网卡相连则无法与宿主机之外的网络通信


neutron在创建网络和子网之后会自动创建两个设备:
1.bridge设备 qbrxxx xxx 为network ID 的后11位
2.tap设备--对应port tapxxx xxx为port ID 的后11位
在实例创建时,neutron会在subnet中创建一个port,分配IP 和 MAC 地址,并将PORT分配给该实例


在实例启动时:
1.宿主机的neutron-liinuxbridge-agent会根据port信息创建tap设备,并链接到linuxbridge
2.同时该tap会映射成实例的虚拟网卡(VIF)即virtual interface,两个实例的虚拟网卡共同连接到同一个linuxbridge上,就可以实现通信


linuxbridge namespace用来隔离dnsmasq服务(dhcp)
在二层网络中vlan可以将一个物理交换机分割成机几个虚拟交换机
在三层网络中namespace可以将一个物理三层网络划分为多个虚拟的三层网络


neutron通过namespace为每个网络提供独立的dhcp和路由服务,从而允许租户创建重叠的网络
每个dnsmasq进程位于一个独立的namespace,命名为qdhcp -network id
ip netns list 可以查看所有的namespace
veth pair是一种成对出现的特殊网络设备,它像一根虚拟的网线,可以链接两个namespace,一端输入设备另一端读出


routing 服务提供跨subnet互联互通功能,neutron的路由服务是l3-agent组件提供的
l3-agent还通过iptables 提供 firewall 和 floating ip服务
如果veth对应 租户网络(内部网络),则其命名格式为qr-xxx
如果veth对应 外部网络 ,则其命名格式为qg-xxx


Core Plugin 和 Service Plugin 的区别
image

镜像制作

一个下很多镜像的地址镜像密码均为 intel@123
在创建qcow2文件时,大小要尽量设置的小,否则在创建实例时会占用较多的内存
windows删除虚拟磁盘,以减小镜像大小
(控制面板--系统--高级系统设置--设置--性能--高级--虚拟内存更改--无分页文件)
Win2003
注意步骤5、6在计算机安装好之后弹出下图之后配置(hdc改为hda),然后下图点击取消,登陆进去之后要更改网卡驱动,配DNS
windows 安装cloudbaseinit创建实例,网络初始化之后会自动重启,解决办法:给cloudbaseinit.conf文件,加上一行allow_reboot=false
windows的快照启动实例之后网络初始化太慢,解决办法:在打快照的机器上命令行执行ipconfig /release
释放IP 然后关机,打快照
windows2003安装curl,在curl下载地址下载xxx.CAB 文件,zip的不行解压后将i386里的四个文件全拷到c:/windows/system32目录下即可(其他系统直接下zip包就行
如果安装了一个程序(如winrar,curl),这命令行执行时报不是xxx命令,就这个exe文件(winrar.exe,curl.exe)拷贝到c:/windows/system32目录下即可
安卓镜像制作
android镜像下载地址
windows更新语言包,在控制面板语言里,增加,然后下载,换region和local
kali安装不能进图形化界面的解决方法
kali用户自动登陆
Kali安装xrdp
Macos
Win10
windows xp安装cloudbaseinit

Win2008
Win2012
例:
sudo virt-install --name=win10_I --ram=4096 --vcpus=2 --boot=cdrom --os-type windows --os-variant win8.1 --disk path=/home/sf/Downloads/virtio-win-0.1.141_amd64.vfd,device=floppy --force --disk path=/home/sf/win10_qiye.qcow2,device=disk,format=qcow2,bus=virtio --cdrom=/home/sf/win10_enterprise.iso --network network:default,model=virtio --graphics vnc,listen=0.0.0.0 --accelerate --hvm --noautoconsole
其他版本类似
一. Centos镜像制作

  1. 创建一个盘存储镜像
    qemu-img create -f qcow2 /tmp/centos.qcow2 10G
    所在路径为/tmp/centos.qcow2 大小为10G

  2. 用virt-install 进行初始化
    virt-install --virt-type kvm --name centos --ram 1024
    --disk /tmp/centos.qcow2,format=qcow2
    --network network=default
    --graphics vnc,listen=0.0.0.0 --noautoconsole
    --os-type=linux --os-variant=centos7.0
    --location=/images/CentOS-7-x86_64-Minimal-1611.iso
    --name 为名称
    --disk 为新建盘的位置
    --format 为格式
    --network 启动网络(默认的)
    --graphics vnc 允许VNC图形化
    --os-type 系统类型
    --os-variant 系统版本
    --location 镜像存储位置

  3. 打开VNC进行安装初始化
    VNC 配置为虚拟机的IP,端口是默认的5900,输入0就行
    例: 10.10.80.10:0
    如果不确定端口可以执行命令ps –ef|grep kvm|grep vnc进行查看

  4. 设置网络

  5. 设置时区
    要把时区该到**

  6. 硬盘设置
    硬盘默认是lvm要改为ext4

  7. 设置用户名和密码
    安装完成之后会自动机

  8. 在虚拟机中查看镜像状态
    virsh dumpxml centos:
    centos为机器名称

virsh list --all 查看所有机器
9. 启动镜像
virsh start centos 启动机器
如果是windows系统要安装virtio驱动,linux系统自带的有
10. 再次打开VNC
用之前设置的用户名和密码进行登陆
改ACPI设置 acpid
yum install acpid
systemctl enable acpid
11. 用cloudinit进行初始化
yum install cloud-init
12. growpart 允许扩展内存
yum install cloud-utils-growpart
13. nozeroconf 与cloudinit有关
echo "NOZEROCONF=yes" >> /etc/sysconfig/network

  1. Configure console 与日志有关
    编辑/etc/default/grub ,配置 GRUB_CMDLINE_LINUX字段的值
    改为
    GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=cl/root rd.lvm.lv=cl/swap console=tty0 console=ttyS0,115200n8”
    15.在虚拟机中查看镜像相关信息
    virsh dumpxml centos

  2. 在虚拟机中执行,移除镜像中MAC地址等信息
    virt-sysprep -d centos

  3. 在虚拟机中执行,解除关联:
    virsh undefine centos
    18.windows server 2012
    sudo virt-install --name=ws2012r2 --ram=2048 --vcpus=2 --os-type=windows --os-variant=win2k12r2 --disk /images/win2012/win2012_r2.qcow2,bus=virtio --disk /images/win2012/winserver2012.ISO,device=cdrom --disk /images/win2012/virtio-win-0.1.141.iso,device=cdrom,bus=ide --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole

openstack 安装之后需要修改的一些配置

1.数据库连接数改为最大10240

mariab修改最大连接数永久生效:
 编辑/usr/lib/systemd/system/mariadb.service,在[Service]项最后加上以下两行:
 LimitNOFILE=65535
 LimitNPROC=65535
编辑/etc/my.cnf和/etc/my.cnf.d/mariadb-server.cnf,在[mysqld]项最后加上下面一行:
 max_connections=1024
编辑/etc/my.cnf和/etc/my.cnf.d/openstack.cnf,在[mysqld]项最后加上下面一行:
 max_connections=1024
 重启服务
  systemctl daemon-reload
  service mariadb restart
 查看支持最大连接数:
 MariaDB [(none)]> show variables like "max_connections";

2.文件句柄数改为最大65535永久生效

编辑文件vim /etc/security/limits.conf,在最末加上:
 * soft nofile 65535
 * hard nofile 65535
 保存退出,reboot后ulimit -n查看是否生效

3.修改连接释放机制,防止timewait数过多:

编辑文件vim /etc/sysctl.conf,在最末加上:
net.ipv4.tcp_syncookies = 1
 net.ipv4.tcp_tw_reuse = 1
 net.ipv4.tcp_tw_recycle = 0(高并发时设为1)
 net.ipv4.tcp_fin_timeout = 30
 保存退出,执行sysctl -p

4.修改openstack worker数为5:

包含以下服务的worker:
 glance
 nova
 metadata
 neutron
  1. 访问dashboard 报500
    查看日志报too many open files
    参考链接

6.更改网络安全组
如果不设置安全组,可能会导致ping不通,而且ssh也连不上,
安全组设置: project--network--securitygroup--新增规则,加tcp/udp/icmp的ingress和Egress
7.还要改系统时间
date -s
clock -w

api url的解析(以nova为例)

流程解析链接

app:实际处理REST API请求的python类。

filter:一种装饰器,为app提供一层封装,在app处理请求之前会先调用filter的对象。

pipeline:所对应的对象是对filter和app的的封装,他将多个filter和某个app绑在一起,在app处理请求之前要先通过pipline指定的在app之前的filter的处理。

router:根据REST请求的URL让不同的对象的不同的方法处理该REST请求。

app---composite--filter

前台发送过来的rest api请求经过api-paste.int 进行解析
找到对应的wsgi Service


    [composite:osapi_compute]  
    use = call:nova.api.openstack.urlmap:urlmap_factory  

    /v2: openstack_compute_api_v21_legacy_v2_compatible  
    /v2.1: openstack_compute_api_v21  

其中使用'nova.api.openstack.urlmap模块的urlmap_factory函数来进行API的分发'
例如创建云主机,http://192.168.1.9:8774/v2.1/14fd316568bc4f6992ba161fd4e23001/servers,
用的是v2版本的api,根据路由解析可以很明显的看到最后调用的是‘paste.app_factory = nova.api.openstack.compute:APIRouterV21.factory’
到了具体的执行函数

    # vim nova/api/openstack/compute/__init__.py  
      class APIRouterV21(nova.api.openstack.APIRouterV21):  
        """Routes requests on the OpenStack API to the appropriate controller 
        and method. 
        """  
        def __init__(self, init_only=None):  
            self._loaded_extension_info = extension_info.LoadedExtensionInfo()  
            super(APIRouterV21, self).__init__(init_only)  
      
        def _register_extension(self, ext):  
            return self.loaded_extension_info.register_extension(ext.obj)  

paste.deploy

用来解析/etc/nova/api-paste.ini文件,加载用于服务的wsgi app。它的功能有:

 api-paste.ini中配置多个wsgi app,deploy可根据传入的app name加载指定的wsgi app;

`    deploy.loadapp("config:/etc/nova/api-paste.ini", name="osapi-compute")  `
加载api-paste.ini中,名为osapi-compute的WSGI APP,并作为结果返回。

通过写入api-paste.ini的配置,可方便地实现特定字符开始的url到特定wsgi app的映射。如:
[composite:osapi_compute]                                                         
  use = call:nova.api.openstack.urlmap:urlmap_factory                               
  /: oscomputeversions                                                   
  /v2: openstack_compute_api_v2   

通过该配置,以“/v2”开始的url将交给名为openstack_compute_api_v2的WSGI APP处理,其它以“/”开的url就交给oscomputerversions处理。其实这并非deploy的功能,而是上面配置的urlmap实现的。不过通过配置文件,再由deploy调用urlmap,使用就更简单了。

middle ware的简单加载和去除。
[composite:openstack_compute_api_v2]                                              
  use = call:nova.api.auth:pipeline_factory               
  keystone = faultwrap sizelimit authtoken keystonecontext ratelimit osapi_compute_app_v2  

上面的faultwrap sizelimit authtoken keystonecontext ratelimit都为middle ware(在nova代码中称为MiddleWare,deploy中称为filter),osapi_compute_app_v2才是wsgi app。请求先交给middle ware处理,再由middle ware决定要不要或者怎么交给wsgi app处理。这些middle ware是可以添加和去除的,如果不想对osapi_compute_app_v2进行限速,那么去掉ratelimit就可以了。其实这是pipeline_factory实现的功能,不过通过deploy来配置加载更方便。

  nova-api中提供了很多服务API:ec2(与EC2兼容的API),osapi_compute(openstack compute自己风格的API),osapi_volume(openstack volume服务API),metadata(metadata 服务API)等。通过配置文件api-paste.ini,可以方便管理这些API。

  deploy提供了server、filter、app的概念,其中filter(即middle ware)、app在nova-api被重度使用,的确太好用了。发布每个API时,它们有时需要一些相同的功能,如:keystone验证、限速、错误处理等功能。nova将这些功能实现为middle ware,如果需要,通过api-paste.ini配置,给它加上就可以。比如,我需要记录每个访问nova-api的ip,及它们的访问次数和访问的时间。那么我实现一个middle ware--nova.api.middleware:MonitorMiddleware来记录这些数据。通过下面的api-paste.ini配置,就可对nova-api的访问进行记录了。
[composite:openstack_compute_api_v2]                                              
  use = call:nova.api.auth:pipeline_factory               
  keystone = faultwrap sizelimit authtoken keystonecontext ratelimit <strong>monitor</strong> osapi_compute_app_v2  
    
  [filter:<strong>monitor</strong>]                                                                  
  paste.filter_factory = nova.api.middleware:MonitorMiddleware.factory  
 **routes**

   用来给服务内部定义url到具体函数的映射。deploy也有url到服务映射功能,但这个映射层次偏高一点。根据上面配置,deploy将以“/v2”开始的url将交给名为openstack_compute_api_v2处理。但openstack_compute_api_v2怎么将/v2/project_id/servers/的GET请求交给nova.api.openstack.compute.servers.Controller.index()处理,并且将POST请求交给create()处理呢;怎么将/v2/project_id/servers/id的GET请求交给show()处理呢?这个就是routes.mappers所提供的功能,它根据path和请求方法,将请求映射到具体的函数上。如在nova中,添加/v2/project_id/servers/{list_vm_state, os_vmsum}两个GET请求来分别获取指定VM的状态和VM的总数。可在nova.api.openstack.compute.APIRouter中添加如下两行,将请求分别交给list_vm_state和os_vmsum两个函数处理并返回结果:
self.resources['servers'] = servers.create_resource(ext_mgr)  
  mapper.resource("server", "servers",  
                  controller=self.resources['servers'],  
                  <strong>collection={'list_vm_state': 'GET',  
                              'os_vmsum': 'GET'}</strong>)  
  这里利用了routes.mapper支持restful api的特性,仅用两条指令,就定义了十多个url到函数的映射。当然你可以如下方式添加接口,不过代码稍多,风格不那么统一:
mapper.connect("server",  
                "/{project_id}/servers/list_vm_state",  
                controller=self.resources['servers'],  
                action='list_vm_state',  
                conditions={'list_vm_state': 'GET'})  
   
 mapper.connect("server",  
                "/{project_id}/servers/os_vmsum",  
                controller=self.resources['servers'],  
                action='os_vmsum',  
                conditions={'os_vmsum': 'GET'})  

pike 一次尴尬的经历

重启openstack 之后,虚拟机的ip地址ping不通,进虚拟机发现网卡启动失败,内部设置静态仍然没用
发现iptables的服务被关闭了,重启iptables服务之后,虚拟机网络正常
错误:
在创建虚拟机的时候报错,没有多余的浮动IP ,进入admin的networks,查看外部网络的 subnet,看到
Free IPs这一栏的数值小于1,发现确实floatingIP不够了
解决办法:
进入floatingiP 将里面所有状态为Down的条目release掉

nova源码结构分析

代码调用流程图
image


一. 整体结构:
从请求发出到响应返回的流程
Nova是和虚拟机打交道的模块,Nova是无共享、基于消息的架构所以Nova组件可以在多台服务器上分布式运行,想要知道一个项目有哪些服务组成,入口函数在哪里,最直接的方式就是查看项目根目录下的setup.cfg文件,是整个项目的入口文件,而其中的console_scripts是所有服务组件的入口,比如nova的
setup.cfg的console_scripts:

[entry_points]

console_scripts =
    nova-all = nova.cmd.all:main
    nova-api = nova.cmd.api:main
    nova-api-metadata = nova.cmd.api_metadata:main
    nova-api-os-compute = nova.cmd.api_os_compute:main
    nova-cells = nova.cmd.cells:main
    nova-cert = nova.cmd.cert:main
    nova-compute = nova.cmd.compute:main
    nova-conductor = nova.cmd.conductor:main
    nova-console = nova.cmd.console:main
    nova-consoleauth = nova.cmd.consoleauth:main
    nova-dhcpbridge = nova.cmd.dhcpbridge:main
    nova-idmapshift = nova.cmd.idmapshift:main
    nova-manage = nova.cmd.manage:main
    nova-network = nova.cmd.network:main
    nova-novncproxy = nova.cmd.novncproxy:main
    nova-rootwrap = oslo_rootwrap.cmd:main
    nova-rootwrap-daemon = oslo_rootwrap.cmd:daemon
    nova-scheduler = nova.cmd.scheduler:main
    nova-serialproxy = nova.cmd.serialproxy:main
    nova-spicehtml5proxy = nova.cmd.spicehtml5proxy:main
nova-xvpvncproxy = nova.cmd.xvpvncproxy:main

由上我们可以知道nova项目打包后会包含21个可执行程序,其中:
nova-api服务的入口是nova/cmd/api.py文件的main函数
Nova-compute服务的入口是nova/cmd/compute.py的main函数
Pdb调试,在想要设置断点的地方嵌入以下代码:
Import pdb
Pdb.set_trace()然后在命令行直接运行服务即可。
假如想跟踪nova创建虚拟机的过程,首先在/nova/api/openstack/compute/servers.py的create 函数下打断点即可,然后注意需要通过命令行直接运行,而不是通过systemd启动: su -c 'nova-api' nova
Openstack项目的目录结构并不是根据组件严格划分,而是根据功能划分,比如:
compute目录并不是一定在nova-compute节点上运行,而主要是和compute相关(虚拟机操作相关)的功能实现,同样的,scheduler目录代码并不全在scheduler服务节点运行,但主要是和调度相关的代码。


通常一个服务的目录都会包含api.py、rpcapi.py、manager.py这三个是最终要的模块
api.py: 通常是供其它组件调用的封装库。换句话说,该模块通常并不会由本模块调用。比如compute目录的api.py,通常由nova-api服务的controller调用。
rpcapi.py:这个是RPC请求的封装,或者说是RPC封装的client端,该模块封装了RPC请求调用。
manager.py: 这个才是真正服务的功能实现,也是RPC的服务端,即处理RPC请求的入口,实现的方法通常和rpcapi实现的方法一一对应。

比如对一个虚拟机执行关机操作:
API节点
nova-api接收用户请求 -> nova-api调用compute/api.py -> compute/api调用compute/rpcapi.py -> rpcapi.py向目标计算节点发起stop_instance()RPC请求
计算节点
收到stop_instance()请求 -> 调用compute/manager.py的callback方法stop_instance() -> 调用libvirt关机虚拟机


OpenStack项目的目录结构是按照功能划分的,而不是服务组件,因此并不是所有的目录都能有对应的组件。仍以Nova为例:

 Cmd:是服务的启动脚本,即所有服务的main函数。---看服务怎么初始化,就从这里开始
 Db:封装数据库访问,目前支持的driver为sqlalchemy
 Conf:Nova的配置项声明都在这里
 Locale:本地化处理
 Image:封装Glance调用接口
 Network:封装网络服务接口,根据配置不同,可能调用nova-network或者neutron。
 volume: 封装数据卷访问接口,通常是Cinder的client封装。
 virt: 这是所有支持的hypervisor驱动,主流的如libvirt、xen等。
 objects: 对象模型,封装了所有实体对象的CURD操作,相对以前直接调用db的model更安全,并且支持版本控制。
 policies: policy校验实现。
 tests: 单元测试和功能测试代码。

所有的API入口都是从xxx-pai开始的,RESTFUL API是openstack服务的唯一入口。也就是说,阅读源码就从API开始。而api组件也是按照实体划分的,不同的实体对应不同的controller,比如servers、flavors、keypairs等,controller的index方法对应list操作、show方法对应get操作、create创建、delete删除、update更新等。


二. 创建虚拟机过程分析
入口时nova/api/openstack/servers.py的create方法,在完成启动的过程中设计三个组件(每个组件各三个主要文件api,rpcapi,manager.py):

1. nova-conductor-----Nova 与数据库交互的组件
       (build_instances,_schedule_instances)
2. Nova-schedule------Nova调度组件,根据算法选择compute节点
       (select_destinatioins---根据调度算法选择计算节点)
3. Nova-compute------Nova计算功能的实体
       (build_and_run_instances)

总的来讲就是nova-api-----nova-conductor-----nova-schedule---nova-compute----libvirt-driver


三. Nova与数据库的交互
在早前的版本中nova是直接与数据库进行交互的,这样很不安全
为实现与数据库访问的解耦,在现在的版本中开发了nova_conductor组件,专门负责和数据库进行交互,在其他服务访问数据库时需要向nova-conductor发起RPC请求,由nova-conductor代理请求数据库

git clone项目安装方法

fwaas-dashboard
zun
zun-ui
kuryr
kuryr-libnetwork
1.进入目录
2.执行 pip install -r requirement.txt
3.执行python setup.py install

openstack pycharm 调试

远程调试的配置方法

1、在远程计算机上安装pydevd模块
首先,在本地开发环境的pycharm安装路径中找到pycharm-debug.egg文件(若远程计算机运行的是python3,则需要pycharm-debug-py3k.egg);
然后,将pycharm-debug.egg文件拷贝到远程计算机,在远程计算机中将pycharm-debug.egg添加至引用路径(/usr/lib/python2.7/site-packages),可以采用多种方式:

1.采用esay_install pycharm-debug.egg命令进行安装(pip命令无法安装,只能使用easy_install);
2.将pychram-debug.egg添加至PYTHON或sys.path:import sys;sys.path.append('/usr/lib/python2.7/site-packages/pycharm-debug.egg')
3.解压pycharm-debug.egg,将其中的pydev文件夹拷贝至远程应用程序目录下

最后,在远程计算机的python命令行中输入import pydevd,若没有报错则说明pydevd模块安装成功,如下图所示:

2、在本地开发环境的pycharm中进行监听配置
在pycharm中配置说明如下:

【Run】 - > 【Edit Configurations】
【Add New Configuration】- > 【Python Remote Debug】
填写Local host name和port,其中Local host name指的是本机开发环境的IP地址,而port则随便填写一个未被占用的端口即可;需要注意的是,由于远程计算机需要连接至本地开发环境,因此本地IP应该保证远程可以访问的到
【Apply】and 【OK】
如下图所示:

image
image

3、在本地开发环境的pycharm中配置Mapping映射

【Tools】-> 【Depioyment】->【Configuration】如下图所示:

image

【Mappings】配置Local path和Deployment path on server(这里选择远程计算上需要映射的代码文件即可):

image

点击OK,等待远程代码下载到本地pycharm里面
4、在远程计算机的应用程序中插入代码
将如下代码插入至远程计算机的应用程序中

import pydevd
pydevd.settrace('172.18.0.131', port=8090, stdoutToServer=True, stderrToServer=True)

其中,IP地址和端口号要与pycharm中监听配置保持一致
如下截图:

image

5、在pycharm中启动Debug Server
【Run】->【Debug】或者点击pycharm的有个虫子的图标,选择刚创建的远程调试配置项,在Debug Console中会显示如下信息:
image

这说明Debug Server已经启动并处于监听状态
6、向远程计算机应用程序发送请求(命令行、postman或者horizon都可以)
向远程计算机程序发送请求,当执行到pydevd.settrace语句时,便会与本地开发环境中的pycharm建立通讯连接,接下来便可以在本地IDE中进行单步调试了。
需要注意的是,本地开发环境必须保证IP地址和端口号可以从远程计算机访问的到,否真会无法建立连接。
通讯建立起来,进入调试如下图所示:

7.此处发现pycharm并没有进入到get_all 断点调试的代码处,而是进入了thread.py的线程文件,这是因为nova底层代码

使用的eventlet多线程(协程)导致,解决此问题参考如下:

grep -rn 'eventlet.monkey_patch' /usr/lib/python2.7/site-packages/nova
vim /usr/lib/python2.6/site-packages/nova/cmd/init.py


import eventlet from nova import debugger
 if debugger.enabled():   
    # turn off thread patching to enable the remote debugger   
    eventlet.monkey_patch(os=False, thread=False) 
else:    
    eventlet.monkey_patch(os=False)
改为:
from nova import debugger


if debugger.enabled():

    # turn off thread patching to enable the remote debugger

    eventlet.monkey_patch(os=False, thread=False)

else:

    eventlet.monkey_patch(os=False, thread=False)

--
neutron debug链接
或者

在远程计算机中启动应用程序,当执行到pydevd.settrace语句时,便会与本地开发环境中的PyCharm建立通讯连接,接下来便可以在本地IDE中进行单步调试了。

需要注意的是,本地开发环境必须保证IP地址和端口号可从远程计算机访问得到,否则会无法建立连接。

Centos 7使用zabbix

参考链接
Zabbix3.0安装使用教程
在给数据库赋权的时候加一条
grant all privileges on zabbix.* to zabbix@'%' identified by 'root'; 允许所有地址访问


dashboard
默认账号:Admin,密码:zabbix,这是一个超级管理员。登陆之后在右下角可以看到“connected as Admin“(中文版:连接为Admin)。


按照上面链接 zabbix-server装好之后,安装zabbix-agent
yum -y install zabbix-agent

zabbix-agent的配置使用
邮件告警


Zabbix组件

Zabbix Server:负责接收agent发送的报告信息的核心组件,所有配置、统计数据及操作数据均由其组织进行
Database Storage:专用于存储所有配置信息,以及有zabbix收集的数据
Web interface(frontend):zabbix的GUI接口,通常与server运行在同一台机器上
Proxy:可选组件,常用于分布式监控环境中,代理Server收集部分被监控数据并统一发往Server端
Agent:部署在被监控主机上,负责收集本地数据并发往Server端或者Proxy端


Zabbix server 的配置使用:
配置---->新建主机群组---->新建主机,并加入到主机群组
新建模板--->选择新建的模板,新建应用集--->新建监控项--->新建触发器,图形等
sendmail邮件发送的安装使用


 sendEmail -f [email protected] -t [email protected] -s smtp.163.com -u "我是 邮件主题" -o message-content-type=html -o message-charset=utf8 -xu [email protected] -xp smtp授权码 -m "我 是邮 内容" -o tls=no -l /var/log/sendMyEmail.log 
Jun 13 07:21:39 localhost sendEmail[6698]: Email was sent successfully!  From: <[email protected]> To: <[email protected]> Subject: [我是邮件主题] Server: [smtp.163.com:25]

报错1:
Jun 13 07:14:17 localhost sendEmail[6481]: ERROR => ERROR => SMTP-AUTH: Authentication to smtp.163.com:25 failed.

将 163邮箱密码改为授权码

报错2

System environment
CentOS Linux release 7.2.1511 (Core)

SendEmail send a message with the following error:
*******************************************************************
Using the default of Ssl_verify_mode of Ssl_verify_none for client
Is deprecated! Please set Ssl_verify_mode to Ssl_verify_peer
Together with ssl_ca_file| Ssl_ca_path for verification.
If you really don ' t want to verify the certificate and keep the
Connection open to Man-in-the-middle attacks, please set
Ssl_verify_mode explicitly to Ssl_verify_none in your application.
*******************************************************************
At/usr/bin/sendemail Line 1906.
Invalid ssl_version specified at/usr/share/perl5/vendor_perl/io/socket/ssl.pm line 415.

Problem Reason:
SSL.PM File 415 Line

${* $self {' _ssl_ctx '} = io::socket::ssl::ssl_context->new ($arg _hash) | | Return

# perl-v

This is Perl 5, version, Subversion 3 (v5.16.3) built for X86_64-linux-thread-multi
(with registered patches, the perl-v for more detail)

Since the version of Perl in CentOS 7 is 5.16 and centos6.5 is 5.10, the version is incompatible

解决方法:

A, uninstall the existing Perl version, install the old version (not recommended)
b, add Parameters-o tls=no option
#/usr/local/bin/sendemail-f [email protected] smtp.163.com-xu [email protected] 123456-t [email protected] ' test Mail "-M" Test mail "- o tls=no
APR 14:55:16 Server sendemail[185679]: Email was sent successfully!
***
发送邮件脚本

zabbix_sendEmail.txt

[root@localhost alertscripts]# ./sendEmail.sh [email protected] [email protected] '我是标题' siyao '我是内容'
Jun 13 23:01:31 localhost sendEmail[22252]: Email was sent successfully!

***
[邮件告警配置](http://www.cnblogs.com/Eivll0m/p/5446993.html)
***
安装文档
[01.yum安装zabbix_亲测.docx](https://github.com/sfPPP/openstack-note/files/2100538/01.yum.zabbix_.docx)
[zabbix更换字体](https://blog.csdn.net/kk185800961/article/details/51820533)

[zabbix 端口批量监听](https://www.cnblogs.com/JeremyWYL/p/8328081.html)
[zabbix源码编译安装](http://www.cnblogs.com/wangxiaoqiangs/p/5336210.html)
[zabbix 日志监控](https://blog.csdn.net/wszll_alex/article/details/77001686)
***
**日志监控时要注意agent上主动模式的设置**

Server='zabbix-server的IP'
StartAgents=3 //设置为0是纯主动模式
ServerActive='zabbix-server的IP'
Hostname=‘本机IP’

***
**zabbix主动模式和被动模式的比较**

具体:
主动、被动模式都是相对于proxy来说的。proxy主动发送数据就是主动模式;proxy等待server的请求,再发送数据就是被动模式。因为主动模式可以有效减轻zabbix server压力,需要监控的东西很多时一定要把监控模式更改为主动监控

***
被动模式流程,被动模式一定要记得设置Server = ServerIP
被动模式工作流程:
Server 打开一个TCP连接
Server发送一个key 为agent.ping
Agent接受这个请求,然后响应< HEADER >< DATALEN >
Server对接受到的数据进行处理
TCP连接关闭
***

主动模式流程,主动模式一定要记得设置ServerActive=ServerIP
Agent向Server建立一个TCP连接
Agent请求需要检测的数据列表
Server响应Agent,发送一个Items列表
Agent允许响应
TCP连接完成本次会话关闭
Agent开始周期性地收集数据

监控ssh暴力破解

日志监控的脚本可以参照这个写:

    # cat /root/ssh_failed.sh  //内容如下  
    #!/bin/sh  
    SCANIP=`grep "Failed" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | awk '{print $1"="$2;}'`  
    for i in $SCANIP  
    do  
        NUMBER=`echo $i | awk -F= '{print $1}'`  
        SCANIP=`echo $i | awk -F= '{print $2}'`  
        echo "$NUMBER($SCANIP)"  
        if [ $NUMBER -gt 10 ] && [ -z "`/sbin/iptables -vnL INPUT | grep $SCANIP`" ]  
        then  
            /sbin/iptables -I INPUT -s $SCANIP -m state --state NEW,RELATED,ESTABLISHED -j DROP  
            echo "`date` $SCANIP($NUMBER)" >> /var/log/scanip.log  
        fi  
    done  

openstack Client和api比较

以NOVA 为例:
Client

nova client对请求进行封装,然后通过api发出请求
执行 CLI:nova list
args.func(self.cs, args) 的处理过程实际上是:


def do_list(cs, args) 这个函数被注册为一个 nova list 的function
回调的时候实际上调用:novaclient.v2.shell.do_list 的这个方法
    servers = cs.servers.list
    这个是核心的查询方法,调用了实例化 v2 client 的 servers 的 list 方法

novaclient.v2.client.Client 初始化的实例化了 servers:
    self.servers = servers.ServerManager(self)

Client的使用:

>>> from novaclient import client

实例化 client 对象:
>>> nova = client.Client(2,'admin','pass',None,'http://172.16.34.29/identity/',project_name='admin')

获取 VM instances 列表:
>>> nova.servers.list()
[<Server: yenai>]

创建一个新的 VM:
>>> nova.servers.create('client_test','834b3b40-c1b7-43bb-94d6-9327bb564612','1')
<Server: client_test>

获取 VM instances 列表:
>>> nova.servers.list()
[<Server: client_test>, <Server: yenai>]

删除刚刚创建的 VM:
>>> testvm = nova.servers.list()[0]
>>> nova.servers.delete(testvm)
()
>>> nova.servers.list()

所以最终 nova list 实际上是调用 novaclient.v2.servers.ServerManager.list
这个方法就是构造了请求的 URL,最终发送 RESTful 请求到 nova-api。

API
直接请求url(要加请求头token --'X-Auth-Token')

pike 装cinder

Cinder块存储服务

块存储服务(cinder)为实例提供块存储。存储的分配和消耗是由块存储驱动器,或者多后端配置的驱动器决定的。还有很多驱动程序可用:NAS/SAN,NFS,ISCSI,Ceph等。典型情况下,块服务API和调度器服务运行在控制节点上。取决于使用的驱动,卷服务器可以运行在控制节点、计算节点或单独的存储节点。
它由下面4个组件来组成的: 基本命令
1.cinder-api:
接受API请求,并将请求调度到cinder-volume 执行
2.cinder-volume
与块存储服务,例如cinder-scheduler的进程直接交互。它也可以与这些进程通过一个消息队列交互。cinder-volume服务响应到块存储服务的读写请求来维持状态。它也可以和多种存储驱动交互
3.cinder-scheduler守护进程
选择最优存储提供节点来创建卷。其与nova-scheduler组件类似。
4.cinder-backup daemon(可以不装,swift或者ceph)
采用nfs cinder 文件系统
cinder-backup服务提供任何种类备份卷到一个备份存储提供者。就像cinder-volume服务,它与多种存储提供者在驱动架构下进行交互。
单机版cinder安装步骤,这个文档不能全信
1.下载包
yum install openstack-cinder targetcli
2.数据库准备

  mysql -u root -p
 CREATE DATABASE cinder;
 GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' \
  IDENTIFIED BY 'CINDER_DBPASS';
 GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' \
  IDENTIFIED BY 'CINDER_DBPASS';

3.新建用户和服务

openstack user create --domain default --password-prompt cinder
openstack role add --project service --user cinder admin
openstack service create --name cinderv2 \
  --description "OpenStack Block Storage" volumev2
openstack service create --name cinderv3 \
  --description "OpenStack Block Storage" volumev3
openstack endpoint create --region RegionOne \
  volumev2 public http://controller:8776/v2/%\(project_id\)s
 openstack endpoint create --region RegionOne \
  volumev2 internal http://controller:8776/v2/%\(project_id\)s
 openstack endpoint create --region RegionOne \
  volumev2 admin http://controller:8776/v2/%\(project_id\)s
openstack endpoint create --region RegionOne \
  volumev3 public http://controller:8776/v3/%\(project_id\)s
openstack endpoint create --region RegionOne \
  volumev3 internal http://controller:8776/v3/%\(project_id\)s
openstack endpoint create --region RegionOne \
  volumev3 admin http://controller:8776/v3/%\(project_id\)s
  1. nfs的配置
 yum -y install nfs-utils rpcbind
 vi /etc/exports
/data/nfs *(rw,no_root_squash)   # 把/data/nfs共享出去,
(rpcbind要比nfs先启动)
 systemctl restart rpcbind
 systemctl enable rpcbind
 systemctl restart nfs
 systemctl enable nfs

showmount -e localhost
Export list for localhost:
/data/nfs *

5.创建nfs配置文件

vi/etc/cinder/nfs_shares
192.168.56.12:/data/nfs     
chown root:cinder /etc/cinder/nfs_shares
 chmod 640 /etc/cinder/nfs_shares
ll  /etc/cinder/nfs_shares    # 确保权限一致
-rw-r-----. 1 root cinder 24 Feb 10 21:57 /etc/cinder/nfs_shares

6.改 /etc/cinder/cinder.conf

[DEFAULT]
transport_url = rabbit://openstack:ADMIN_PASS@controller
auth_strategy = keystone
my_ip = 10.10.80.12
enabled_backends = nfs
glance_api_servers = http://controller:9292
[backend]
[backend_defaults]
nfs_snapshot_support = True
[barbican]
[brcd_fabric_example]
[cisco_fabric_example]
[coordination]
[cors]
[database]
connection = mysql+pymysql://cinder:root@localhost/cinder
[fc-zone-manager]
[healthcheck]
[key_manager]
[keystone_authtoken]
auth_uri = http://controller:5000
auth_url = http://controller:35357
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = cinder
password = ADMIN_PASS
[matchmaker_redis]
[nova]
[oslo_concurrency]
lock_path = /var/lib/cinder/tmp
[oslo_messaging_amqp]
[oslo_messaging_kafka]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_messaging_zmq]
[oslo_middleware]
[oslo_policy]
[oslo_reports]
[oslo_versionedobjects]
[profiler]
[ssl]
[nfs]
volume_driver = cinder.volume.drivers.nfs.NfsDriver
nfs_shares_config = /etc/cinder/nfs_shares
nfs_mount_point_base = $state_path/mnt
systemctl enable openstack-cinder-volume.service target.service
systemctl start openstack-cinder-volume.service target.service

su -s /bin/sh -c "cinder-manage db sync" cinder 同步数据库

5.改nova.conf配置

[cinder]
os_region_name = RegionOne

systemctl restart openstack-nova-api.service
 systemctl enable openstack-cinder-api.service openstack-cinder-scheduler.service
systemctl start openstack-cinder-api.service openstack-cinder-scheduler.service

6.改/data/nfs权限

 chmod 777 /data/nfs
否则会报错:
ERROR oslo_messaging.rpc.server IOError: [Errno 13] Permission denied: '/var/lib/cinder/mnt/6dbef71848bc7293622410394f02f74d/volume-

linux网络设备

linux 网络设备:

  1. bridge:
    Bridge 的功能主要在内核里实现。当一个从设备被 attach 到 Bridge 上时,相当于现实世界里交换机的端口被插入了一根连有终端的网线。每当这个从设备收到数据时都会调用这个函数可以把数据转发到 Bridge 上。当 Bridge 接收到此数据时,br_handle_frame()被调用,进行一个和现实世界中的交换机类似的处理过程:判断包的类别(广播/单点),查找内部 MAC 端口映射表,定位目标端口号,将数据转发到目标端口或丢弃,自动更新内部 MAC 端口映射表以自我学习。

  2. VLAN
    每个 VLAN 拥有多个端口,同一 VLAN 端口之间可以交换转发,不同 VLAN 端口之间隔离,所以其包含两层功能:交换与隔离。Linux VLAN device 实现的是隔离功能,没有交换功能。一个 VLAN 母设备不可能拥有两个相同 ID 的 VLAN 子设备,因此也就不可能出现数据交换情况
    Linux 里 802.1.q VLAN 设备是以母子关系成对出现的,母设备相当于现实世界中的交换机 TRUNK 口,用于连接上级网络,子设备相当于普通接口用于连接下级网络。当数据在母子设备间传递时,内核将会根据 802.1.q VLAN Tag 进行对应操作。母子设备之间是一对多的关系,一个母设备可以有多个子设备,一个子设备只有一个母设备,一个子设备有一包数据需要发送时,数据将被加入 VLAN Tag 然后从母设备发送出去。当母设备收到一包数据时,它将会分析其中的 VLAN Tag,如果有对应的子设备存在,则把数据转发到那个子设备上并根据设置移除 VLAN Tag,否则丢弃该数据。在某些设置下,VLAN Tag 可以不被移除以满足某些监听程序的需要,如 DHCP 服务程序

3.TAP 设备与 VETH 设备

TUN/TAP 设备是一种让用户态程序向内核协议栈注入数据的设备,一个工作在三层,一个工作在二层,使用较多的是 TAP 设备。VETH 设备出现较早,它的作用是反转通讯数据的方向,需要发送的数据会被转换成需要收到的数据重新送入内核网络层进行处理,从而间接的完成数据的注入。
VETH 设备总是成对出现,送到一端请求发送的数据总是从另一端以请求接受的形式出现

Linux 主要使用以下三种设备模型:Bridge、TAP、VETH、VLAN。
Bridge 设备是基于内核实现的二层数据交换设备,其作用类似于现实世界中的二级交换机。
TAP 设备是一种工作在二层协议的点对点网络设备,每一个 TAP 设备都有一个对应的 Linux 字符设备,用户程序可以通过对字符设备的读写操作,完成与 Linux 内核网络协议栈的数据交换工作,在虚拟化环境中经常被模拟器使用。VETH 设备是一种成对出现的点对点网络设备,从一段输入的数据会从另一端改变方向输出,通常用于改变数据方向,或连接其它网络设备。
VLAN 设备是以母子关系出现的一组设备,是 Linux 里对 802.1.Q VLAN 技术的部分实现,主要完成对 802.1.Q VLAN Tag 的处理。

Linux 上配置网络设备命令举例

以 Redhat6.2 红帽 Linux 发行版为例,如果已安装 VLAN 内核模块和管理工具 vconfig,TAP/TUN 设备管理工具 tunctl,那么可以用以下命令设置前述网络设备:

创建 Bridge:brctl addbr [BRIDGE NAME]
删除 Bridge:brctl delbr [BRIDGE NAME]
attach 设备到 Bridge:brctl addif [BRIDGE NAME] [DEVICE NAME]
从 Bridge detach 设备:brctl delif [BRIDGE NAME] [DEVICE NAME]
查询 Bridge 情况:brctl show
创建 VLAN 设备:vconfig add [PARENT DEVICE NAME] [VLAN ID]
删除 VLAN 设备:vconfig rem [VLAN DEVICE NAME]
设置 VLAN 设备 flag:vconfig set_flag [VLAN DEVICE NAME] [FLAG] [VALUE]
设置 VLAN 设备 qos:

vconfig set_egress_map [VLAN DEVICE NAME] [SKB_PRIORITY] [VLAN_QOS]

vconfig set_ingress_map [VLAN DEVICE NAME] [SKB_PRIORITY] [VLAN_QOS]

查询 VLAN 设备情况:cat /proc/net/vlan/[VLAN DEVICE NAME]
创建 VETH 设备:ip link add link [DEVICE NAME] type veth
创建 TAP 设备:tunctl -p [TAP DEVICE NAME]
删除 TAP 设备:tunctl -d [TAP DEVICE NAME]
查询系统里所有二层设备,包括 VETH/TAP 设备:ip link show
删除普通二层设备:ip link delete [DEVICE NAME] type [TYPE]

    bridge:网桥,Linux中用于表示一个能连接不同网络设备的虚拟设备,linux中传统实现的网桥类似一个hub设备,bridge相连的所有接口都可以收到数据包。而ovs管理的网桥一般类似交换机。

    br-int:bridge-integration,综合网桥,常用于表示实现主要内部网络功能的网桥。

    br-ex:bridge-external,外部网桥,通常表示负责跟外部网络通信的网桥。

    GRE:General Routing Encapsulation,一种通过封装来实现隧道的方式。在openstack中一般是基于L3的gre,即original pkt/GRE/IP/Ethernet

    VETH:虚拟ethernet接口,通常以pair的方式出现,一端发出的网包,会被另一端接收,可以形成两个网桥之间的通道。虚拟网络对VETH,实现了不同虚拟网络的联通。

    qvb:neutron veth, Linux Bridge-side

    qvo:neutron veth, OVS-side

    TAP设备:模拟一个二层的网络设备,可以接受和发送二层网包。

    TUN设备:模拟一个三层的网络设备,可以接受和发送三层网包。

    iptables:Linux 上常见的实现安全策略的防火墙软件。

    Vlan:虚拟 Lan,同一个物理 Lan 下用标签实现隔离,可用标号为1-4094。

    VXLAN:一套利用 UDP 协议作为底层传输协议的 Overlay 实现。一般认为作为 VLan 技术的延伸或替代者。

    namespace:用来实现隔离的一套机制,不同 namespace 中的资源之间彼此不可见。

rabbitmq web界面登陆

默认情况下15672端口可能没开
rabbitmq-plugins enable rabbitmq_management 允许web访问

guest用户默认只能localhost登陆
1首先查看所有用户
rabbitmqctl list_users
2创建新的用户
rabbitmqctl add_user Username Password
3给用户设置身份(tag)
rabbitmqctl set_user_tags Username tag
用户角色有:

按照个人理解,用户角色可分为五类,超级管理员, 监控者, 策略制定者, 普通管理者以及其他。


(1) 超级管理员(administrator)

可登陆管理控制台(启用management plugin的情况下),可查看所有的信息,并且可以对用户,策略(policy)进行操作。

(2) 监控者(monitoring)

可登陆管理控制台(启用management plugin的情况下),同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)

(3) 策略制定者(policymaker)

可登陆管理控制台(启用management plugin的情况下), 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。

与administrator的对比,administrator能看到这些内容

(4) 普通管理者(management)

仅可登陆管理控制台(启用management plugin的情况下),无法看到节点信息,也无法对策略进行管理。

4给用户赋权
rabbitmqctl set_permissions -p / test "." "." ".*"

修改rabbitmq最大连接数
注意下图的几项指标
image

以下为使用systemd的修改方法:

1、系统层修改:
通过修改sysctl配置,提高系统的打开文件数量
vim /etc/sysctl.conf,添加:
fs.file-max = 65535
执行sysctl -p

此步骤调整后,打开rabbitmq管理页面,会发现rabbitmq最大的打开文件数量并未调整,需要进行下面步骤

2、修改rabbitmq配置
修改/etc/systemd/system/multi-user.target.wants/rabbitmq-server.service
在[Service]中,增加LimitNOFILE=20000(具体数值根据需要)

执行systemctl daemon-reload
重启rabbitmq服务

Dashboard 登陆 Unable to create a new session key. It is likely that the cache is unavailable

Dshboard 登陆时报错
Unable to create a new session key. It is likely that the cache is unavailable

查看apache日志/var/log/httpd/error_log,发现以下错误

RuntimeError: Unable to create a new session key. It is likely that the cache is unavailable.
问题:重启httpd 和 memcached 之后dashboard无法登陆
原因分析: 可能是在重启的时候memcached的缓存没清完全
解决方法
将session从cache换到file 中
1.修改配置文件

vim /etc/openstack-dashboard/local_settings

2.将SESSION_ENGINE值修改

原

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'


改为

SESSION_ENGINE = 'django.contrib.sessions.backends.file'

3.重启服务,然后再次登录。
systemctl restart httpd.service memcached.service

glance相关知识

image和 镜像文件的区别:

image 是 glance 上保存的镜像,一般是qcow2格式的
镜像文件是 instance 启动盘所对应的文件(backing file,一般为iso格式)

在nova 创建实例之前,会先将其inage 下载到指定位置,然后将qcow2文件转换为iso文件,作为镜像文件(backing file)来创建实例,如果已经存在该image,则之间将qcow2文件转换为iso文件

Glance-API
主要用来响应各种REST请求然后通过其他模块(主要是glance-registry组件和后端存储接口)完成镜像的上传、删除、查询等操作。可以简单的再分为两部分:一层中间件,它主要是做一些对请求的解析工作(如分析出版本号), 另外一部分提供实际的服务(如与镜像上传下载的后端存储接口交互)。默认绑定端口是9292。

Glance-Registry 镜像注册服务
用于提供镜像元数据的REST接口。主要工作是存储或者获取镜像的元数据,与MySQL数据库进行交互。也可以简单的再细分为两部分,API和具体的Server。元数据是指镜像相关的一些信息(如id,size, status,location, checksum, min_disk, min_ram, owner等),真正的镜像数据保存在实际所使用的后端存储里(如swift,s3,filesystem等)。默认绑定的端口是9191。

API解析流程

glance-api-paste.ini文件,/usr/share/glance/glance-api-paste.ini定义了很多不同的pipeline,他们的区别在于定义了不同的filter来处理请求,而最终请求被glance.api.v1.router:API的对象处理。然后我们看一下router.py文件的API类。它继承了wsgi.Router,可以根据REST请求的URL以及请求的类型(GET、PUT等)将请求映射给不同对象的不同方法进行处理。

glance/api/v1/router.py映射请求的部分代码如下:

images_resource = images.create_resource()

mapper.resource("image", "images", controller=images_resource,
                collection={'detail': 'GET'})
mapper.connect("/", controller=images_resource, action="index")
mapper.connect("/images/{id}", controller=images_resource,
               action="meta", conditions=dict(method=["HEAD"]))

members_resource = members.create_resource()
mapper.resource("member", "members", controller=members_resource,
                parent_resource=dict(member_name='image',
                collection_name='images'))
mapper.connect("/shared-images/{id}",
               controller=members_resource,
               action="index_shared_images")
mapper.connect("/images/{image_id}/members",
               controller=members_resource,
               action="update_all",
               conditions=dict(method=["PUT"]))

通过查看完整的代码(v1和v2),我们可以知道,请求最终都是被images.py、image_data.py、schemas.py、image_access.py以及image_tags.py中的controller类的不同方法处理。
 所以上面添加镜像的请求会被glance/api/v1/images.py中的Controller类的create函数处理,该方法会调用_handle_source方法,进而调用_upload_and_activate方法。_upload_and_activate方法做了两件重要的事情:
调用self._upload上传镜像,调用self._activate通过glance registry服务更新glance数据库中镜像的状态。具体存储接口实例的选择是在self._upload方法中。之后会调用确定的存储接口中的add方法保存需要上传的镜像。

restful-api http 协议

openstack中各组件是基于restful api通信的
restful api可以单纯的理解为一个url地址:http://www.egon.com/index.html
网址url的解析过程:
1.首先必须web服务器运行
2.客户端运行浏览器软件
3.用户输入http://www.sina.com.cn/
4.浏览器发送请求的url会经过DNS 操作解析,将域名解析为IP 地址
5.客户端浏览器发送http请求http://202.103.0.33:80/index.html (80是web服务器的默认端口,index.html是默认的请求的资源)
6.WEB 服务器端收到该http的request请求头,从请求头中获取客户端的方法GET/POST.../index.html这个路径,及客户端请求的其他相关信息(request.data可以获取到请求头中的参数信息等)
7.服务端web服务根据取得的信息,回复respone响应头
响应头中包含:

响应代码:200表示成功,3xx表示重定向,4xx表示客户端发送的请求有错误,5xx表示服务器端处理时发生了错误;
响应类型:由Content-Type指定;
以及其他相关的Header;

通常服务器的HTTP响应会携带内容,也就是有一个Body,包含响应的内容,网页的HTML源码就在Body中,压缩后返回给客户端。

8.客户端浏览器收到服务端发来的数据,解压后解析html内容,用户就看到网页内容了

9.html内可能嵌套其他的链接,比方说图片、视频、javascript脚本,flash等,客户端浏览器会继续发起http请求来获取它们。这样来自图片和视频的压力就被分散到各个服务器,一个站点由无数个站点相互连接起来,就形成了World Wide Web,简称WWW。

综上,其实就是一次http请求-响应的流程
http协议概述

HTTP(hypertext transport protocol),即超文本传输协议。这个协议详细规定了浏览器和万维网服务器之间互相通信的规则。

HTTP就是一个通信规则,通信规则规定了客户端发送给服务器的内容格式,也规定了服务器发送给客户端的内容格式。其实我们要学习的就是这个两个格式!客户端发送给服务器的格式叫“请求协议”;服务器发送给客户端的格式叫“响应协议”。

特点:

HTTP叫超文本传输协议,基于请求/响应模式的!
HTTP是无状态协议,FTP是有状态。

URL:统一资源定位符,就是一个网址:协议名://域名:端口/路径,例如:http://www.oldboy.cn:80/index.html
请求协议

HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。

1.GET方法
最常见的一种请求方式,当客户端要从服务器中获取数据时,当点击网页上的链接或者通过在浏览器的地址栏输入网址来浏览网页的,使用的都是GET方式。GET方法要求服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。使用GET方法时,请求参数和对应的值附加在URL后面,利用一个问号(“?”)代表URL的结尾与请求参数的开始,传递参数长度受限制。例如,/index.jsp?id=100&op=bind,这样通过GET方式传递的数据直接表示在地址中,所以我们可以把请求结果以链接的形式发送给好友
由于不同的浏览器对地址的字符限制也有所不同,一般最多只能识别1024个字符,所以如果需要传送大量数据的时候,也不适合使用GET方式。
GET 多参 url = 'xxx.html?id='id的直+‘&pk=’+pk
2.POST 方法
POST方法将请求参数封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据,这样POST方式对传送的数据大小没有限制,而且也不会显示在URL中
把提交的数据放置在是HTTP包的包体<request-body>
GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变, POST的安全性要比GET的安全性高

状态码:

HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。

1xx:指示信息--表示请求已接收,继续处理。
2xx:成功--表示请求已被成功接收、理解、接受。
3xx:重定向--要完成请求必须进行更进一步的操作。
4xx:客户端错误--请求有语法错误或请求无法实现。
5xx:服务器端错误--服务器未能实现合法的请求。

常见状态代码、状态描述的说明如下。

200 OK:客户端请求成功。
400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden:服务器收到请求,但是拒绝提供服务。
404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
500 Internal Server Error:服务器发生不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。

openstack horizon 新增dashboard

主要是仿照其他模块结构新增
层次结构:
---------panel_dashboard ——》project

           -----------panel_group——》compute

                         ------------panel——》instance

层次结构之间关联关系的处理在/horizon/horizon/base.py里面完成的
image

1.在openstack_dashboard/dashboards下面新建一个目录,例如mydashboard文件夹
在mydashboard文件夹下新建dashboard.py文件,最简化的目录结构为:
image

mydashboard等同于project, instances等同于instances
image

各文件内容可以仿照其他模块
例如 dashboard.py

class mydashboard(horizon.Dashboard):
    name = _("mydashboard")
    slug = "mydashboard"

    if getattr(settings, 'POLICY_CHECK_FUNCTION', None):
        policy_rules = (('identity', 'admin_required'),
                        ('image', 'context_is_admin'),
                        ('volume', 'context_is_admin'),
                        ('compute', 'context_is_admin'),
                        ('network', 'context_is_admin'),
                        ('orchestration', 'context_is_admin'),)
    else:
        permissions = (tuple(utils.get_admin_permissions()),)
horizon.register(mydashboard)

2.在mydashboard目录下加一个overview作为默认的panel,不然会报错
image
url的获取与解析
image

panel.py


from django.utils.translation import ugettext_lazy as _

import horizon

class Instances(horizon.Panel):
    name = _("Instances")
    slug = 'instances'
    permissions = ('openstack.services.compute',)

3.在openstack_dashboard/enabled下面加一下绿色的几个文件
image
上图:
A:x000代表新建的项目(一级目录)

# The slug of the dashboard to be added to HORIZON['dashboards']. Required.
DASHBOARD = 'mydashboard'

# A list of applications to be added to INSTALLED_APPS.
ADD_INSTALLED_APPS = [
    'openstack_dashboard.dashboards.mydashboard',
]

ADD_ANGULAR_MODULES = [
]

AUTO_DISCOVER_STATIC_FILES = True

B: xxx_panel_group.py代表一个panel_group(二级目录)

    from django.utils.translation import ugettext_lazy as _

# The slug of the panel group to be added to HORIZON_CONFIG. Required.
PANEL_GROUP = 'compute'
# The display name of the PANEL_GROUP. Required.
PANEL_GROUP_NAME = _('Compute')
# The slug of the dashboard the PANEL_GROUP associated with. Required.
PANEL_GROUP_DASHBOARD = 'mydashboard'

C: xxx_panel 代表panel(三级目录)

# The slug of the panel to be added to HORIZON_CONFIG. Required.
PANEL = 'images'
# The slug of the dashboard the PANEL associated with. Required.
PANEL_DASHBOARD = 'mydashboard'  
# The slug of the panel group the PANEL is associated with.
PANEL_GROUP = 'compute'

# Python panel class of the PANEL to be added.
ADD_PANEL = 'openstack_dashboard.dashboards.mydashboard.images.panel.Images'

nova 所存储镜像过期时间配置

Should unused base images be removed? (boolean value)

#remove_unused_base_images=true(是否删除不在用的镜像)

Unused unresized base images younger than this will not be removed.

(integer value)

#remove_unused_original_minimum_age_seconds=86400(不在用的镜像的过期时间)

remove_unused_original_minimum_age_seconds 的值默认是86400秒(24小时),你可 以等待这个时间间隔来查看基础镜像是否被删除,

openstack常用 image metadata

磁盘控制器 hw_disk_bus

ide
  virtio
  scsi
  uml
  xen
  usb

挂载磁盘格式hw_cdrom_bus

ide
  virtio
  scsi
  uml
  xen
  usb

虚拟网卡型号 hw_vif_model

  rtl8139
   virtio
   e1000
   ne2k_pci
   pcnet

常用元数据

labels aren t unique duplicates

openstack dashboard 无法访问 httpd 启动出错
image
报错如上图
原因: app加载重复
执行 egrep appname 文件夹
image
如上图可以看到neutron_fwaas_dashboard这个app被加载了两次
解决方法:因为我们用的是fwaas_v2所以把_7010给干掉

mount 和umount命令

mount a b 将a 挂载到b

挂载CDROM:

      mount /dev/cdrom /home/ping.bao/cd



取消挂载:



      umount /dev/cdrom /home/ping.bao/cd

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.