示例: import httplib import json import base64 tenant_id='xxx' token='xxx' compute_host="xxx" compute_port="8774" name="xzcloud" flavorRef="984017df-6cac-4020-8cdd-f284d89a331c" imageRef="45f8ac31-0c1c-4f7c-8144-0c561d4de98f" user_data="""#!/bin/bash env echo "export AAAAAA=1234567890" >> ~/.bashrc echo "export BBBBBB=0123456789" >> ~/.bashrc source ~/.bashrc env """ user_data = base64.encodestring(user_data) conn = httplib.HTTPConnection(compute_host+":"+compute_port) headers = {"Content-type":"application/json","X-Auth-Token":token} params = ({ "server": { "availability_zone": "nova", # 寫死 "name": name, # 虛擬機名字 "flavorRef": flavorRef, # 虛擬機規格ID,虛擬機預置之后提供 "user_data": user_data, # 虛擬機啟動之后需要執行的腳本,需要base64編碼 "config_drive": True, # 寫死 "imageRef": imageRef # 虛擬機鏡像ID,虛擬機預置之后提供 } }) conn.request("POST", "/v2/"+tenant_id+"/servers", body=json.JSONEncoder().encode(params), headers=headers) response = conn.getresponse() data = response.read() data = json.loads(data,encoding='UTF-8') print data
有的時候我們希望在boot虛擬機的時候能夠對虛擬機做些配置, 比如配置網絡, 寫入文件, 下載一些包並安裝等等, openstack中提供了實現這些的方法, 就是user-data 和Cloud-init。
user-data
在說user-data之前, 要先說下nova 的metadata api, 所謂metadata就是關於虛擬機的元數據,提供這個api主要是為了能夠在虛擬機啟動的時候能夠實現一些信息的初始化。
在虛擬機內部使用curl命令, 可以得到如下結果, 它們是表示不同版本, 每個版本中包含meta-data和user-data, meta-data 中是包括虛擬機的各種基本信息, 如ip,磁盤,內存,hostname,public key, 安全組等設置, user-data主要是做一些參數設置, 和一些腳本, 如python腳本, 當用heat boot虛擬機,可以看到這樣的user-data例子, user-data是能夠實現instance個性化定制的基礎, 它書寫的格式有很多, 詳細看cloud-init章節。
- $ 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
關於metadata的相關信息, 也可以詳細看EC2 文檔 Instance Metadata and User Data
Cloud-init
數據准備好, 完成最后action的工作就必須cloud-init出馬了, 它能夠把這些數據在虛擬機boot的時候執行起來。關於cloud-init相關介紹與其所使用的user-data格式, 請看Ubuntu Cloudinit。
接下來將實際使用這些技術做個測試。
保證能夠與nova metadata api連通
回到OpneStack本身,要把user-data使用起來,要先保證能夠在創建的虛擬機內部能夠連接到nova的metadata api IP 地址,metadata app IP 沿用了亞馬遜所用的169.254.169.254. 在OpenStack生產環境中, 我們是沒有這個IP的, 需要利用以下命令把到169.254.169.254的請求路由到nova的metadata api實際的監聽IP和端口上, 如下所示
- sudo iptables -t nat -A PREROUTING -d 169.254.169.254/32 -p tcp -m tcp--dport 80 -j DNAT --to-destination 10.11.0.16:8775
10.11.0.16 是metadata api listen ip address
注意兩個相關的配置項
/etc/nova/nova.conf
- metadata_listen=10.11.0.16
/etc/neutron/metadata_agent.ini
- nova_metadata_ip = 10.11.0.16
Nova boot :上傳user-data,並cloud-init注入數據
把我們需要的腳本、參數配置等等寫入文本文件, 通過--user-data 上傳到nova metadata server上,然后利用鏡像的cloud init注入數據, nova中語法為:
- nova boot --user-data /filepath/filename ...
首先找個已安裝cloud init包的鏡像,本文使用Fedora 20, 可以在http://cloud.fedoraproject.org/ 下載,
第一步:glance 創建image
- glance image-create --name F20 --disk-format=qcow2 --container-format=bare --is-public=true --file=Fedora-x86_64-20-20131211.1-sda.qcow2
第二步:創建user-data file
下面為user-data的一個例子, 為一段腳本,其他格式可參見文章末尾的參考資料
- #!/bin/bash
- echo "one test about user data" >>userdata
- chmod 777 userdata
- useradd -m me
- echo -e 'me\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
第三步:boot虛擬機, 注入初始化數據
注意:本例中利用--key-name參數傳入公鑰, 實現無密碼ssh, 用戶名為fedora,本例中root_key為一keypair,用nova keypair-add 添加。
- nova boot --key-name root_key --user-data ./user-data.txt --flavor 2 --image aad51d83-6398-4d18-89c8-5302993363b5 test_f20
第四步:ssh 進入虛擬機進行驗證
- [root@chen ~]# ssh fedora@10.20.1.33
- Last login: Thu Apr 3 02:07:24 2014 from 10.20.1.3
- [fedora@test-f20 ~]$ curl 169.254.169.254/latest/user-data
- #!/bin/bash
- echo "one test about user data" >>userdata
- chmod 777 userdata
- useradd -m me
- echo -e 'me\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
- [fedora@test-f20 ~]$ cat /userdata
- one test about user data
- [fedora@test-f20 ~]$ ll /userdata
- -rwxrwxrwx. 1 root root 25 Apr 3 02:07 /userdata
- [fedora@test-f20 ~]$ su me
- Password:
也可以check下/etc/sudoers
其他相關參考資料:
user-data的支持格式:https://help.ubuntu.com/community/CloudInit
OpenStack解決非UEC鏡像的虛擬機cloud-init不工作不能自動修改主機名稱不能注入user data
下面這篇文章講了如何以cirros為例安裝cloud init包,並使用的例子http://eccp.csdb.cn/blog/?p=68
file/meta/user-data注入數據http://docs.openstack.org/grizzly/openstack-compute/admin/content/instance-data.html#inserting_sshkeys
參考資料:
http://cloudinit.readthedocs.io/:http://cloudinit.readthedocs.io/en/latest/index.html
雲平台openstack中,cloudinit安裝使用:http://www.it165.net/os/html/201404/7848.html
用cloud-init制作的鏡像root無法登陸問題:http://linuxfun.me/?p=1552
Basic Hardening with User Data / Cloud-Init:http://openstack.prov12n.com/basic-hardening-with-user-data-cloud-init/
OpenStack Nova:虛擬機初始化user-data & Cloud-init:http://blog.csdn.net/juvxiao/article/details/22664457
CloudInit:https://help.ubuntu.com/community/CloudInit
OpenStack解決非UEC鏡像的虛擬機cloud-init不工作不能自動修改主機名稱不能注入user data:http://blog.csdn.net/networm3/article/details/8559504