|
|
虚拟机启动时候需要注入hostname、password、public-key、network-info之类的信息,以便虚拟机能够被租户管理。对于这些信息的注入openstack提供了两种方式, guestfs-inject以及metadata-server。+ Y9 W" i1 e0 O7 z0 |
# t b$ K4 |8 F5 mguestfs-inject的使用很受限制尤其是并不是所有镜像都能够支持这种方式,I版本也以及取消了这种方式; metadata-server使用上更为灵活,但是他们都依赖镜像内部必须装有cloud-init组件,尽管如此,由于aws力挺metadata-server,所以这已经成为了虚拟机 信息注入方案事实上的标准。
, M( w: w( \% c1 Z$ Q& _' D) e! O# N: x0 `# R
本文主要探讨metadata-server在openstack中如何实现。
4 R2 C9 s3 G" ?* E: }, v5 Z4 `1 @- j
- C) T0 m# E( j0 ]5 p1. cloud-init
8 ]" g+ a+ `3 n3 n# m
! x! J# b; K- P3 F" ]9 ccloud-init是一个在启动的时候定制你的Iaas平台中虚拟机的包,它可以帮助你重新定义你的虚拟机而不需要重新安装,只需要加入对应的配置项即可。在Ec2中有很多镜像都安装了cloud-init来方便用户定制自己的虚拟机。它可以让你在虚拟机启动的时候设置语言环境,设置主机名,甚至生成私钥,添加用户自己的ssh公钥到虚拟机.ssh/authorized_keys, 设置临时挂载点等等。
, h+ ^2 M* o% X- D7 h0 j2 S+ O
$ s, k @' R2 a; K! Rcloud-init 项目地址: https://launchpad.net/cloud-init; i4 h6 S9 ~ r* {% _" r
* a+ {2 Z; I0 U; x: V! {cloud-init 文档地址: http://cloudinit.readthedocs.org
6 P3 o7 [( M8 z
8 M5 q0 i8 E; V- C2. metadata元数据服务8 g" }: k$ b( r1 u& Z5 N0 D, H! w
7 N% z2 ?: x; ^
metadata字面上是元数据,是一个不容易理解的概念。在除了openstack的其他场合也经常会碰到。openstack里的metadata,是提供一个机制给用户,可以设定每一个instance 的参数。+ t8 `& T# g! o9 Z7 {' i
1 |! @' b- _. Q7 k0 h2 i+ ?* m
Amazon首先提出了metadata的概念,并搭建了metadata的服务,这个服务的公网IP是169.254.169.254,通常虚拟机通过cloud-init发出的请求是:1 _1 I- A) F+ R- s7 x. v K
9 Z/ L) d( A2 Z. e
http://169.254.169.254/latest/meta-data
7 G' R* @ F; s# P) U6 ]1 a: u# E$ z# ?* q
" y) A. e* O" u* r& N( [后来很多人给亚马逊定制了一些操作系统的镜像,比如 ubuntu, fedora, centos 等等,而且将里面获取 metadta 的api地址也写死了。所以opentack为了兼容,保留了这个地址 169.254.169.254。然后通过iptables nat映射到真实的api上。/ i& f) F; u0 N# G4 ^8 |' Z5 g
4 X& i! [3 {+ T( J; G% c( L
metadata在openstack中的BP: https://blueprints.launchpad.net ... nstack-api-metadata
* E7 T R/ T5 j
, P. |; K- b" K* g2 \: `0 W- F6 fnova中的metadata-server
# p! Z) Y8 @! h1 k3 }5 l+ F: J/ @, j" E) }2 {$ J7 j- q& f
metadata-server的具体实现是在nova-api组件中,nova.conf中与metadata有关的配置如下:
( d0 @* P+ g, |+ R& K" U. tenabled_apis=ec2,osapi_compute,metadata
5 [; ~+ v* O9 z" i; A7 F. c r
# N& p: T8 i' }: W+ p: h# OpenStack metadata service manager
8 {. [* E i, g* lmetadata_manager=nova.api.manager.MetadataManager
$ H1 D4 {: ] K0 I2 g8 {1 T4 P9 s
9 a" a8 p3 p0 f6 A% A# IP address for metadata api to listen( \! o: L+ r2 _2 `5 g
metadata_listen=0.0.0.0
8 z) _. h) Y9 O. n9 |* a$ O$ R; g# V7 e, P
# port for metadata api to listen
- `+ t0 \- A3 ]+ Y4 t" _ Q8 nmetadata_listen_port=8775
{. c6 |& }3 G# [' Y$ G5 u+ c" e( A0 [! @$ b1 B
# Number of workers for metadata service% c2 X& R4 b, n& [ g+ W
metadata_workers=9 I+ M, l$ ~- i2 }; ~
/ W% B P: i' s1 V, n2 e: S% v$ l8 K8 M
# 和neutron-metadata-agent 通信相关
/ P9 _ ~0 L0 }4 Zservice_neutron_metadata_proxy=True$ K# {/ B& s+ E8 r
neutron_metadata_proxy_shared_secret=) U# }; I' f) m, `
: q3 X) o1 O, x2 l, U# i' \6 M; y2 O- z3 F2 d. K+ k
具体的代码实现在 api/metadata 下:; _" P9 H- w) V: p) x# ^, b: F
3 a/ a9 f: W8 u) ]: u) |. S
metadata=metadata {6 t, t8 c: Z! M1 O' E
__init__.py% p Y5 U- s$ R. x3 O
base.py
" \' e4 j8 M G5 ] handler.py
4 f( ?+ Z( ?- b0 Y3 d password.py( S2 S. h$ I& w; @, x& s- c" T
vendordata_json.py0 i8 d9 ^: T+ B/ X
}, u: I* Z7 f0 i+ B
% I3 X; J, C5 m1 H1 v% ?5 a; g+ J" _* [7 T0 Y
与neutron的结合使用7 m* C7 y& O M8 I
通常我们使用neutron实现虚拟机的网络方案,neutron的metadata-agent并不会自己实现metadata服务,而是把cloud-init的请求转发给nova-api中的metadata服务,具体服务流程请看下图:
8 ~0 D+ C- ?/ Z 8 `: m5 H6 C" W# `+ S
$ E& C$ p6 L' C$ z) C. c
虚拟机通过cloud-init组件请求169.254.169.254这个地址的metadata服务,这时这个请求会有两种方式处理。
9 H; Q. u* U8 Y" u* Y9 y" N server" title="openstack中的metadata server" action-data="http%3A%2F%2Fs14.sinaimg.cn%2Fmw690%2F0000cGopgy6TdIm27252d%26690" action-type="show-slide" style="border-width: 0px; border-style: initial; list-style: none;">( Z3 @) f1 s& b) l, J' R
3 ^9 e. w3 F4 w0 q! w
0 s! ~& n( [ ?2 N% ?当虚拟机所在的子网拥有网关而且连接了l3-router,则通过qrouter的namespace中的iptables处理; 当虚拟机所在的子网没有网关,是个封闭的子网,那么dhcp服务的虚拟网卡会添加一个169.254.169.254的ip;% z: t8 q. y. b3 w/ \$ p
接收的cloud-init请求由ns-metadata-proxy处理,ns-metadata-proxy与metadata-agent通过unix domain socket实现IPC,实现将对ns-metadata-proxy的请求交给metadata-agent处理。
% ~" M! i3 ~7 ~# l; g8 y/ ?. X# o3 H0 p7 [metadata-agent接收请求,将请求交给metadata-server的真实实现者nova-api。
+ ?4 |& T" x' {3 z% w1 h7 ]
, u8 b8 Y# z/ ]0 F7 p, V( Q |
|