cloud-init 就是一个运行在实例里面并用来初始化实例的一个框架. 它利用这些 cloud provider(e.g. CloudFormation, nova metadata service) 提供的信息在实例启动的时候初始化该实例。比如,可以用来设置主机名,密码,SSH key等等,它的行为可以通过user-data设置。可以在创建云主机的时候通过–user-data或者–user-data-file指定。
metadata就是关于虚拟机的元数据,提供这个api主要是为了能够在虚拟机启动的时候能够实现一些信息的初始化。由openstack-nova-api负责监听8775端口。
OpenStack里,由于镜像(image)操作系统一般都装有cloud-init,所以在启动虚机的时候,会发现虚机去访问169.254.169.254这个地址,尝试获得metadata信息。
一旦虚拟机launched,User-Data在虚拟机运行过程中无法进行修改,且仅适用在launch阶段,后续的重启都不会运行。
要把user-data使用起来,要先保证能够在创建的虚拟机内部能够连接到nova的metadata api IP 地址,metadata api IP 沿用了亚马逊所用的169.254.169.254。
在虚拟机内部使用curl命令, 可以得到如下结果:
$ curl 169.254.169.254
1.0
2007-01-19
2007-03-01
2007-08-29
2007-10-10
2007-12-15
2008-02-01
2008-09-01
2009-04-04
latest
它们是表示不同版本, 每个版本中包含meta-data和user-data, meta-data 中是包括虚拟机的各种基本信息, 如ip,磁盘,内存,hostname,public key, 安全组等设置, user-data主要是做一些参数设置, 和一些脚本, 如python脚本。
Metadata API IP为169.254.169.254,这个IP在OpenStack中实际上是不存在的,最早metadata的概念由亚马逊提出,后来很多人给亚马逊定制了一些操作系统的镜像,比如 ubuntu, fedora, centos 等等,而且将里面获取 metadta 的api地址也写死了。所以opentack为了兼容,保留了这个地址 169.254.169.254。然后通过iptables nat映射到真实的api上。
首先要确保虚拟机装有Cloud-init。它的作用是把User-Data在虚拟机boot的时候执行起来。
Command:
通过–user-data或者–user-data-file指定。
e.g.
#cat /root/user-data
#!/bin/bash
passwd root << EOD
123456
123456
EOD
#nova boot --flavor --image --user-data-file /root/user-data
Dashboard:
可在虚拟机创建的界面直接输入user-data内容。
虚拟机启动后,打开虚拟机终端,验证root密码有没有被修改。
六、问题及解决方案
如果虚拟机内部使用curl命令无法连接169.254.169.254,请按照如下步骤进行排查。
前提是虚拟机正常启动而且有分配IP。
1.检查端口
# netstat -anp|grep 8775
如果端口没有监听,则查看openstack-nova-api有没有启动。
2.检查配置文件
Controller & Compute node
/etc/nova/nova.conf
# The IP address on which the metadata API will listen.
# (string value)
metadata_listen=0.0.0.0
# The port on which the metadata API will listen. (integer
# value)
#metadata_listen_port=8775
# The IP address for the metadata API server (string value)
#metadata_host=$my_ip
# The port for the metadata API port (integer value)
#metadata_port=8775
# Set flag to indicate Neutron will proxy metadata requests
# and resolve instance ids. (boolean value)
service_metadata_proxy=True
# Shared secret to validate proxies Neutron metadata requests
# (string value)
metadata_proxy_shared_secret=abcdefgsecretkey
network node
/etc/neutron/metadata_agent.ini
nova_metadata_ip=$CONTROLLER_IP
nova_metadata_port=8775
metadata_proxy_shared_secret=abcdefgsecretkey
/etc/neutron/l3_agent.ini
metadata_port=9697
3.由于虚拟机到169.254.254.254的路由是通过qrouter namespace内的iptable进行转发的,检查qrouter namespace里的iptables设定:
1)找到虚拟机使用的路由的namespace
[root@network1 ~]# ip netns list
······
qrouter-1a2b3c4d-5e6f-1a2b-3c4d-1a2b3c4d0617
#路由对应的namespace
······
2)查看路由fip_test的namespace的iptables规则,是否有重定向
[root@network1 ~]# ip netns exec qrouter-1a2b3c4d-5e6f-1a2b-3c4d-1a2b3c4d0617 iptables -L -t nat
······
Chain neutron-l3-agent-PREROUTING (1 references)
target prot opt source destination
REDIRECT tcp -- anywhere 169.254.169.254 tcp dpt:http redir ports 9697
#将对169.254.169.254访问重定向到本地端口9697
······