找回密码
 注册
查看: 5185|回复: 6

cloud-init制作Centos7镜像

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2017-11-2 19:32:49 | 显示全部楼层 |阅读模式
一、环境说明
* Y! Q# \9 `* M/ _+ X你需要准备一台KVM机器,用于制作初始的centos7镜像。建议最终将ISO镜像转为QCOW2。
二、配置好网络
% q) k6 w3 f' Q- r0 H9 oISO镜像的centos7系统刚装好,网络可能不通,所以要检查网络。 ) R' r( Q' x$ z& V0 u/ M' o
ping 外网检测
  • 1: X, L3 Y7 W( j& \9 [
如果未能ping通,请依次检测ip,route
# vi /etc/sysconfig/network-script/ifcfg-eth0
  • 1. U. u# l) ^. [  v1 p
可以先将dhcp动态分配IP改为静态IP
#cgls #BOOTPROTO=dhcpBOOTPROTO=staticIPADDR=172.16.5.133GATEWAY=172.16.1.1NETMASK=255.255.0.0ONBOOT=yes
重启网卡使其生效
# service network restart
  • 1( R& Z6 E" R0 J; y, h8 R( F4 F# ~) Q
检查路由
# route -n
Kernel
IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface0.0.0.0         172.16.1.1      0.0.0.0         UG    100    0        0 eth0169.254.169.254 172.16.88.100   255.255.255.255 UGH   100    0        0 eth0172.16.0.0      0.0.0.0         255.255.0.0     U     100    0        0 eth0
如果你缺失第一个路由,是肯定无法ping通外网的这里写代码片 ; H& P. s6 b% f! `# F) N
添加dns
# vim /etc/resolv.conf
nameserver
114.114.114.114nameserver 8.8.8.8
  • 24 k9 A1 M  l: ~0 T) G, h6 w7 j
添加路由
# route add default gw 172.16.1.1
  • 1
    ) c; p" a0 E' y, X: q. |2 k4 R
试一下ping百度
成功之后我们可以开始下一步操作。
三、安装相应的包
! ^* ~& M% |) U+ X安装ACPI服务 & W  I- W5 W! i1 l- i4 z3 E* B
这个服务是控制重启和关闭实例
# yum -y install acpid
# systemctl enable acpid
配置获取元数据 . K& t4 x1 I. g2 ]6 D
一个实例必须与元数据服务进行交互任务后再启动。 例如:必须得到实例 ssh公钥并运行脚本的用户数据。 为了确保实例执行这些任务,推荐安装一个cloud-init包。
- m" G! e9 i) Y. t  h+ z0 c* A使用cloud-init获取公钥,cloud-init包将从元数据服务器和一个帐户的关键的地方自动获取公钥 。 1 U. t! q6 N2 E6 v' c; \
安装cloud-init。
# yum -y install cloud-init
cloud-init通过编辑/etc/cloud/cloud.cfg,对镜像进行定制。我们现在暂时不修改这个文件,将其他配置弄完再进行定制。
安装cloud-utils-growpart允许分区调整
# yum -y install cloud-utils-growpart
实例需要访问元数据服务, 必须禁用默认zeroconf路线。
# echo "NOZEROCONF=yes" >> /etc/sysconfig/network
配置控制台 3 \( q, P; F1 g! q$ h; B7 h+ m
如果希望在仪表盘界面查看nova控制台的日志,需要做以下配置:
# vi /etc/default/grub
修改GRUB_CMDLINE_LINUX为以下内容
GRUB_CMDLINE_LINUX="crashkernel=auto console=tty0 console=ttyS0,115200n8"
保存更改
# grub2-mkconfig -o /boot/grub2/grub.cfg
出现以下内容,配置结束。
Generating grub configuration file ...Found linux image: /boot/vmlinuz-3.10.0-229.14.1.el7.x86_64Found initrd image: /boot/initramfs-3.10.0-229.14.1.el7.x86_64.imgFound linux image: /boot/vmlinuz-3.10.0-229.4.2.el7.x86_64Found initrd image: /boot/initramfs-3.10.0-229.4.2.el7.x86_64.imgFound linux image: /boot/vmlinuz-3.10.0-229.el7.x86_64Found initrd image: /boot/initramfs-3.10.0-229.el7.x86_64.imgFound linux image: /boot/vmlinuz-0-rescue-605f01abef434fb98dd1309e774b72baFound initrd image: /boot/initramfs-0-rescue-605f01abef434fb98dd1309e774b72ba.imgdone7 `4 `) F3 @9 ?" E& Z$ E+ h1 j
三、进行定制 6 e) P5 Z1 ?% _6 k8 ^* Y( y
修改配置项,修改之前说两句。
3 H# N2 C. w" x& k: i% t; {3 `% ^阅读cloud-init官方文档,读几遍,确保你知道你在配置些什么,以及这些配置项是如何生效的,模块频率是怎样。 * V* \! G& t1 t6 w% a: _* \
Users and Groups模块的模块频率是每个实例执行一次,也就是说你制作的镜像起了云主机之后,再修改这个模块配置重启机器是不再生效了。
  j+ f% h$ o7 m* |与Users and Groups模块的模块频率相似的还有Write_files、Set Passwords模块。 / k; b* V; r: X1 m6 \% e
Bootcmd模块的模块频率是每个实例可以执行多次,也就是说,起了云主机之后,再修改这个模块配置重启机器之后也会生效。
- d4 b1 I+ z! k' M, ?与Bootcmd模块的模块频率相似的还有Runcmd。
vi /etc/cloud/cloud.cfg
将locale_configfile: /etc/sysconfig/i18n之前的配置替换为以下内容。
groups:  - centosusers:  - name: demo    expiredate: 2016-09-01    groups: centos    homedir: /home/bh    lock_passwd: false    passwd: $6$dfdfsdsf$y9obLvZMtAb.uWTIU1OTrZqZImHvCCs01ntDFwO0DnfFxXtgaLq2YoMK6yJ0KjfI260DH0Pv7T6Sj9TXVuUag0  - name: root    ssh_authorized_keys:      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDYbA+xgxzm3pySQfW6oh7yr4xYD6n6T/upHuWAdVp/sU2ukeoDU/U6qPBpJuMVRzfaT6pyJEgK7gknaKu/GZxMfnA/9Dt5JJln6PmstWZoWclmxvS7MPCqeL0+ESFvMx64UZFIePbClb5kh1UFggQ5WwDvAIC+1HysI3qGOIZ/RoYUrOHNdgQJzV8xcpWLeDKF2MBNQt/Pyzl+WLxoTN6cd4XlrA9E729t8OwrK5mvTe9CUpWKYELGV6bfqNLGNcUT5LYx9tqyanB4KA1eBC5/9MhBjGeO+EcsQv6zooVJTIAE65XmCEib4WukQcUTr8Td7+6+wMY9463us2OrVVw7bootcmd:  - echo 123321 >> /root/bootcmd.logwrite_files:  - encoding: b64    content: CiMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4...    owner: root:root    path: /etc/sysconfig/cjm    permissions: '0644'  - content: |      # My new /etc/sysconfig/samba file      SMDBOPTIONS="-D"    path: /etc/sysconfig/cglsruncmd:  - [ sh, -c, sh /root/bootcmd.sh ]  - [ sh, -c, echo "=========hello world'=========" >> /root/runcmd.log ]ssh_pwauth: yeschpasswd:  list: |    root:cjm123  expire: False  preserve_hostname: flasefqdn: qwehost.localhostname: qwehostmanage_etc_hosts: true
6 b+ U5 ?" \5 ^# P0 [8 \; M! o0 q+ k, ^/ F" k; f9 o' }& N
复制过去的时候注意格式问题。
0 A+ r% S+ v  N9 K: B. X8 Z注意格式问题:
% O7 H9 \/ B/ T8 u/ E" D( q1 ]& T1.确定空行一致性,统一以空2格作为区分。 / r& [+ U2 H% C) w% @: G
2.冒号后空一格
9 n5 q5 @# h# i0 g8 }" K3.写多行需要按照yuml语法编写 1 z, j8 |: S+ \$ }3 `
如果格式出了问题,你配置的cloud-init将全部失效。
解释配置: / u  S& t5 t0 e! \; B* r& Q
1.配置了用户组
groups: - centos
2.配置用户,创建了demo用户,设置了过期时间,所属用户组,用户目录,以及是否开启密码登录,并为其设置了密码。 ' W/ l% b+ ^) t9 t% f4 L: R
为root用户,设置了ssh免密码登录,附上了公钥。
6 t$ H/ w6 L5 v/ v密码是通过加密的产生的,生成命令为:
# python -c 'import crypt; print crypt.crypt("cgls", "$6$dfdfsdsf")'
在需要免密码登录的机器上执行下面命令,产生密钥对。
# ssh-keygen -t rsa
将公钥内容复制到配置中
cat /root/.ssh/id_rsa.pubusers:  - name: demo    expiredate: 2016-09-01    groups: centos    homedir: /home/bh    lock_passwd: false    passwd: $6$dfdfsdsf$y9obLvZMtAb.uWTIU1OTrZqZImHvCCs01ntDFwO0DnfFxXtgaLq2YoMK6yJ0KjfI260DH0Pv7T6Sj9TXVuUag0  - name: root    ssh_authorized_keys:      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDYbA+xgxzm3pySQfW6oh7yr4xYD6n6T/upHuWAdVp/sU2ukeoDU/U6qPBpJuMVRzfaT6pyJEgK7gknaKu/GZxMfnA/9Dt5JJln6PmstWZoWclmxvS7MPCqeL0+ESFvMx64UZFIePbClb5kh1UFggQ5WwDvAIC+1HysI3qGOIZ/RoYUrOHNdgQJzV8xcpWLeDKF2MBNQt/Pyzl+WLxoTN6cd4XlrA9E729t8OwrK5mvTe9CUpWKYELGV6bfqNLGNcUT5LYx9tqyanB4KA1eBC5/9MhBjGeO+EcsQv6zooVJTIAE65XmCEib4WukQcUTr8Td7+6+wMY9463us2OrVVw73.Bootcmd只用于在引导过程之后不能做的时候再使用bootcmd:  - echo 123321 >> /root/bootcmd.log
4.写文件,第一个是加密之后的内容,第二个是正常内容。
write_files:  - encoding: b64    content: CiMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4...    owner: root:root    path: /etc/sysconfig/cjm    permissions: '0644'  - content: |      # My new /etc/sysconfig/samba file      SMDBOPTIONS="-D"    path: /etc/sysconfig/cgls
5.与bootcmd类似,可在引导之后使用
runcmd:
  -
[ sh, -c, sh /root/bootcmd.sh ]
  - [ sh, -c, echo "=========hello world'=========" >> /root/runcmd.log ]
6.设置root用户密码
ssh_pwauth: yes
chpasswd:
list: |
    root:cjm123
  expire: False  
最后就是修改静态IP为dhcp动态获取了
# vi /etc/sysconfig/network-scripts/ifcfg-eth0 #cgls BOOTPROTO=dhcp#BOOTPROTO=static#IPADDR=172.16.5.133#GATEWAY=172.16.1.1#NETMASK=255.255.0.0ONBOOT=yes
关机
# poweroff
四、开启云主机 & n: O$ I  u1 ?7 q; {
上传镜像到openstack上
# openstack image create "centos7_init" --file centos7.0-3.qcow2 --disk-format qcow2 --container-format bare --public
控制台界面中自己开启云主机,可以看到自己定制的centos7有没有成功了。
& H. h9 x9 q5 Y4 `' ]# N
& U1 |) u: d9 ?' z6 {6 |/ S

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2021-11-3 09:57:18 | 显示全部楼层
按照使用启动实例向导启动实例中介绍的实例启动过程操作,但在进行到该过程中的步骤 3:配置实例详细信息 时,在 User data (用户数据) 字段中输入 cloud-init 指令文本,然后完成启动过程。5 J. `+ ?1 H0 y. s9 I4 d$ w) D

4 u1 y- u6 h% J! d( n, ?在以下示例中,这些指令在 Amazon Linux 2 上创建并配置 Web 服务器。要将命令标识为 cloud-init 指令,顶部的 #cloud-config 行是必需的。
  s4 i; o1 d9 Q) |( [! A7 e( i3 m- P$ d6 k
#cloud-config
1 A1 ~2 d/ Y  _& urepo_update: true7 M- ]5 m$ E, H5 H! k  a+ U; F
repo_upgrade: all
1 a" N: g/ Z/ t2 e8 C# j& d- C. b0 @) B; d4 P8 f! _
packages:; U) b: e  e+ p& T) q
- httpd
0 S( f! P' J* S* P0 V! p - mariadb-server$ [- Z" h, v/ l8 h+ v! M# o

* _: o2 Z, S4 ]' R5 gruncmd:
/ V2 ?) E' b7 z9 r - [ sh, -c, "amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2" ]
+ L! K! s" E" @8 @5 {$ J- b - systemctl start httpd
- k8 ?, k5 l4 q3 c; D - sudo systemctl enable httpd
* P& c* Y8 j9 @  d3 H7 u$ F3 @ - [ sh, -c, "usermod -a -G apache ec2-user" ]
& _5 I0 I" R% P - [ sh, -c, "chown -R ec2-user:apache /var/www" ]
/ u4 X5 f1 m! f$ R" _ - chmod 2775 /var/www
# k0 C5 {8 J2 [' Z+ e% u - [ find, /var/www, -type, d, -exec, chmod, 2775, {}, \; ]7 k; z/ k7 S: X8 D
- [ find, /var/www, -type, f, -exec, chmod, 0664, {}, \; ]
! }9 \7 A8 y. G" x5 Z; m - [ sh, -c, 'echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php' ]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2021-11-25 14:21:22 | 显示全部楼层
entos 7实例,连接多个接口。之前说过路由冲突引起的问题。
) i5 F$ t6 j9 o/ t
% V% M* z: M. Z9 m" ]- W这次碰到的是由于接口分离再连接导致的网卡索引号问题。(索引号改变和串网卡)
, M5 I7 |+ G+ y- f! t$ V% ^
0 H9 X: e$ E# x  k6 x3 X* N/ g问题分为两种: L7 f1 t& J+ P( i0 B4 S4 L

5 P# u# o# k  h- ]# I1、接口分开再连接,网卡名没变,但是通过ip a命令查看,可以看到网卡的网卡索引号改变了。8 t# B; m2 s, v  J- o
# ?4 U. ~, r. J9 G, C
网卡索引号,累加,添加了一个当前最大索引号加1的网卡。ip a可以看到分离再添加的网卡排到了最后。
$ W/ ~% n- n1 z, O4 ]' l' ]8 q' k0 \3 L' n& u/ h, `
通过网卡索引号,来识别网卡的程序,碰到了问题。% B! Y# W, v9 ^8 O) Z
; O- c  _6 g+ O' A# y5 o  f
此时我改为使用通过网卡名,来获取索引号的方式,来识别网卡。使应用程序正常工作。! d5 m$ E& b& F5 @5 g& n

5 ?5 a; m* ~" N8 b, m+ \7 a: ?
8 N% D/ }6 ~" z2 h8 J5 e1 Y3 K
4 b9 E) d2 @% P, ]5 K1 z6 z& m3 c2、接口分开再连接,关闭实例之后,再开机,出现串网卡的问题。
8 \7 q4 s+ q5 {2 K5 R; i% L3 t+ {3 q: _8 Y) e7 U2 q: f
reboot不影响,不会产生串网卡问题。实例内部使用ip a查看IP地址和mac地址,  D# O$ d$ e' u2 J, @, Q9 E* H* n
1 z3 L% x( O# p2 h2 h" \
对应所挂网络,发现分开再连接的网络接口,变成了最后一块网卡。
$ H4 s( W* m1 h  F! x# w: T" |" G* Y! L! R
查找资料,发现,centos实例开机加载网卡的顺序保存在openstack的nova数据库instance_info_caches表中。: l2 o; c2 d; ?) i! P
0 A" k; ]; ^7 V) R
每次重挂网络时,改变表中network_info字段顺序,即可。  a( h: m8 k4 W' m- b3 ]

9 h0 d' \6 t7 C& C% \此字段为json格式。. b& _' G+ t4 D4 a( M  l8 C9 T
, |" e: K  e3 F7 I# ?* |
[{"profile": {}, "ovs_interfaceid": "ce6a61ff-15b9-4102-9ba8-1755ad4840a1", "preserve_on_delete": false, "network": {"bridge": "br-int", "subnets": [{"ips": [{"meta": {}, "version": 4, "type": "fixed", "floating_ips": [], "address": "192.168.1.10"}], "version": 4, "meta": {"dhcp_server": "192.168.1.2"}, "dns": [], "routes": [], "cidr": "192.168.1.0/24", "gateway": {"meta": {}, "version": 4, "type": "gateway", "address": "192.168.1.1"}}], "meta": {"injected": false, "tenant_id": "40026f6973464ee9a19ad04f6221e213", "mtu": 1500}, "id": "d6fcefec-8216-4c24-a8a5-fa32c498d615", "label": "network_7260"}, "devname": "tapce6a61ff-15", "vnic_type": "normal", "qbh_params": null, "meta": {}, "details": {"port_filter": true, "datapath_type": "system", "ovs_hybrid_plug": false}, "address": "fa:16:3e:6e:34:44", "active": true, "type": "ovs", "id": "ce6a61ff-15b9-4102-9ba8-1755ad4840a1", "qbg_params": null}]0 Y7 c% ^2 Y& p0 D) r
1.
- B  P+ }# [6 }- ~1 L0 ~/ {5 G将其装换后,修改顺序,就能回去之前顺序。
4 V; d# _$ P" c6 N  @* f6 t6 W6 L# b$ R( ]7 P
+ X# h5 h/ M4 q

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2021-11-25 15:25:13 | 显示全部楼层
执行如下命令,进入/etc/sysconfig/network-scripts/文件夹:/ V/ q9 s9 h- [3 N: l7 i' z
cd /etc/sysconfig/network-scripts/0 N7 ]- Z6 a; {5 |; b
根据实际情况创建新网卡的配置文件,如下以创建命名为 ifcfg-eth1 的配置文件为例 :
6 E1 h# d' i  u9 v3 n& X输入命令:
6 h7 f8 S2 X# j- l6 `cp ifcfg-eth0 ifcfg-eth14 K' @  \' I! b1 D" {; U
输入命令修改配置文件内容:! {8 v' v) f. Q: Z( q
    vim ifcfg-eth1
$ ?; f* \! b7 _# `8 y按 “i” 切换至编辑模式,把配置文件内容修改为以下内容:6 l; ]/ I% b9 M5 x+ I
DEVICE='eth1' # 此处填写步骤1中查看到的需配置的弹性网卡名称,请根据实际填写6 R4 |! p+ E5 h" {8 ~1 ~
NM_CONTROLLED='yes'+ q2 F$ B" ?& K9 G: ?
ONBOOT='yes'
# D! |9 W' j2 b) d # 配置主ip7 f8 L" {+ q, f! P6 h  v1 Q' i2 |0 e
IPADDR0=10.0.0.7 # 此处填写步骤一:添加辅助网卡中手动填写的主 IP,请根据实际填写
" q1 [& w0 K  W% m+ A+ }NETMASK0=255.255.255.0 # 此处填写步骤三中所记录的子网掩码,请根据实际填写' g7 M/ H3 _' y0 J$ Z" G& x& i, o
# 配置辅助 ip1" D$ N5 ]8 c) [+ X; T6 s( Y9 u) f0 a1 U
IPADDR1=10.0.0.8 # 此处填写步骤一:添加辅助网卡中手动填写的辅助 IP,请根据实际填写
% w% a+ Z0 s; uNETMASK1=255.255.255.0 # 此处填写步骤三中所记录的子网掩码,请根据实际填写- S( I; e- q0 v% g3 }. a: g
#GATEWAY='192.168.1.1'  # 因为 eth0 文件定义了网关,这里不再写网关,避免网关冲突,请根据实际填写
( L' V* Z# t% B+ W修改后,示例如下:
8 t( j9 v7 O( m6 A* q+ m! U0 z
9 f- j- {; {5 k; R! Q修改后保存配置文件并退出(在 vim 的末行模式下按 “Esc”,输入 “wq!” 并回车)。$ k* F* C+ k2 h2 ]
输入如下命令重启网络服务。
  W4 J! H) j% n# c$ Y. a0 Dsystemctl restart network) T7 g4 G1 l# x3 f  F4 i$ n; O; v
检查和确认 IP 配置正确。4 e, |8 @- |3 V* N
输入如下查看 IP 的命令。/ B6 @: D8 K  M- O1 r
ip addr
4 n; J8 w% P) B, l0 O. k4 l确认辅助网卡和辅助网卡上的 IP 可见,如下图所示。$ O& ?% t1 ~" _

5 N5 Y. p; P4 C; Q# F# W如果 IP 配置不正确,请执行如下检查:
  v4 H7 ?1 N) Q! Q( l7 U/ S0 @检查配置文件是否正确,如不正确请重新配置。
% c0 V3 b. j- y1 C. R9 M检查网络是否重启,如未重启,请执行如下命令重启网络,使配置生效。
  K& y1 d* N: S1 w' H  b* xsystemctl restart network- C% `7 N. k1 z4 {2 w4 n( H$ J
根据业务实际情况配置路由策略。6 V# I0 K9 ]3 _) Y4 ~+ v
按照上述步骤配置好后,Linux 镜像依旧默认从主网卡发包。您可通过策略路由来指定报文从某个网卡进,并从该网卡返回。& s. r5 u7 d- G6 |9 y$ M& f
创建两张路由表。+ a3 A" l9 \" n6 D! ^/ b" {
echo "10 t1" >> /etc/iproute2/rt_tables
8 l1 q/ y1 |1 yecho "20 t2" >> /etc/iproute2/rt_tables
6 I0 v4 z# V9 ]6 k* A: D+ t说明
( s$ Y  B$ {; z' Q1 G& D此处10、20为自定义的路由 ID,t1、t2为自定义的路由表名称,请根据实际填写。
. c7 @8 g7 f; F0 K0 a7 j1 o, c  g( F/ d
给两个路由表添加默认路由。. J2 X/ a+ D7 m4 y7 X9 B' m
ip route add default dev eth0 via 192.168.1.1 table 105 I2 q) ^. q9 d6 \, ^
ip route add default dev eth1 via 192.168.1.1 table 20
9 c. x( M- S% h1 |: @说明; w8 l1 i- n& _. o5 A
此处两个命令中,192.168.1.1要分别替换成主网卡所属子网的网关,以及辅助网卡所属子网的网关。1 [0 B' N* @5 D, B! U

' P# }+ m5 ]0 e8 t; i配置策略路由。+ _" l% r( _! G. E- X+ H. q
ip rule add from 192.168.1.5 table 10
3 X! W9 E! N6 n0 x) {8 W2 t% q1 cip rule add from 192.168.1.62 table 20
& n  o! Z; X) W$ ^6 t说明6 G. r# T4 Z1 H" ?, ^; L/ s5 \
此处两个命令中,IP 要分别替换成主网卡上的 IP,以及辅助网卡上的 IP;10和20为 步骤6.1 中自定义的路由 ID,请根据实际情况填写。- S# S7 I4 b, Q7 ~) P7 m
配置完成后,可用同一个子网下的 CVM,来 Ping 内网地址,能 Ping 通即说明配置成功。如无其他 CVM,可以给辅助网卡的内网 IP 绑定公网 IP,Ping 该公网 IP 来验证。! P2 a) R2 F3 u) L: m1 j( r
此处配置的是临时静态路由,网络重启后需要重新配置路由,如希望网络重启后路由不丢失,可再执行 步骤7 将路由配置持久化。9 C3 \4 G( R; Q# k& k
(可选)配置永久静态路由,即:将路由配置持久化写入文件,可确保网络重启后路由不丢失。9 q  G7 Q  x# ?% t# _: J3 s
执行如下命令,进入配置文件。
! }9 q! U3 `/ v1 D  d# q& Dvi /etc/sysconfig/network-scripts/route-eth1   ( D( C: f  m& Q. d3 C; N
按 “i” 切换至编辑模式,并进行如下配置。
  v% J  f1 L/ {% y: }0.0.0.0/0 via 192.168.1.1 dev eth0 table 10
' h, F1 ^/ Z5 Q! y2 p" D0.0.0.0/0 via 192.168.1.1 dev eth1 table 20- `$ m4 _) o9 q+ P) n' P
按 “Esc”,输入 “:wq”,保存文件并返回。

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2021-11-25 15:33:11 | 显示全部楼层
执行网卡多队列的配置脚本. b6 [* B8 @( G) ]' d2 g* u) p0 O
Windows操作系统暂未商用支持网卡多队列,如果对Windows操作系统镜像添加网卡多队列标签,开启网卡多队列功能,可能会引起操作系统启动速度变慢等问题。" Y. z. N7 v/ J& A. V, W

9 I  E% G% p* @: L* H针对Linux操作系统,我们提供了自动开启网卡多队列功能的配置脚本。如果弹性云服务器有多张网卡,执行配置脚本后,所有网卡均会自动开启多队列。3 |( x( V5 o9 m& B# W

+ q$ y5 e0 H1 v- A- c3 G登录弹性云服务器,查看网卡支持和已开启的队列数。% K! M1 {9 e# B6 s; o+ j8 H) C& D8 u
ethtool -l 网卡" G5 t$ r" u+ q; @3 m" p

) F! n0 _3 i8 a1 e& L示例:
, r! w, N- O, x3 ?% _
9 a7 A5 c' E: R5 A[root@localhost ~]# ethtool -l eth0   #查询网卡eth0的队列数* q( z6 v3 D+ ]% D" ]; T8 m2 z
Channel parameters for eth0:
+ m( Y# F0 h2 N. `Pre-set maximums:
. e% a0 w9 V1 |8 z' |+ @2 LRX:               0: W4 I; F7 ~/ `: H
TX:               0
7 m! y# `8 V( xOther:            0
; ^& u) c5 f" t, _/ q. O, [Combined:         4   #表示此网卡最多支持设置4个队列
/ C& _" t3 y/ g( p% N+ |Current hardware settings:% p' w! ]- a! j" E4 D1 R5 w
RX:               0
: M) ^' d% B+ I* h) QTX:               03 b+ ]8 v3 i, c7 L: H, E0 ?$ o. S
Other:            08 t5 s* i3 a5 ?4 s/ \
Combined:         1   #表示当前已开启的是1个队列
9 T7 f* X1 ]) \# n0 ^4 o) ?& u
" B0 ~" o  `) y" K+ D# ?) n1 ^如果返回信息中,两个“Combined”字段取值相同,则表示网卡已开启多队列,无需执行以下操作。
$ @8 l9 H% \6 ^; I# X7 C1 U
7 b  p6 z  s& ], b* [5 i( ^2 e& R执行以下命令,下载配置脚本“multi-queue-hw”。9 J' s: t  ~4 _% M* F
wget https://ecs-instance-driver.obs. ... .com/multi-queue-hw
9 s' U! O. v8 {1 d, N! w0 m9 B$ `# J
其中,下载地址为:https://ecs-instance-driver.obs. ... .com/multi-queue-hw
% L) L; o3 v' H# H' e! Y* p! o* h5 W2 z. }  r8 E" s( L
执行以下命令,添加执行权限。
5 Q: G$ _$ [8 W2 fchmod +x multi-queue-hw1 H7 v- `- e1 ]( v/ ~4 A, [
3 O; ~2 k7 S- }9 I- F
执行以下命令,将脚本“multi-queue-hw”放到目录/etc/init.d下。
) `" V3 [8 p5 A2 v+ q+ Cmv multi-queue-hw /etc/init.d
' k- ]7 H! P- ~  e* d
0 A0 |% T: i& a% |; J, n. s如果出现如下提示信息,请输入“y”。
- D$ ^& ~5 E4 r; s' B" r7 o. s
8 |( D( w6 b0 s8 e& a: P8 x' m" O6 Z7 smv: overwrite '/etc/init.d/multi-queue-hw'?/ O8 P1 \# N* o$ t1 W

/ E7 A5 x$ w0 s; p1 I9 o% C执行以下命令,运行脚本“multi-queue-hw”。
" m; E1 d/ y2 H/etc/init.d/multi-queue-hw start& Q; ]& S3 P( L

2 W3 ]5 J( S7 J/ i  Q运行脚本后,立即生效。但关机弹性云服务器后,网卡多队列功能将自动失效。
2 q; F6 ]: D- ~0 c/ Z/ {  o$ q( e: l, y
为了使网卡多队列功能开机自动生效,各个OS需要增加开机启动配置:
# e: I# l1 m+ V* w$ {& A5 H5 K" jCentOS/Red Hat/Fedora/EulerOS/Suse/openSUSE使用如下命令,增加开机启动项,使网卡多队列配置开机:: U3 |1 \' S: |+ z# J5 q
chkconfig multi-queue-hw on
! n/ v$ e+ V5 C& K
6 D) J3 A: V+ q* {( [Ubuntu使用如下命令,增加开机启动项:1 v1 G: [" w- V: e# }- z
update-rc.d multi-queue-hw defaults 90 10# w: M" d6 x* }1 U9 q3 c

: f2 u5 m& j$ f% ?Debian使用如下命令,增加开机启动项:8 y' b( D2 x' g. d
systemctl enable multi-queue-hw

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2021-11-25 15:59:38 | 显示全部楼层
在上一篇文章构建 Openstack 镜像的环境搭建中我们介绍了如何在自己的笔记本或台式机上搭建一个可以用于制作 Openstack 镜像的环境,本文我们将利用这个环境,以制作 CentOS7.1 镜像为例,介绍手动制作 Openstack Linux 镜像的详细步骤。5 ?, c. D  c# {, P
下载镜像
1 |. M9 b4 e% G! |( [访问镜像下载地址,进入后选择版本为 7.1.1503,在 isos 目录下下载 x86_64 的 Minimal 镜像,并上传到/tvm 下。如果网速不给力,最好不要选择下载 Netinstall 镜像,因为这会在安装时联网下载大量的软件包,重新安装时需要重新下载这些软件包。" w2 _4 H) ?- G" z' l2 J
创建虚拟机$ O: W9 g2 i2 {1 I9 i- e
首先创建一个 raw 格式镜像文档,用于虚拟机的根磁盘,大小 30G 就够了。(镜像文档大小可根据实际情况自行调整,此处以 30G 为例)
  `. [- T: B, w. d) u1
  B, U3 c- z. }2
4 Y- O' |+ ^# B" ^8 ~; E( vcd /tvm/0 i6 e9 Q& y" h) F) s2 V
qemu-img create -f raw CentOS7.1.raw 30G
' U" i3 h8 i: N1 t; `7 _修改/tvm/templates.xml,将图中红色方框处改成虚拟机镜像文档所在绝对路径,并指定相应 ISO 文档绝对路径。
2 f7 x# k$ a' i+ f" _/ E7 [! f2 H2 [+ L6 l1 ]' `- T- ]
启动虚拟机
) o0 z- U: G& F: x15 z+ @4 c0 [$ t6 g& }
25 k) ~) n2 W) X
cd /tvm/6 _1 l( \$ I. X1 {/ K6 B+ l* T, A
virsh create templates.xml
9 a7 A7 D$ B; u/ C1 M0 z启动完成后,使用 vnc client 连接到虚拟机控制面板。
( \5 \5 L8 N' ?+ S- v安装 OS
$ s9 E6 |3 p0 L, a! i9 C! g. j( s- S进入虚拟机控制面板可以看到 CentOS 的启动菜单,选择 “Install CentOS 7”,继续选择语言后将进入 INSTALL SUMMARY,其中大多数配置默认即可,时区选择 “Asia/Shanghai”,“SOFTWARE SELECTION” 选择 “Minimal Install”,“INSTALLATION DESTINATION” 需要选择手动配置分区,我们只需要一个根分区即可,不需要 swap 分区,Device Type 选择 Standard Partition(务必选择此选项,因为 cloud-init 只支持标准分区的自动扩展),文档系统选择 ext4 或者 xfs,存储驱动选择 Virtio Block Device,如图:6 r! h# G! E  r, n- n7 e
7 u; N% B2 V5 g8 V  a# K
' B0 T8 e% h% F3 l
7 t/ F. N5 r  [! p8 L
配置完成后就可以开始安装了,在 CONFIGURATION 中设置 root 用户密码。大约几分钟后,即可自动完成安装配置工作,最后点击右下角的 reboot 重启退出虚拟机。2 g! D9 a& N$ d
注:此时你会发现虚拟机重启后又再次进入了 CentOS 的启动菜单,因此需要先终止掉此虚拟机进程,然后修改/tvm/templates.xml,将文档中指定的 ISO 文档路径清空,然后再次启动虚拟机,此时虚拟机就会直接从硬盘中启动系统。# z: [& p  r# T9 k6 ?, e2 Z' t

4 \1 j/ N  A& B8 |, X[root@koenli tvm]# virsh list
7 S# `9 u5 G0 Y! I: n7 W# K5 u Id    Name                           State% \% h6 L; H4 ~8 o
----------------------------------------------------" A) h$ `- S1 b
3     koenli                         running
, M! A) k3 G  O[root@koenli tvm]# virsh destroy 3
% z2 Z% A$ v" ~0 bDomain 3 destroyed! ]6 ^/ T! N: `$ H5 F! o
2 W4 M. Y1 [* W; J! Q
配置 OS5 u' K- W4 z1 F- E
配置网卡配置文档# Z6 H) V; f* |
配置网卡配置文档 ifcfg-eth0,ifcfg-eth1,删除 mac 地址和 UUID 相关配置项,IP 为 dhcp 获取,开机自启动$ Q2 K6 D* A( o, r4 Y6 f
, O0 U. v0 q5 s* M+ g8 ?# c" m* E
CentOS6.x/RedHat6.x操作如下:
% U3 h2 n' S* n. _; {0 x- s7 Dcat > /etc/sysconfig/network-scripts/ifcfg-eth0 << EOF
! ], ]9 s3 `6 m1 U( tDEVICE=eth0* |7 |& S0 i0 n; D, @
TYPE=Ethernet
: A% s0 K4 f8 f/ e: n% |ONBOOT=yes
- D  y) v, J) j( SNM_CONTROLLED=yes
  c4 S/ L! j3 O& I% I' [1 ABOOTPROTO=dhcp
* `7 s6 c6 p7 V; |( g! l' SEOF
" w9 n% ~$ c* \7 n4 Y% Acat > /etc/sysconfig/network-scripts/ifcfg-eth1 << EOF9 A, s) @5 U* s
DEVICE=eth1
, X3 x6 Q8 `# j5 U# P& Z+ W  Z; z3 F( p6 PTYPE=Ethernet% q- _+ O) C& g2 w, `
ONBOOT=no
: U1 d* v. ^& i+ ?1 d( r7 ^) t% iNM_CONTROLLED=yes& ?# u6 Z0 H( F7 L, Y' f6 w
BOOTPROTO=dhcp  r  F5 ]3 ]' \7 r7 Z% K
EOF
7 L! t0 s- c6 ?- S. ]/etc/init.d/network restart. P# E2 W# B6 Z7 T. e9 C: l
CentOS7.x/RedHat7.x操作如下:
& G! Z/ O, f7 a! n8 X& Kcat > /etc/sysconfig/network-scripts/ifcfg-eth0 << EOF
1 ]+ v5 G! b" {  D/ m4 rTYPE=Ethernet. _4 ?2 w- q, C# V- J; A  y
BOOTPROTO=dhcp% R8 c/ ]% ?: A
DEFROUTE=yes
1 d3 }) W# O0 b% z# f5 n/ M6 MPEERDNS=yes
1 s9 r  m1 `' ]! t+ N- z7 lPEERROUTES=yes
7 \( K; e! @% p1 HIPV4_FAILURE_FATAL=no
+ E$ D$ F, ]. r# b: iNAME=eth0
. Y4 k8 j% O8 w9 G" B* wDEVICE=eth0
. \; X. `" R5 ]( t; qONBOOT=yes
& F6 ?( K, L9 C7 {6 OEOF7 ]8 `! e% f! k$ ]7 r) R/ o- |
cat > /etc/sysconfig/network-scripts/ifcfg-eth1 << EOF
$ ?' G# s' Z/ x! a! H" ^: R4 e3 c& hTYPE=Ethernet
  r* @9 C% ^! `7 u- m; l4 L& ~BOOTPROTO=dhcp% [$ a7 T& \7 S5 W+ A2 L! q$ r6 q
DEFROUTE=yes! r: {) q4 P) Y" y
PEERDNS=yes# t3 Q0 w9 O; B# ~5 o4 [% E
PEERROUTES=yes1 o* p# j# h! G) Z0 k
IPV4_FAILURE_FATAL=no: Y. i, e, q4 P4 m* @8 R
NAME=eth1; g! c$ Y$ X3 ]7 E4 y+ \% b
DEVICE=eth1
$ B( ^4 e$ h& u2 d/ J; A, kONBOOT=no% G- C' X. _' M
EOF
0 g# P7 b2 N9 ^6 x7 i( F: I" x) rsystemctl stop  NetworkManager
4 N: H. m7 G3 c: g! i. y. Usystemctl disable NetworkManager
1 E8 j( Z& N+ F0 Lsystemctl restart network( G1 F9 Z# z% N* f
配置 sshd 服务/ @/ m+ G" O: S' m& w/ `5 E9 W3 [
关闭 sshd 服务的 UseDNS 和 GSSAPIAuthentication 选项; I3 Y) y5 G, L3 p& ~7 c: G, E3 B9 J0 h) d
, N4 l3 _* o  a2 _/ y
CentOS6.x/RedHat6.x操作如下:
' [3 c, G6 M6 B8 i! rsed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config
" @$ {( l( O* V9 ^! @5 x# n8 esed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/g' /etc/ssh/sshd_config$ Y8 z+ {1 h2 M; z: L! n/ z
/etc/init.d/sshd restart
* n7 B1 V& n8 [- ~) N* tCentOS7.x/RedHat7.x操作如下:8 `. ~7 w+ H5 b, R4 E, A) c
sed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config
4 W/ a" z$ W4 z9 X! Xsed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/g' /etc/ssh/sshd_config
, ]* ]1 @, e& D6 |$ wsystemctl restart sshd# c8 L  E- J% w$ `& P/ x8 _  g
配置 iptables 和 selinux
  X+ g/ M+ W+ L+ u5 ^- l9 c: ?关闭 iptables 和 selinux,并设置开机不自启(需重启生效)4 I7 G' g  t) C/ T2 z& H! z2 J' Y

% b1 Q* j5 S, d- y( ~CentOS6.x/RedHat6.x操作如下:# V2 S- e, Q) a2 @3 T
/etc/init.d/iptables stop
) _; l$ N+ @  e  p7 \; |) Wchkconfig iptables off' i8 z6 G) h1 n- j3 l# |
setenforce 0
- v: x2 _( t5 Z2 m4 o; Z3 Z  Psed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config  n" b) e# |. f* B
reboot2 I- v3 b( M7 L7 ]: D
CentOS7.x/RedHat7.x操作如下:
( F$ ?; F; A7 gsystemctl stop firewalld
! ?! R' h3 s  l6 V. gsystemctl disable firewalld5 H# [4 m% D: \) ~2 ]- k! f
setenforce 0
- D; H* W- |% Rsed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
  t: `5 E; o% Z% h1 u6 rreboot
# L3 q# V, _2 B1 B. [, i6 y$ C系统参数和内核参数优化4 b, C+ x$ m( @6 U8 }! L
设置系统文档句柄数限制和进程数限制(需重启生效)' C1 Z: ]: W- T0 Y
  I6 Y: h9 y8 K% ]+ G
CentOS6.x/RedHat6.x/CentOS7.x/RedHat7.x操作如下:
4 R/ ]: G2 s; [2 q- ycat >> /etc/security/limits.conf << EOF
, t* ?+ s! T  I0 l  M! O/ _* soft nproc 655360- ^: G! g0 ^; {
* hard nproc 655360
3 {  p. T7 u# t6 ?5 @% D* soft nofile 6553600 X1 m9 @6 e# W4 w
* hard nofile 655360* C/ b9 a7 a- {( y3 k- O; `
EOF
5 a+ s# a6 _9 Greboot. M6 u. O$ U( _
设置系统内核参数& R% G3 t  A% R/ E  x" R
' e& I: i( h" q) b/ x6 J6 n
CentOS6.x/RedHat6.x操作如下:
; ~) V' w! ^; C+ qcp -a /etc/sysctl.conf /etc/sysctl.conf.bak
, Q9 d9 L7 U+ becho "net.ipv4.ip_forward=1" > /etc/sysctl.conf2 E7 k* `2 x  ]) U
echo "net.ipv4.conf.default.rp_filter=0" >> /etc/sysctl.conf
# Q4 C- m9 C0 |7 T; ^echo "net.ipv4.conf.all.rp_filter=0" >> /etc/sysctl.conf" t- r% S6 k- O5 x
sysctl -p
- l) u6 y- j3 ?' aCentOS7.x/RedHat7.x操作如下:/ S- O) n7 O6 m  m& o
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
& p0 O4 ]: Q& s3 ~5 s! t4 ]echo "net.ipv4.conf.default.rp_filter=0" >> /etc/sysctl.conf4 |  l( ^6 N4 Z( e5 s. y' V
echo "net.ipv4.conf.all.rp_filter=0" >> /etc/sysctl.conf/ Z& b& W0 P3 c" d' \% |0 ~5 z
sysctl -p
, R) N; p8 e0 |5 K: a设置 history 历史命令显示格式
9 i, e& O& \4 j' H6 K1 n9 x! z1 E& E2 ~: ?( @# q" X0 I/ l1 X
CentOS6.x/RedHat6.x/CentOS7.x/RedHat7.x操作如下:1 \$ s' \7 \" \0 I/ s8 J& W4 j
echo 'HISTTIMEFORMAT="[%Y-%m-%d %H:%M:%S $USER] "' >> /etc/profile
! z# v/ x4 ^$ j" C5 ^source  /etc/profile
1 @! N) k& w2 f( P上传 iso 文档配置本地 yum 源7 E6 u0 A  b+ J9 Y) c- K/ h
此步可参考CentOS6.X/CentOS7.X 配置本地 yum 源教程,此处不再赘述。
9 d! n- {' ~' |安装基础软件包2 {% [  \5 v& G3 c! w' ~

' [. t5 P  r1 e; B' DCentOS6.x/RedHat6.x/CentOS7.x/RedHat7.x操作如下:* t& H. W% _/ C
yum install -y vim net-tools lrzsz unzip dos2unix telnet sysstat iotop pciutils lsof tcpdump wget strace ipmitool psmisc tree bc
1 `& ~1 y! K6 a3 K安装 epel 源4 X/ A4 H6 m1 T8 F& S9 o
https://fedoraproject.org/wiki/EPEL/zh-cn下载对应操作系统版本的 epel-release 包的最新版本,然后上传到虚拟机的/root 目录下并安装
+ b7 l! ~7 p- |( m! ]5 j; j) d- ^) M9 t
8 i4 ?/ c# `) E
CentOS6.x/RedHat6.x操作如下:
  I: ^' v0 F, \. ]* z5 l' ncd /root/& m4 W! c2 V+ n! G
rpm -ivh epel-release-latest-6.noarch.rpm
9 {* y4 [0 J3 ?2 A& _rm -rf epel-release-latest-6.noarch.rpm4 n# C* a; `# t
CentOS7.x/RedHat7.x操作如下:
) @5 l. U' f( m/ @9 Z& Qcd /root/. M5 K! X+ X. h
rpm -ivh epel-release-latest-7.noarch.rpm
% W: W+ f+ u9 k) N+ q9 n( l5 Grm -rf epel-release-latest-7.noarch.rpm
# C8 ~/ B$ Q2 J( u+ ?; M安装 cloud-utils-growpart
) }6 W! k+ v+ ~安装 cloud-utils-growpart 工具,实现根分区自动扩展/ A+ I, j: [$ {! ]9 d8 h

2 y! e. Q% q( o0 _( T7 U- A- ICentOS6.x/RedHat6.x操作如下:) ^: o6 e: M# Y6 B. T
yum install cloud-utils-growpart dracut-modules-growroot -y
' M+ L) s( j% `0 Udracut -f# y" k0 v- D6 o3 J0 O( Q# ^3 H1 \  U
CentOS7.x/RedHat7.x操作如下:$ M( V/ H  H7 p! y
yum install cloud-utils-growpart -y  a) y$ C+ o- D4 ]% f
安装 cloud-init5 ?8 ~( l( E. R, P7 b1 @9 C; k
https://share.weiyun.com/5gNv58k 密码:k6wnsx 下载对应操作系统版本的 cloud-init 安装包,并上传到虚拟机的/root/cloud-init 目录下并安装(/root/cloud-init 目录通过执行 mkdir /root/cloud-init 新建)6 z: s5 r; F+ y5 l

1 M8 q* n9 e$ b  c9 b* n% l4 |CentOS6.x/RedHat6.x操作如下:1 `( O2 p( ?" m* Z
cd /root/cloud-init/8 q* i1 P0 C/ g
yum localinstall *.rpm -y
5 o+ ~# x3 t+ c) gCentOS7.x/RedHat7.x操作如下:; N1 @0 ]# }/ k  I# F# U: g
cd /root/cloud-init/0 Q, `/ J: Q* A% N
yum localinstall *.rpm -y
' r" ^' w; f: g& B0 n9 r, P; A编辑/etc/cloud/cloud.cfg,将 disable_root 参数设为 0(允许 root 用户 ssh 远程登录),ssh_pwauth 参数设为 1(允许 password 认证),保存退出
& D* t9 c% X, E5 e% d& @: N
; u# c3 [7 U, M0 CCentOS6.x/RedHat6.x/CentOS7.x/RedHat7.x操作如下:
) V+ \* a. ^2 t4 ~9 [vim /etc/cloud/cloud.cfg0 X# Y' N# \) f. f
users:
2 Y' V, F; s9 N5 j - default8 D2 W& H/ m7 n! y) n
disable_root: 0
& O- V/ `. Z0 ossh_pwauth:   1
. n, x3 _+ J4 H6 T: X...& O% ^! K, V+ ^8 z+ s, _$ b
启动 cloud-init 并设置开机自启,因为做镜像的环境是无法访问到 openstack 的元数据服务的,故此次启动 cloud-init 时间会比较长,可以新开一个窗口执行 tail -f /var/log/messages 查看启动进度。' p- q! B6 m- g# A% I2 ?3 s, P

. c/ M. S7 K2 N( T  j, FCentOS6.x/RedHat6.x操作如下:
- K  G8 n0 r+ e. @  K. Wchkconfig cloud-init on* j; T9 j$ Y/ [7 w0 ^) k% }. j% U
/etc/init.d/cloud-init restart( ~: A0 x- f% w" H: B, m$ v. r
CentOS7.x/RedHat7.x操作如下:, ^7 X  r5 j7 @- k/ N. k+ w5 S2 Q
systemctl enable cloud-init
/ w( F! @, F9 {) t6 v; J. msystemctl restart cloud-init, B) }9 g- |6 V6 @( Y$ f/ Q
CentOS7.x/RedHat7.x 上若 cloud-init 启动失败,执行 systemctl status cloud-init 查看服务状态,若出现类似如下报错,则执行下面的命令更新 six,然后再次启动
8 [8 t: T  n5 j, [, b3 s" N" g4 S6 h$ n6 y
Dec 12 00:12:59 localhost.localdomain cloud-init[1989]: File "/usr/lib/python2.7/site-packages/cloudinit/cmd/main.py", line 2...dule>) p0 m9 {( P1 U& X; n" M$ F
Dec 12 00:12:59 localhost.localdomain cloud-init[1989]: from cloudinit import netinfo1 k5 n, \5 X! U0 n- T. _1 ]( O
Dec 12 00:12:59 localhost.localdomain cloud-init[1989]: File "/usr/lib/python2.7/site-packages/cloudinit/netinfo.py", line 14...dule>
7 p  X7 {$ P/ v# `9 l/ dDec 12 00:12:59 localhost.localdomain cloud-init[1989]: from cloudinit import util7 ^; F* l' q# |3 }% _
Dec 12 00:12:59 localhost.localdomain cloud-init[1989]: File "/usr/lib/python2.7/site-packages/cloudinit/util.py", line 37, i...dule>& _. `7 }( I; H$ ?2 F" \+ R- D
Dec 12 00:12:59 localhost.localdomain cloud-init[1989]: from six.moves.urllib import parse as urlparse
) B5 @3 v8 F& F- F) f# u2 JDec 12 00:12:59 localhost.localdomain cloud-init[1989]: ImportError: No module named urllib
  E: k9 x% L1 u# c" x- cDec 12 00:12:59 localhost.localdomain systemd[1]: cloud-init.service: main process exited, code=exited, status=1/FAILURE
( F% {1 p) ]/ {& p5 H7 QDec 12 00:12:59 localhost.localdomain systemd[1]: Failed to start Initial cloud-init job (metadata service crawler).7 q( ~" W+ l* `# a' f. ]
Dec 12 00:12:59 localhost.localdomain systemd[1]: Unit cloud-init.service entered failed state.: F% h1 A1 r7 V! h, Z; h
解决方法:
' q* u) i0 ?' s3 L! c7 Uyum install python-pip -y
& _" V& ^# z) T+ ~8 Y: I( I" Zpip install --upgrade six
; r+ s8 n& _& U2 P* a! usystemctl enable cloud-init
8 c& z1 b* t+ L7 c: ]- ~5 esystemctl restart cloud-init
, U- u5 R9 V5 i) b& V: cCentOS7.x/RedHat7.x 需再次编辑网卡配置文档,将网卡配置文档(/etc/sysconfig/network-scripts/ifcfg-eth0)中的 HWADDR 一行删除并保存退出。
# Z0 Y9 I; b1 F0 E' F6 a* z安装 qemu-guest-agent
$ _" m) E; N0 k# e4 L5 y9 |
9 @6 ?" n6 v8 iCentOS6.x/RedHat6.x操作如下:" ^9 n0 F$ U8 ~9 Z1 f
yum install qemu-guest-agent -y6 A! f& u" P6 ?/ t+ x
chkconfig qemu-ga on
/ y% {# U+ y1 ]: w4 R% P! OCentOS7.x/RedHat7.x操作如下:" h. i" [/ K+ |1 w6 j0 n
yum install qemu-guest-agent -y2 K. V8 P5 Y' P1 u, D3 |& I+ w8 l
禁用 zeroconf
  ~/ [6 \' U/ Y1 ~: Q  Q/ m. W+ p编辑/etc/sysconfig/network-scripts/ifup-eth 注释掉以下部分,禁用 zeroconf,否则 zeroconf router 在虚拟机开机时会自动生成路由 169.254.0.0/16 0 0 0 0 导致虚拟机无法与元数据通信
: E: C2 ~* O. v) e& \, Q' J2 l2 S! y$ T) o2 Y7 t
原内容
; j- |" \8 Y0 W/ N# s! ?/ a* Z# Add Zeroconf route.8 @1 H3 e: W3 \# d; j% z2 w
if [ -z "${NOZEROCONF}" -a "${ISALIAS}" = "no" -a "${REALDEVICE}" != "lo" ]; then
- q  a" e. z  {. F: _6 D    ip route add 169.254.0.0/16 dev ${REALDEVICE} metric $((1000 + $(cat /sys/class/net/${REALDEVICE}/ifindex))) scope link
, G" u3 r& g; gfi
" p: [4 ]; a) c8 Q6 G注释后:
3 m: p8 E; R5 @! ^1 |( _- H# Add Zeroconf route.
, H4 m2 I" S* u: ], v, X#if [ -z "${NOZEROCONF}" -a "${ISALIAS}" = "no" -a "${REALDEVICE}" != "lo" ]; then" X& O7 r; @( `8 j9 z4 q" S
#    ip route add 169.254.0.0/16 dev ${REALDEVICE} metric $((1000 + $(cat /sys/class/net/${REALDEVICE}/ifindex))) scope link
% d0 I6 d8 S2 Z4 ?7 S+ k6 i- C#fi+ ]/ |. h+ H! K5 _8 m6 J
设置 NTP(可选). S& K4 [" Z$ O5 I" |, K
& @( j3 r. i3 u7 k" S( o
CentOS6.x/RedHat6.x操作如下:& D# R" [- _1 T! y" m& {
yum install ntp ntpdate -y
# S, M- p  h2 ~+ H& \+ @# g- qsed -i "s%^server%#server%g" /etc/ntp.conf5 s# `, E" h3 J0 f) F
echo "server <ntpserver_ip>" >> /etc/ntp.conf    #<ntpserver_ip>替换为ntpserver的IP地址5 x# k# u7 z+ B2 d! G& L  V
/etc/init.d/ntpd restart
6 y$ L$ p% Y* F$ k- P$ k' Schkconfig ntpd on
3 l1 g2 P0 M; j  y$ _' _2 wCentOS7.x/RedHat7.x操作如下:
" k' X' ?# t$ c3 s3 O( wyum install ntp ntpdate -y6 h3 B  p* s2 x" c* X6 s9 t
sed -i "s%^server%#server%g" /etc/ntp.conf
7 ?/ N; N- y9 i/ C9 Yecho "server <ntpserver_ip>" >> /etc/ntp.conf    #<ntpserver_ip>替换为ntpserver的IP地址
* A+ Z. e# f8 E, L" m9 X2 W) h; Osystemctl restart ntpd
  b% U4 i1 p6 r7 _systemctl enable ntpd" P- i, A/ \' r- x( P# d
systemctl stop chronyd
8 }- C% H0 E! jsystemctl disable chronyd
9 i* ^" i$ @/ N& h4 w; f清理文档: V- W7 ~5 S# e% X
3 t9 `; f* l$ c/ m$ s
CentOS6.x/RedHat6.x/CentOS7.x/RedHat7.x操作如下:* M" m0 S. D& F; ]/ r
rm -rf /root/cloud-init/- a6 U' \3 W  E' H+ f; i
rpm -e `rpm -qa |grep epel`
/ h8 `3 X1 }3 o& b) t# v1 U, [yum clean all
3 p, S9 y5 S. }+ k# @$ H) }/ Orm -rf /etc/udev/rules.d/70-persistent-net.rules
/ t9 d8 U9 |- j( m6 S: U8 e; p清理命令历史记录并关机* \' c) O& V' x4 J
5 d+ l: b7 G( I% i5 r, C
CentOS6.x/RedHat6.x/CentOS7.x/RedHat7.x操作如下:
( T5 U& w8 n* }echo > /var/log/wtmp) l/ ~- D: ]* O+ g! m0 _$ f
echo > /var/log/btmp. Q0 \. W7 l3 P, F
echo > ~/.bash_history  E$ @' P3 Y2 \! x
history -c2 N4 _! {5 S6 ~1 h8 |4 P. H3 }' W4 ~
shutdown -h now
% T0 `/ C8 Y* W" p% ]4 c  M以上为几个比较常用的配置,更多自定义配置可以参考此文2 g2 N9 t. P% T
转换镜像格式  |% e* ~2 s5 f+ E, C  {1 N! [
将 raw 格式镜像文档转换成 qcow2 格式镜像文档,压缩空间便于传输。
: h' X, `6 C: c8 L8 ?8 X

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2021-12-10 17:35:28 | 显示全部楼层
目录/ X3 b8 G! v1 ]/ \
目录
# q9 T+ ]: M2 C! ]5 X' j8 q前文列表
, T" h1 }" [4 Z) ^  R9 ]扩展阅读4 Z% T8 b; o  U
系统环境
) z. s3 x. [8 H前言' W/ p8 j3 h- n+ g+ o
Cloud-init
: \3 U" v4 |( D6 \9 CCloud-init 的配置文件* k; w/ c" w$ P; [: r
metadata userdata
7 y  E% q* P8 n7 ?" p% Ametadata 和 userdata 的区别2 |+ [1 ]2 `7 p% n, s
metadata 的服务机制
  p5 H" i/ Z) s. A: B4 WConfigDrive
* M1 y. c" S% C& ?" \$ EMetadata RESTful
: W) f+ y; ]; U: |- r前文列表0 E+ f2 e4 [$ U7 h( P
Openstack 实现技术分解 (1) 开发环境 — Devstack 部署案例详解
4 c( ~% I- I: ]) v, L: d, Q扩展阅读/ X/ F% ?) d' d
Documentation — Cloud-Init 0.7.9 documentation
, l; l7 b+ `2 A2 B* U系统环境
3 |4 a  V3 _* x- A* wDevstack-M
& W2 ^8 R9 s# VUbuntu TLS 14.04- D( {6 n  [: P# m5 h/ z
前言# k, n* e; e/ F' P& A0 ]
Cloud-Init + metadata + userdata 是一套初始化定制云平台虚拟机的解决方案, 最主要解决了下列功能需求:
* ]# V5 e3 U8 t3 n- C0 A1 g3 W能够自动化的完成对云平台虚拟机的初始设置, EG. set-hostname/set-ipv4/set-disk-size/upgrade/exec-script 等等
# L' M( S7 j5 B" H* k支持云平台与虚拟机的通信, 以此来获取虚拟机的具体信息
1 {! ]% _% o* H' Y, p; p& u简单来说就是能够 注入/获取 虚拟机的信息, 并以此衍生出对虚拟机的初始化定制能力. 其生产价值类似于无人值守技术, 避免了单独为每一台虚拟机进行人工初始化的繁琐.+ H+ y& q8 I1 r6 _9 o. ]
Cloud-init
# B# k) U: ^- [0 T- d$ S3 kEverything about cloud-init, a set of python scripts and utilities to make your cloud images be all they can be!
# N2 C. V8 W6 FCloud-Init 是一组 Python Script 的集合, 是一个能够定制 Cloud Images 的实用工具.1 Z! e, v: \8 [0 E9 S" ]- N4 Q
所以 Cloud-init 一般会被包含在用于启动云平台虚拟机的 Images 文件中, 并且使用该镜像启动虚拟机时, Cloud-init 应该是自启动的, 因为其工作在虚拟机的启动过程中, 对虚拟机进行定制化的初始配置.. c  |, ^! ?  W2 y2 B
安装 Cloud-init 方法非常简单, 基本上常规的系统发行版都有原生的软件源, EG. ubuntu 安装:% d8 q% D8 |* |3 C
sudo apt-get install cloud-init
, l! [0 @! G) Y: K/ q2 I8 iNOTE: Cloud-init 安装在虚拟机中, 然后再将该虚拟机制作成有如 qcow2 格式的 Image 文件.+ c- k* y0 x" c
那么, 第一个问题: Cloud-init 是怎么定制虚拟机配置的呢?
9 ?% c0 ~) H9 A! \4 A7 u& s: _/ e/ L6 \答案就是 Cloud-init 的配置文件 cloud.cfg.2 j" i# f( T$ B7 C
Cloud-init 的配置文件& ~+ S5 x0 \+ [% Y
一般我们也只需要关心 Cloud-init 配置文件的定义, /etc/cloud/cloud.cfg:/ R+ N: L3 }! [" G( C0 T
stack@fanguiju-dev:~/devstack$ cat /etc/cloud/cloud.cfg | grep -v ^# | grep -v ^$6 q( D; c. m: i7 U; c6 B; i
users:
. k7 s5 U/ I0 I% d1 l   - default
+ [4 Y6 Z' g. `disable_root: true
; ^/ @, r0 a5 O. spreserve_hostname: false
: d$ V0 s1 B- a8 b& A- m- ]( Kcloud_init_modules:8 b+ d& {3 j' W1 v' T* [) Z; q
- migrator; l5 L0 d6 d% g" n4 v
- seed_random9 @; a( n3 x- e# t: ^8 d) x
- bootcmd
  r& E8 o7 h0 Y* ~9 f# F' \ - write-files! d) P* r4 ?* {+ T, Q1 F+ y/ `
- growpart+ ^9 ^2 y- f5 x- `
- resizefs8 S, _+ J+ z/ R& {
- set_hostname5 p) X7 D. y0 U: a, a
- update_hostname- e7 d" g- X( O8 A
- update_etc_hosts; J9 c) ~9 U& R0 K8 i+ e
- ca-certs; G! `; k0 L& j/ T  e& o- e0 K
- rsyslog4 }8 ~5 O6 ]$ U! ]
- users-groups8 a9 H: v# U* h  S
- ssh
1 F; G# L9 M6 q; a! ?2 `* tcloud_config_modules:+ s" Z4 a& w) V% g! r' u3 |
- emit_upstart
" N8 i. }* f" L4 l. i* W1 B& g1 m - disk_setup7 C4 e" D  q* A
- mounts
5 R$ g2 R, ]: f$ r9 u+ E" i4 D - ssh-import-id# o4 k! f' s# ]$ b5 m8 I
- locale
, B0 e7 E2 H" H" E5 X( q" l - set-passwords  `1 Q9 R5 |" V- L& G- g, [3 m: e$ s
- grub-dpkg+ y) h; j4 U; |6 o) t
- apt-pipelining
2 A( T7 I4 a) K2 c# G) W8 n9 S+ U - apt-configure
  y* t$ C5 R; Q4 O - package-update-upgrade-install
* _, f6 W8 S" g" C; Y" L - landscape: S/ E+ f9 F' }6 [5 L
- timezone
% q# G8 G9 h" q0 ~2 i# Q - puppet
% \* S# X" t; a3 I3 B7 c% T - chef
3 N8 g, q+ b1 c# P. R. M: T+ T - salt-minion
( Y2 ^+ i; L' q - mcollective
- {& `7 q3 @6 ]# m- G7 g - disable-ec2-metadata- ]7 U* t9 A( m( ]
- runcmd& o3 z( B& {1 w! K6 S! I
- byobu
2 R2 P8 i. K, s6 {) r6 S# [cloud_final_modules:
0 ?7 o& b) ]- D8 H3 z4 [ - rightscale_userdata) k. Q6 f( q( ]$ ]* W- n5 k
- scripts-vendor4 v4 K5 ^% e2 x! T  C
- scripts-per-once
5 G7 B! V' h5 U: B" j$ ?! U6 y1 T( w - scripts-per-boot
% ~. o- g7 g9 T - scripts-per-instance
/ Y( S' D/ W9 {' O - scripts-user9 d, B) D$ h+ H' z7 C1 M  t, ~/ e
- ssh-authkey-fingerprints: L/ N) o9 P; e- Y; x. T$ W9 p; m
- keys-to-console
7 m  u. J5 Y/ g - phone-home
0 ?2 h% E7 y4 x( U% a - final-message
/ ^& U; s+ I9 r) N7 F4 B; { - power-state-change& z- G; l5 c% i! [. s
Cloud-Init 根据配置文件的内容, 来定制虚拟机配置, 其中最主要配置项的就是下列三个模块列表:5 M* R, G, r4 o/ n8 r
cloud_init_modules
1 E3 F6 i8 O# V0 A8 ~3 @cloud_config_modules8 X3 }3 `, X" K6 g
cloud_final_modules: [9 E' D. ~# A
在虚拟机启动时, 会顺序的根据模块列表中含有的各个模块的变量值来对其进行配置, EG. 模块列表 cloud_init_modules 中包含的模块 update_etc_hosts (/usr/lib/python2.7/dist-packages/cloudinit/config/cc\_update\_etc\_hosts.py). 从该模块的代码可以看出其能够配置虚拟机的 hostname/fqdn/manage_etc_hosts 等信息. Cloud-Init 首先会尝试从配置文件 /etc/cloud/cloud.cfg 读取变量 hostname/fqdn/manage_etc_hosts 的值, 如果没有定义, 则尝试从其他的数据源中获取并实现配置. EG. Openstack 可以通过 Metadata 来获取 hostname 等变量值.' n, l5 N7 f) }5 C8 Q) C' ^
NOTE 1: 除此之外, Cloud-Init 还会按照上述模块列表的顺序来进行配置, 这是因为有些模块的执行对虚拟机操作系统当前的状态是有要求的, 后面模块的配置可能需要前面模块的配置做支撑.
- |( O3 [' G# x! \2 X4 bNOTE 2: 而且, 模块列表中的模块具有多种运行模式:
- |) P& [+ j! p% x" `per-once: 仅执行一次, 在执行完毕之后会在 sem 目录中创建一个信号文件, 防止在下次启动虚拟机时重复执行.
, h4 x0 c- @4 ?+ L8 Z% I* Mper-always: 每次启动都会执行
; n$ \1 l5 y# z( m3 B4 fper-instance: 每一个虚拟机都会执行
5 |/ b& [3 N( ~7 rEG.
2 Z7 s# }7 Q) Q( e( L4 c& acloud_final_modules:+ u5 D! e% ~6 j+ j# _: }- s
- scripts-per-once
3 n" `( J% E* \. q - scripts-per-boot
% R6 Y9 Y) ~9 m - scripts-per-instance, E' ~% e6 L+ H4 k
配置文件 cloud.cfg 更相信的用法请查阅官网, 一般而言, 默认的就够用了.
' ^2 z! L' c  e# M. e. ~第二个问题: Cloud-init 定制虚拟机操作系统配置时, 配置项目的值, 从哪里获取?
4 O7 t8 v* X1 M答案就是 metadata/userdata$ f* @8 \0 Z" n$ }# R, m
metadata & userdata
, C: L8 p4 f4 o- t; i/ K; d$ V; W. rmetadata 是一个数据源, 在 Openstack 中是由 nova-api service 提供的, 一般我们会在虚拟机中通过IP 169.254.169.254 来获取.
% P2 h, c- J6 O9 J0 S; mOpenstack 实现技术分解 (2) 虚拟机初始化工具 — Cloud-Init & metadata & userdata..._第1张图片
: V  R- r) \- X- z4 G" Q选择一个版本
% k, ?/ m5 f3 Z* m$ V1 bOpenstack 实现技术分解 (2) 虚拟机初始化工具 — Cloud-Init & metadata & userdata..._第2张图片! }1 R; p; i' F( ~. k
选择一个配置项目
$ {, {* w1 r# X7 n这里写图片描述
- G  ?: s6 w: z% H3 }( d( I3 C# _显然, Cloud-init 能够通过访问这些 URL 来获取其所需要的信息, 然后再进行配置. 但是需要说明的一点是 169.254.169.254 这个 IP 实际是不存在的, 本质上提供 metadata 的是 nova-api service, 所以通常都需要设定防火墙 DNAT 将 169.254.169.254 映射到 nova-api-service-ip:port 这个 IP.9 Q: C. D4 h# B4 l. }
metadata 和 userdata 的区别
+ g8 {8 Z7 o- h- m其实 userdata 与 metadata 本质上都是提供配置信息的数据源, 使用了相同的信息注入机制, 只是两者代表了不同的信息类型而已:( g0 F# ]1 O# v; L0 o3 _5 Y
metadata 主要提供了虚拟机的常用属性, EG. hostname/network/SSH/…, 其以 key/value 的形式进行注入, 所以非常适合应用到 REST 的场景中.- i. S% E$ r$ \5 x0 H
userdata 主要提供了 Shell 相关的 CLI 和 Script 等, 其通过文件的方式进行注入, 支持多种文件格式(EG. gzip/Bash/cloud-init/…).$ \) j% z8 B' T; k7 @( S
所以, 两者的区别仅在于虚拟机在获取到信息后, 对两者的处理方式不尽相同而已.
7 A; g0 ?$ J+ w' c! o9 T: }  G# K第三个问题: metadata 和 userdata 含有的配置信息是怎么被注入到虚拟机中的?4 Z& e0 A% Y2 n  k. ^% A
答案就是 ConfigDrive/RESTful API
+ h& h+ {: b) b. l# Ymetadata 的服务机制
' M6 M1 M$ K: Q' J( Z! HConfigDrive
% c, Z1 U% b. [$ @1 T手动指定使用 ConfigDrive:
$ R" _, h! }1 i. T8 `' h+ \. }nova boot --config-drive=true ...
; J1 \# Z: b7 ]5 H5 F启动虚拟机时, 使用 --config-drive=true 就是使用 ConfigDrive 机制来注入 metadata 信息.
, @7 u$ Y! f; T$ O+ g: a9 M: N修改配置文件默认使用 ConfigDrive:, K( q4 S3 n  D6 f# [+ `6 f
vim /etc/nova/nova.conf
2 ~5 B7 Y. S9 G[DEFAULT]- F3 n1 W2 E. w7 z, p" F( B
...2 |! I) v" C. y; c
force_config_drive = True& d' l" `" A* ~) M5 U/ W3 t
ConfigDrive 机制: OpenStack 会将 metadata 信息写入虚拟机的特殊设备中, 然后在虚拟机启动时, 会将该设备挂载到虚拟机上并由 Cloud-init 读取内含的 metadata 信息, 从而实现信息注入.
; d* ?8 n4 g; f2 l6 b# P例如, 初始化定制 Openstack 默认支持的 Libvirt 虚拟机配置时, OpenStack 就会将 metadata 写入虚拟机的 vdisk 文件中, 并将 vdisk 指定为 cdrom 设备.
% H; _  K7 E9 H6 kOpenstack 实现技术分解 (2) 虚拟机初始化工具 — Cloud-Init & metadata & userdata..._第3张图片: g% M! y& F8 M* |4 G/ y2 t
我们启动一个测试用的 Libvirt 虚拟机, 其 id 为 30ba8cc0-b2f9-4e38-9a27-6bfa9d82f5f2. 然后找到该虚拟机的 XML 文件, 其中含有以下配置内容:- N% k$ p" W; ~8 S
vim /opt/stack/data/nova/instances/30ba8cc0-b2f9-4e38-9a27-6bfa9d82f5f2/libvirt.xml
, R8 e: U  n, z3 ^. @# [    <disk type="file" device="cdrom">) d9 \, j! C3 X8 J: A
      <driver name="qemu" type="raw" cache="none"/>
( R; k: ^( M4 T3 s6 M4 |" R" x      <source file="/opt/stack/data/nova/instances/30ba8cc0-b2f9-4e38-9a27-6bfa9d82f5f2/disk.config"/>/ X1 S7 ]9 X  Z6 ]5 C, C
      <target bus="ide" dev="hdd"/>9 ^+ Q2 M. Q- M! A( j0 [$ c% |9 D
    disk>
! W9 d0 L% ?! V' K5 A2 F! c4 E所以, 这里的 cdrom 设备就是以 ConfigDrive 方式进行 metadata 信息注入所使用到的特殊设备.
+ h- h! k4 T, o" v$ X' B但是需要注意的是: 显然, 不同的底层 hypervisor 支撑, 其所挂载的设备类型也不尽相同.3 \! t5 n5 X. O& V
在虚拟机中查看 metadata 信息:
8 I. u2 ?  Q( @' |9 }ubuntu@auto-dep-db:~$ sudo mount /dev/disk/by-label/config-2 /mnt/8 ^6 Z: l8 U) V% L
mount: block device /dev/sr0 is write-protected, mounting read-only6 f9 f/ r9 N+ ^+ C) \
ubuntu@auto-dep-db:~$ cd /mnt/) Z2 L  a2 p- E: r, {
ubuntu@auto-dep-db:/mnt$ ls/ e( _$ Y5 i6 G$ A/ z( _
ec2  openstack* ^& Y0 N* H6 O0 c
ubuntu@auto-dep-db:/mnt$ cd openstack/, m$ f3 d8 V9 s* R8 l6 k+ K
ubuntu@auto-dep-db:/mnt/openstack$ ls
  k1 b. [- t  R* o7 e2012-08-10  2013-04-04  2013-10-17  2015-10-15  latest& }! Q2 w4 p) |' F
ubuntu@auto-dep-db:/mnt/openstack$ cd 2015-10-15/
- J: o  G0 a7 `* xubuntu@auto-dep-db:/mnt/openstack/2015-10-15$ ls
9 H* ~7 A; s& e; `: o- [; jmeta_data.json  network_data.json  user_data  vendor_data.json9 x# O7 H/ ^# h
ubuntu@auto-dep-db:/mnt/openstack/2015-10-15$ vim user_data7 g" f  b: H" _! Y& `3 c3 ^, P; ?
其中 user_data 文件就是我们在创建虚拟机时, 指定需要执行的脚本文件.
- G+ Q) ~. C. u4 L  WMetadata RESTful) {' j; K, o" Z# ]0 M
Openstack 中的虚拟机也可以通过 RESTful API 来获取 metadata 信息, 提供该服务的组件为 nova-api-metadata service + neutron-metadata-agent + neutron-ns-metadata-proxy.( e* W+ S$ x; L6 \! Q5 _
注意, 如果在 Nova-Network 网络模式中后两个服务是不存在也不需要的.$ _" L  S0 m  _% F4 H& X7 _
Nova-api-metadata: 负责接收并处理虚拟机发出的 REST API 请求(EG.curl 169.254.169.254), 从 HTTP Request Header 中能够获得获得虚拟机 id, 继而从 database 中读取虚拟机的 metadata 信息并返回结果给虚拟机.  o( Q5 S2 v/ a! T
Neutron-metadata-agent: 负责将自身节点中的虚拟机发出的 metadata 请求转发到运行 nova-api-metadata 服务的节点中, neutron-metadata-agent 会将虚拟机 id 和 project id 添加到 HTTP Request Header, 最后由 nova-api-metadata 会根据这些信息到 database 中获取 metadata 并返回结果给虚拟机.
, T. f1 J+ S% @& f& y4 x' Z1 ]Neutron-ns-metadata-proxy: 为了解决 Node 中的物理网段和 Project 中的虚拟网段重复的问题, OpenStack 引入了 network namespace 的概念, 每个 namespace 都是独立的, 其包含了各自拥有的 Route 和 DHCP Server. 由于虚拟机的 metadata 请求都是以 Route 和 DHCP Server 作为网络出口的, 所以需要通过 neutron-ns-metadata-proxy 来打通不同的 namespace, 让该请求在不同的 namespace 间跳转, 其实现原理是利用了在 Unix domain socket 基础之上的 HTTP 技术, 并在 HTTP Request Header 中添加 X-Neutron-Router-ID 和 X-Neutron-Network-ID 字段信息, 使得 neutron-metadata-agent 能够定位发出请求的虚拟机并获取其 id.
" K( _& _, A5 j+ b8 {Openstack 实现技术分解 (2) 虚拟机初始化工具 — Cloud-Init & metadata & userdata..._第4张图片5 Z  x4 x0 o! O6 C$ `! s) j+ D5 }
Instance 发送 metadata 请求被发送至 network namespace
# x, j# ~5 q3 J+ L. G! H; n再由 namespace 中的 neutron-ns-metadata-proxy service(添加 router-id/network-id 到请求头) 通过 unix domian socket for IPC 技术转发给 neutron-metadata-agent0 ^: A* c( z& e
在 neutron-metadata-agent 中, 其会根据请求头中的 router-id/network-id/ip/port , 来获取并添加 instance-id/tenant-id 到请求头中
, S* e4 J: y7 B/ u' M8 F然后由 neutron-metadata-agent 将请求被转发给 nova-api-metadata, 并且利用请求头中的 instance-id/tenant-id 从数据库中获取虚拟机的 metadata2 ^* I8 T. V. C
最终原路返回 metadata 到虚拟机中
; i' x0 p3 t2 w3 r) y7 KNOTE: 上面已经提到过了如果虚拟机希望访问 169.254.169.254 首先需要在 Node 上设置 DNET:
) I0 S. Y( U$ H6 x* a( x+ zsudo iptables -t nat -A PREROUTING -d 169.254.169.254/32 -p tcp -m multiport --dport 80 -j DNAT --to-destination <nova_api_server_ip>:8775/ W: Z' T+ B  D" {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 02:03 , Processed in 0.018675 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表