我希望把我的虚拟机导出成 OVA 文件,给其他同事使用。然而在导出之前,曾经编译过我们公司的代码,导致产生了十几 G 的文件,虽然都删除了,但是虚拟机的磁盘文件已经增长到 15G,而在虚拟机里面看到的磁盘使用量其实只有 1G,这样直接导出的话不仅费时费力,还不好传输。可以通过下面是方法减小磁盘大小:

转换格式

只有 VDI 的格式才能够通过 Virtualbox 的命令进行缩小,所以如果不是 VDI 格式的文件,先转换为 VDI 格式,如果已经是 VDI 格式就不需要这一步了。

VboxManage clonehd original-disk.vmdk new-disk.vdi --format VDI

说是转换,其实是拷贝,其中,original-disk.vmdk 为现有的磁盘文件,new-disk.vdi 为新的磁盘文件。
转换好了之后,设置虚拟机配置,让其使用新的磁盘文件。

zerofree

zerofree 可以把磁盘中不使用的块用 0 来填充,这样磁盘能够被更好的压缩,在 Debian/Ubuntu 中可以直接使用 apt 安装

apt-get install zerofree

然后重启虚拟机到维护模式,一般是启动菜单的第二个选项。启动到维护模式之后先将根目录挂载为只读:

mount -n -o remount,ro /

如果挂载失败,可以先把所有在运行的服务停掉,比如 dhclient 等。
然后使用 zerofree 对分区进行处理

zerofree /dev/sda1

当然,你要替换成你自己的分区,等待处理完成之后,关闭虚拟机

poweroff

减小磁盘文件

现在是时候对磁盘文件进行缩减了,使用 Virtualbox 提供的命令即可:

VBoxManage modifyhd new-disk.vdi --compact

执行成功之后,再看一下磁盘文件,从之前的 15G 减小到了 1.5G,效果是还是很明显的,最后导出的虚拟机 OVA 文件只有 300 多兆。


新的 VPS 使用的操作系统 Ubuntu 14.04.1 LTS,其 Apache2 的版本号为 2.4.7-1ubuntu4.1,而 Google 提供的 mod_spdy 安装包依赖的 Apache2 的版本为 2.2,在安装 mod_spdy 的时候会出错,提示如下:

# dpkg -i mod-spdy-beta_current_amd64.deb 

Selecting previously unselected package mod-spdy-beta.
(Reading database ... 111842 files and directories currently installed.)
Preparing to unpack mod-spdy-beta_current_amd64.deb ...
Unpacking mod-spdy-beta (0.9.4.3-r420) ...
dpkg: dependency problems prevent configuration of mod-spdy-beta:
 mod-spdy-beta depends on apache2.2-common; however:
  Package apache2.2-common is not installed.

dpkg: error processing package mod-spdy-beta (--install):
 dependency problems - leaving unconfigured
Errors were encountered while processing:
 mod-spdy-beta

经过一番 Google 之后,找到了这个支持 Apache 2.4的 mod_spdy,安装方法如下,
首先下载源码进行编译:

$ sudo apt-get -y install git g++ apache2 libapr1-dev libaprutil1-dev patch binutils make devscripts
$ git clone https://github.com/eousphoros/mod-spdy.git
$ cd mod-spdy/src
$ git checkout apache-2.4.7
$ ./build_modssl_with_npn.sh
$ chmod +x ./build/gyp_chromium
$ make BUILDTYPE=Release
$ cp out/Release/libmod_spdy.so mod_spdy.so

这个时候会出来两个 Apache2 模块,mod_ssl.so 和 mod_spdy.so,把这两个文件拷贝到 Apache2 的模块目录:

$ sudo mv /usr/lib/apache2/modules/mod_ssl.so /usr/lib/apache2/modules/mod_ssl.so.bak
$ sudo cp mod_ssl.so /usr/lib/apache2/modules
$ sudo cp mod_spdy.so /usr/lib/apache2/modules

mod_ssl.so 会比原来的大不少,那是因为为了不影响系统的 openssl 库,它把 openssl 库给静态编译进去了。
最后设置模块,让 Apache2 启动的时候加载 mod_spdy 模块就行了:

$ echo "LoadModule spdy_module /usr/lib/apache2/modules/mod_spdy.so" | sudo tee /etc/apache2/mods-available/spdy.load
$ echo "SpdyEnabled on" | sudo tee /etc/apache2/mods-available/spdy.conf
$ sudo a2enmod ssl
$ sudo a2enmod spdy
$ sudo service apache2 restart

PS:之前研究 IE11 的时候发现他用的 ALPN 而不是 NPN,花了一下午时间让 mod_spdy 支持了 ALPN 协议,结果回到家才发现 IE11 现在也支持了 NPN,记得以前是不支持 NPN 的呀,简直白折腾了。


去年 10 月份在电信官网上申请了办理电信 100M 宽带的业务,1980 包年,没过几天师傅就进行了上门安装,速度杠杠的,一直使用到现在也没有出现任何问题。
到了今年 9 月份,突然接到电信的电话回访,问我宽带有没有装好。当时觉得莫名其妙,去年装的宽带,用了快一年了才回访,有毛用啊。告诉他去年就装好后就挂断了,当时也没在意。
前几天收到了一份电信的账单,说是我支付了 8 月 1 日到 8 月 31 日的宽带费用一共 224 元。那么现在问题就来了,挖掘机…咳咳,明明是包年的,怎么还会有支出呢,果断进行投诉。
第一次答复说我是 8 月份办的宽带,要到 9 月 1 日才开始生效,所以需要交纳 8 月份使用的宽带费用,得知我是去年办理的宽带后,他说要再查查。
第二次答复的时候,说虽然是去年 10 月份办理的宽带,但是今年 9 月 1 日才生效,可以用到明年 8 月 31 日,而之前用了这么久的网络就算送我了。
真是赚到了,欢快的记录下这次意外收获。


更换原因

本来一直使用亚马逊的 EC2,由于我同学弄了个游戏外挂在淘宝上卖,导致流量上涨,而 EC2 的流量是收费的,导致最近每个月的价格都是十几美元,感觉有点贵了。

现在换到了 DigitalOcean,每月五美元的价格还算承受得起。

切换的过程

由于就只用来放一些网站,以及少量的 vpn 需求,切换过程比较简单:

  1. 备份数据库和网页
  2. 拷贝到新 vps 上
  3. 导入数据库和网页
  4. 最后的调整

备份

使用 mysqldump 把用到的数据库都备份出来,比如 wordpress, dabr 等

mysqldump --databases wordpress dabr > mysql_dump.bak

网页的话直接打个包即可

tar cvfj www_data.tbz2 -C /var/www/ .

拷贝

直接使用 scp 命令即可,无需拷贝到本机,以下是在老的 vps 上操作的,其中 do.zlb.me 是新的 vps 的地址,root 为新 vps 的用户名

scp mysql_dump.bak www_data.tbz2 root@do.zlb.me:/tmp/

导入

数据库到导入:

mysql < /tmp/mysql_dump.bak

网页的导入:

tar xvf /tmp/www_data.tbz2 -C /var/www/

最后的调整

基本上整个迁移就差不多了,不过很有可能新的 vps 上缺少了某些包(比如你的网页需要 php 的 mcrypt, curl 等模块之类的),需要重新安装。或者 apache2 的配置有些不一样(比如说需要启用 ssl, rewrite, headers 等模块),就需要根据实际情况进行调整了。比如我还需要把 SSL 的证书和私钥拷贝到新的 vps 上使用。

最后的最后就是修改 DNS 的指向了,等到 DNS 缓存时间超时后,大家就能访问到新的 vps 了。

其他

看了下居然有一年多没有更新过 Blog 了:(,以后要勤奋点,争取多多更新。


现在 IE11 已经支持 SPYD 协议了,不过在我测试后发现他和 Fx, Chrome 等其他浏览器所使用 TLS 扩展协议不一样。
SPDY 简介中说到过,由于 SPDY 并没有一个确定的端口号,因此现有的 SPDY 协议都是跑在 HTTPS 的 443 端口上的,但是客户端和服务器端在 SSL 协商完成之后,服务器并不知道你是要使用 HTTP 还是 SPDY 协议,因此需要在进行 SSL 协商的同时,将上层的应用层协议给协商出来。
以前 Fx 和 Chrome 是通过 NPN 扩展来进行的协商,而 IE11 则是使用的其他的协议,使用 wireshark 抓包后看到的扩展为“Extension: Unknown 16”,表示认不出来……在 Google 了一番之后,终于找到了其协议的文档,同时也知道了该扩展的名字:ALPN

NPN

NPN 的全称为 Next Protocol Negotiation,其 RFC 草案已经过期了,基本的协商流程如下:

Client                                      Server

ClientHello (NPN extension)  -------->
                                            ServerHello (NPN extension &#038; list of protocols)
                                            Certificate*
                                            ServerKeyExchange*
                                            CertificateRequest*
                             <--------      ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
EncryptedExtensions
Finished                     -------->
                                            [ChangeCipherSpec]
                             <--------      Finished
Application Data             <------->      Application Data

流程描述:

  1. 客户端通过 ClinetHello 发送一个空的 NPN 扩展字段
  2. 服务端通过 NPN 扩展返回支持的协议列表
  3. 客户端在 ChangeCipherSpec 之后 Finished 之前发送 EncryptedExtensions 选择某一个协议

ALPN

ALPN 的全称为 Application Layer Protocol Negotiation,做为 NPN 的替代者,其基本的协商流程如下:

Client                                                          Server

ClientHello (ALPN extension &#038; list of protocols)  -------->
                                                                 ServerHello (ALPN extension &#038; selected protocols)
                                                                 Certificate*
                                                                 ServerKeyExchange*
                                                                 CertificateRequest*
                                                  <--------      ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished                                          -------->
                                                                 [ChangeCipherSpec]
                                                  <--------      Finished
Application Data                                  <------->      Application Data

流程描述:

  1. 客户端通过 ALPN 扩展将自己支持的应用层协议发送给服务端
  2. 服务端选择其中某个协议,并将结果通过 ALPN 扩展发送给客户端
  3. SSL 协商完成后进行正常通讯

两者的区别

  • NPN 是服务器发送协议列表,由客户端进行选择。而 ALPN 则是客户端发送列表,由服务端选择
  • 在 NPN 中,最终的选择结果是在 ChangeCipherSpec 之后发送给服务端的,也就是说是被加密了的。而在 ALPN 中,所有的协商都是明文的
  • 在 NPN 中,为了防止服务器支持的协议泄露,客户端可以选择一个不在服务器端给出的列表中的协议。而 ALPN 中,服务器端只能选择在客户端发送的列表中的某个协议。

基本的区别就是以上几点,虽然看起来两者差别不大,不过似乎现在 NPN 协议已经被弃用,以后 Chrome 和 Google 的服务器都将支持 ALPN,而慢慢将 NPN 给淘汰掉。

参考链接