如果您的Linux镜像不在ECS支持的操作系统版本中且不能通过安装cloud-init完成实例初始化配置,阿里云会将该镜像当作无法识别的操作系统。因此在导入镜像前,您需要自行在镜像中添加解析脚本,用于实例初次启动时完成自动化配置。
为便于区分,如果您导入的Linux系统镜像不在ECS支持的操作系统版本中,该操作系统平台镜像为非标准平台镜像。非标准平台镜像虽然来自标准操作系统平台,但该类镜像属于系统关键性配置文件、系统基础环境和应用方面没有遵守标准平台要求的镜像。导入非标准平台镜像时支持选择的操作系统版本以及配置说明如下:
Others Linux:ECS统一标识为其他系统类型。如果导入Others Linux平台镜像,ECS不会对所创建的实例做任何处理。创建实例后,需登录ECS实例自行配置IP、路由和密码等。
Customized Linux:定制版镜像。导入Customized Linux镜像前,需按照本文进行配置。
前提条件
需确保您的镜像满足如下条件:
第一个分区(通常是/dev/sda1或/dev/vda1)必须具备写权限。
第一个分区的文件类型只能是FAT32、EXT2、EXT3、EXT4或UFS。
说明您可以通过
blkid /dev/sdXn
(其中sdXn是第一个分区名称,例如/sda1)命令查看分区的文件系统类型。虚拟文件的大小必须大于5 GiB。
说明您可以通过
df -h /dev/sdXn
(其中sdXn是第一个分区名称,例如/sda1)命令查看指定分区的空间。
操作步骤
使用root用户登录您制作镜像的虚拟机。
在镜像的第一个分区的根目录下新建目录,目录名称必须为
aliyun_custom_image
。mkdir /aliyun_custom_image
使用Customized Linux镜像创建的ECS实例初次启动时,阿里云会在
aliyun_custom_image
目录的os.conf
文件中写入实例的主机名、用户密码、DNS服务器等相关信息。如果不存在os.conf
文件,则系统会自动创建。os.conf
文件内容示例:hostname=<yourHostName> password=<yourPassword> eth0_ip_addr=10.0.0.2 eth0_mac_addr=00:xx:xx:xx:xx:23 eth0_netmask=255.255.255.0 eth0_gateway=10.0.0.1 eth0_route="0.0.0.0/0 10.0.0.1" dns_nameserver="7.7.X.X 8.8.8.8"
示例中各参数说明如下表所示,请您根据实际环境配置。
参数名称
参数说明
hostname
主机名
password
root用户的密码
eth0_ip_addr
eth0网卡的IP地址
eth0_mac_addr
eth0网卡的MAC地址
eth0_netmask
eth0网卡的子网掩码
eth0_gateway
eth0网卡的默认网关的IP地址
eth0_route
eth0内网的路由列表,默认用空格分隔
dns_nameserver
DNS地址列表,默认用空格分隔
在镜像中创建一份解析脚本(例如脚本名称为
customized-config.service
),用以读取和解析os.conf
文件的系统配置。该解析脚本用于ECS实例首次启动时进行自动化配置,例如设置主机名、root用户密码、DNS服务器以及网络配置等。
脚本内容示例:
#!/bin/bash ### BEGIN INIT INFO # Provides: os-conf # Required-Start: $local_fs $network $named $remote_fs # Required-Stop: # Should-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: The initial os-conf job, config the system. ### END INIT INFO first_partition_dir='/boot/' os_conf_dir=${first_partition_dir}/aliyun_custom_image os_conf_file=${os_conf_dir}/os.conf load_os_conf() { if [[ -f $os_conf_file ]]; then . $os_conf_file return 0 else return 1 fi } cleanup() { # ensure $os_conf_file is deleted, to avoid repeating config system rm $os_conf_file >& /dev/null # ensure $os_conf_dir exists mkdir -p $os_conf_dir } config_password() { if [[ -n $password ]]; then password=$(echo $password | base64 -d) if [[ $? == 0 && -n $password ]]; then echo "root:$password" | chpasswd fi fi } config_hostname() { if [[ -n $hostname ]]; then sed -i "s/^HOSTNAME=.*/HOSTNAME=$hostname/" /etc/sysconfig/network hostname $hostname fi } config_dns() { if [[ -n $dns_nameserver ]]; then dns_conf=/etc/resolv.conf sed -i '/^nameserver.*/d' $dns_conf for i in $dns_nameserver; do echo "nameserver $i" >> $dns_conf done fi } is_classic_network() { # vpc: eth0 # classic: eth0 eth1 grep -q 'eth1' $os_conf_file } config_network() { /etc/init.d/network stop config_interface eth0 ${eth0_ip_addr} ${eth0_netmask} ${eth0_mac_addr} config_route eth0 "${eth0_route}" if is_classic_network ; then config_interface eth1 ${eth1_ip_addr} ${eth1_netmask} ${eth1_mac_addr} config_route eth1 "${eth1_route}" fi /etc/init.d/network start } config_interface() { local interface=$1 local ip=$2 local netmask=$3 local mac=$4 interface_cfg="/etc/sysconfig/network-scripts/ifcfg-${interface}" cat << EOF > $interface_cfg DEVICE=$interface IPADDR=$ip NETMASK=$netmask HWADDR=$mac ONBOOT=yes BOOTPROTO=static EOF } config_default_gateway() { local gateway=$1 sed -i "s/^GATEWAY=.*/GATEWAY=$gateway/" /etc/sysconfig/network } config_route() { local interface=$1 local route="$2" route_conf=/etc/sysconfig/network-scripts/route-${interface} > $route_conf echo $route | sed 's/;/\n/' | \ while read line; do dst=$(echo $line | awk '{print $1}') gw=$(echo $line | awk '{print $2}') if ! grep -q "$dst" $route_conf 2> /dev/null; then echo "$dst via $gw dev $interface" >> $route_conf fi if [[ "$dst" == "0.0.0.0/0" ]]; then config_default_gateway $gw fi done } ################## sysvinit service portal #################### start() { if load_os_conf ; then config_password config_network config_hostname config_dns cleanup return 0 else echo "not load $os_conf_file" return 0 fi } RETVAL=0 case "$1" in start) start RETVAL=$? ;; *) echo "Usage: $0 {start}" RETVAL=3 ;; esac exit $RETVAL
设置脚本开机自启动。
以下命令以Ubuntu为例,请您根据实际操作系统选择开机自启动命令。
systemctl daemon-reload systemctl customized-config.service
说明基于Customized Linux镜像创建的ECS实例新制作自定义镜像时,镜像中也会包含开机启动脚本。阿里云会在实例第一次启动时执行解析脚本运行
os.conf
的相关配置。
相关文档
镜像配置完成后,您可以在导入自定义镜像时选择操作系统版本为Customized Linux。更多信息,请参见导入自定义镜像。