关于 十一月, 2013 的文章

通过非XenCenter方式连接到XenServer各个VM的VNC本地界面

下面,就是我们在线上所使用的脚本,只需要你本地安装有一个VNC客户端就可以了。

获取本地VM列表
# ./getvnc

 
Usage: ./getvnc vm_name
VMs found:
idc2-server1                     
idc2-server2

获取指定VM的VNC端口号
# ./getvnc idc2-server2

 
run this on laptop and connect via vnc to localhost:5903 
--> ssh -L 5903:localhost:5903 root@10.100.1.30

接下来,直接在本地运行"ssh -L 5903:localhost:5903 root@10.100.1.30";
再通过VNC客户端连接"localhost:5903"就可以了。

脚本代码:

 
#!/bin/bash

vm=$1
if [ -z ${vm} ]; then
  echo "Usage: $0 vm_name"
  echo "VMs found:"
  xl list-vm | awk '{print $3}' | grep -vw name
  exit 1
fi

xe vm-list params=name-label name-label=${vm} | grep ${vm} > /dev/null
if [ $? -gt 0 ]; then
  echo "Error: invalid VM name"
  exit 1
fi

host=$(xe vm-list params=resident-on name-label=${vm} | grep resident-on | awk '{print $NF}')
dom=$(xe vm-list params=dom-id name-label=${vm} | grep dom-id | awk '{print $NF}')
port=$(xenstore-read /local/domain/${dom}/console/vnc-port)
ip=$(xe pif-list management=true params=IP host-uuid=${host} | awk '{print $NF}')

echo "run this on laptop and connect via vnc to localhost:${port}"
echo "--> ssh -L ${port}:localhost:${port} root@${ip}"

, ,

No Comments

XenServer 6.2 填坑之 LVM软件包降级

背景:
近期,因为新机房建设,有近30台高配的XenServer上架,随之而来的就是创建近300台虚拟机。
如果采用传统的方法,创建模板,然后手动更改IP地址,磁盘,CPU,内存等大小,会浪费很多时间,因此我一直在考虑将整个流程全部自动化。
最后经过一路填坑和试错,终于成功了。但这些不会在本文中展示,后面会有写文章来分享我的自动化脚本和VM模板。

在这一篇文章中,我要讲的是我此次遇到的最大的坑,而这个坑所有使用XenServer6.2的人都可能会遇到。
情况发生在我用脚本自动化创建VM的过程中,之前的几十台一直正常,结果等所有的创建完成之后。上去一看,后面几百台的VM磁盘居然都没有自动扩容,这不应该啊,所有的服务器环境应该都是相同的。

经过我的排错,发现在做resize的时候有如下报错:
[root@idc1-server4 ~]# xe vdi-resize uuid=786fb0eb-1fd1-4746-86a5-8facd4d0ebc2 disk-size=50GiB

 
Error code: SR_BACKEND_FAILURE_110
Error parameters: , VDI resize failed [opterr=Command ['/usr/sbin/lvcreate', '-n', 'inflate_786fb0eb-1fd1-4746-86a5-8facd4d0ebc2_21525168128', '-L', '4', 'VG_XenStorage-aa1cc675-5367-9a3a-14b9-85b0fc9400c0', '--addtag', 'journaler', '--inactive', '--zero=n'] failed (3): /usr/sbin/lvcreate: unrecognized option `--inactive'
Error during parsing of command line.], 

好端端的命令怎么会提示参数错误呢?经过一番搜索,发现了一位和我同样悲剧的老外:
http://www.experts-exchange.com/OS/Linux/Distributions/Q_28271130.html

接着经过一番检查,就不难发现一些坑爹的情况:
[root@idc1-server4 ~]# lvm version

 
  LVM version:     2.02.88(2)-RHEL5 (2013-06-25)
  Library version: 1.02.67-RHEL5 (2011-10-14)
  Driver version:  4.15.0

[root@idc1-server4 ~]# cat /etc/redhat-release

 
CentOS release 5.10 (Final)

系统应该是XenServer的,结果却变成了CentOS 5.10。

对比创建成功的XenServer:
[root@idc1-server1 ~]# lvm version

 
  LVM version:     2.02.84(2)-RHEL5 (2011-08-26)
  Library version: 1.02.63-RHEL5 (2011-06-10)
  Driver version:  4.15.0

[root@idc1-server1 ~]# cat /etc/redhat-release

 
XenServer release 6.2.0-70446c (xenenterprise)

然后再检查lvcreate命令所在的lvm2软件包:
[root@idc1-server1 ~]# rpm -qa | grep lvm2

 
lvm2-2.02.84-6.xs1120

[root@idc1-server4 ~]# rpm -qa | grep lvm2

 
lvm2-2.02.88-10.el5

版本果然不同,看上去主机idc1-server4上的lvm2要更新一些,但其实idc1-server1上的lvm2才是Citrix打了专门的patch之后的,支持功能更多。
于是我赶紧发了一封邮件,让所有人不要在XenServer上随意使用YUM安装软件,同时禁用了默认的CentOS-Base.repo。

但是问题还是要解决啊,上面的老美说直接重装XenServer,这个太伤了,那么多还要去机房现场操作,我会死掉的。

于是我开始辛辛苦苦的寻找lvm2-2.02.84-6.xs1120这个软件包,哈哈,Google的搜索结果为0条。
那么是不是就没救了呢?我继续尝试从XenServer的ISO里面去找,依然找不到。

最后,我愤怒了,直接到idc1-server1上将所有lvm2相关的文件打包,然后到有问题的服务器上强行卸载lvm2再解压。
就这样,我用暴力填好了这个坑,看着自己的脚本又能够不停的刷屏,自动创建VM,我感动的都快哭了。

 
[root@idc1-server2 dong]# ssh idc1-server1 'cd /tmp; rpm -ql lvm2-2.02.84-6.xs1120 > /tmp/lvm.list; tar -T /tmp/lvm.list -czf /tmp/lvm.tgz' 
tar: Removing leading `/' from member names
[root@idc1-server2 dong]# scp root@idc1-server1:/tmp/lvm.tgz /tmp/
lvm.tgz             100% 2113KB 704.2KB/s   00:03    
[root@idc1-server2 dong]# scp /tmp/lvm.tgz idc1-server4:/tmp/
lvm.tgz              100% 2113KB   2.1MB/s   00:01    
[root@idc1-server2 dong]# ssh idc1-server4 'rpm -qa | grep lvm2 | xargs rpm -e --nodeps'
warning: /etc/lvm/lvm.conf saved as /etc/lvm/lvm.conf.rpmsave
[root@idc1-server2 dong]# ssh idc1-server4 'cd /;tar xzf /tmp/lvm.tgz'

,

1 Comment

XCP/XenServer命令行方式自动化安装VM

背景介绍:
前面我的一篇文章《XCP/XenServer自动化创建并初始化虚拟机》中,讲解了如何通过传递内核参数,来克隆VM并以新的主机名,IP地址等进行初始化。
但是在这之前其实应该还有另外一个问题,就是第一个VM怎样才能自动化创建呢?为了解决这个问题,我咨询了不少的人,但是他们大多数给我的回答的都是,使用XenCenter。
但这并不是我们想要的,经过不断的试错之后,终于成功的完成了第一个VM的自动化安装,其实原理也很简单,就是通过命令行将VM初始化,绑定虚拟硬盘,网络,然后通过httprepo来网络加载ISO,再配合kickstart进行自动化安装。但是在很多具体的步骤上,却又是步步陷阱,一些很小的参数方面设置不正确都会导致失败,而这些,在官方文档中基本上算是被忽略了的。
下面是相关的具体步骤:

环境介绍:
httprepo: 192.168.92.128
xenserver: 192.168.92.140
vm: 192.168.92.142

1. 创建 http repo
# yum install httpd
# wget http://linux.mirrors.es.net/centos/6/isos/x86_64/CentOS-6.4-x86_64-minimal.iso

# mkdir -p /var/www/html/repo/centos/6
# mkdir /var/www/html/repo/ks
# mount -o loop CentOS-6.4-x86_64-minimal.iso /var/www/html/repo/centos/6/

# service httpd start

2. 创建 kickstart 配置文件
# vi /var/www/html/repo/ks/centos-6.4-x86_64-minimal.ks

 
cmdline
skipx
install
cdrom
lang en_US.UTF-8
keyboard us

network --onboot yes --device eth0 --bootproto=static --ip=192.168.92.142 --netmask=255.255.255.0 --gateway=192.168.92.2 --nameserver=192.168.92.2 --noipv6

rootpw mypasswd

firewall --service=ssh
authconfig --enableshadow --passalgo=sha512
selinux --disabled
timezone --utc Etc/UTC

bootloader --location=mbr --driveorder=xvda --append="crashkernel=auto"

zerombr
clearpart --all --initlabel
autopart

reboot

%packages --nobase
@core
%end

3. 自动安装VM
获取Local storage uuid
# xe sr-list | grep -C 1 "Local"

                uuid ( RO): fbeda99f-b5a7-3100-5e3d-fbb48a46fca0
          name-label ( RW): Local storage
    name-description ( RW): 

阅读全文 »

, , ,

No Comments

Percona XtraDB Cluster 功能测试

参考资料:
http://www.mysqlperformanceblog.com/2013/09/23/percona-xtradb-cluster-setting-simple-cluster/

背景介绍:
在我们的生产环境,目前还采用的是单节点的Mater对应多个Slave节点;为了避免Master单点故障,需要尝试其它方案;
类似于通过Keepalived(VIP)或MySQL-Proxy等的方式,应用的比较多,如MySQL MMM;
由于线上采用了Percona Server,因为Manager更推荐采用 Percona 官方的Auto-Failover方式或者XtraDB Cluster的方式,Auto-Failover方式我在上一篇文章中已经讲过了。
因此,本章节主要讲解XtraDB Cluster的功能测试情况。

环境介绍:
servers: demoenv-trial-1 demoenv-trial-2 demoenv-trial-3

1. 安装 Percona Server,在所有服务器上:
$ sudo yum install http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
$ sudo yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo yum install Percona-Server-shared-compat
$ sudo yum install Percona-Server-server-55 Percona-Server-client-55

2. 配置 /etc/my.cnf,在所有服务器上:
$ sudo vim /etc/my.cnf

[mysqld]
# basic settings
datadir = /opt/mysql/data
tmpdir = /opt/mysql/tmp
socket = /opt/mysql/run/mysqld.sock
port = 3306
pid-file = /opt/mysql/run/mysqld.pid

skip-external-locking
max_allowed_packet = 16M

# innodb settings
default-storage-engine = INNODB
innodb_file_per_table = 1
log-bin = /opt/mysql/binlogs/bin-log-mysqld
log-bin-index = /opt/mysql/binlogs/bin-log-mysqld.index
innodb_data_home_dir = /opt/mysql/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /opt/mysql/data
binlog-do-db = testdb

# server id
server-id=1

# other settings
[mysqld_safe]
log-error = /opt/mysql/log/mysqld.log
pid-file = /opt/mysql/run/mysqld.pid
open-files-limit = 8192

[mysqlhotcopy]
interactive-timeout

[client]
port = 3306
socket = /opt/mysql/run/mysqld.sock
default-character-set = utf8

3. 创建所需目录,在所有服务器上:
$ sudo mkdir -p /opt/mysql/{data,tmp,run,binlogs,log}
$ sudo chown mysql:mysql /opt/mysql/{data,tmp,run,binlogs,log}

4. 初始化数据库,在所有服务器上:
$ sudo -i
# su - mysql
$ mysql_install_db --user=mysql --datadir=/opt/mysql/data/
$ exit
# exit
$ sudo /etc/init.d/mysql start

5. 删除原有软件包,在所有服务器上:
因为XtraDB Cluster的软件包与原有软件包冲突:

Error: Percona-XtraDB-Cluster-client conflicts with Percona-Server-client-55-5.5.34-rel32.0.591.rhel6.x86_64
Error: Percona-XtraDB-Cluster-server conflicts with Percona-Server-server-55-5.5.34-rel32.0.591.rhel6.x86_64
Error: Percona-XtraDB-Cluster-shared conflicts with Percona-Server-shared-55-5.5.34-rel32.0.591.rhel6.x86_64

$ sudo /etc/init.d/mysql stop
$ sudo rpm -qa | grep Percona-Server | grep -v compat | xargs sudo rpm -e --nodeps
阅读全文 »

, ,

2 Comments

MySQL 官方 Auto-Failover 功能测试

参考资料:
http://www.clusterdb.com/mysql/replication-and-auto-failover-made-easy-with-mysql-utilities

环境介绍:
master: demoenv-trial-1
slaves: demoenv-trial-2 demoenv-trial-3

1. 安装 Percona Server,在所有服务器上:
$ sudo yum install http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
$ sudo yum install Percona-Server-shared-compat
$ sudo yum install Percona-Server-server-56

$ sudo yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo yum install mysql-utilities

2. 配置 /etc/my.cnf,在所有服务器上:
注意:确保 server-id 不同且 report-host 与自身主机名相同
$ sudo vim /etc/my.cnf

[mysqld]
# basic setting
datadir = /opt/mysql/data
tmpdir = /opt/mysql/tmp
socket = /opt/mysql/run/mysqld.sock
port = 3306
pid-file = /opt/mysql/run/mysqld.pid

# innodb setting
default-storage-engine = INNODB
innodb_file_per_table = 1
log-bin = /opt/mysql/binlogs/bin-log-mysqld
log-bin-index = /opt/mysql/binlogs/bin-log-mysqld.index
innodb_data_home_dir = /opt/mysql/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /opt/mysql/data
binlog-do-db = testdb

# server id
server-id=1

# gtids setting
binlog-format = ROW
log-slave-updates = true
gtid-mode = on
enforce-gtid-consistency = true
report-host = demoenv-trial-1
report-port = 3306
master-info-repository = TABLE
relay-log-info-repository = TABLE
sync-master-info = 1

# other settings
[mysqld_safe]
log-error = /opt/mysql/log/mysqld.log
pid-file = /opt/mysql/run/mysqld.pid
open-files-limit = 8192

[mysqlhotcopy]
interactive-timeout

[client]
port = 3306
socket = /opt/mysql/run/mysqld.sock
default-character-set = utf8

3. 创建所需目录,在所有服务器上:
$ sudo mkdir -p /opt/mysql/{data,tmp,run,binlogs,log}
$ sudo chown mysql:mysql /opt/mysql/{data,tmp,run,binlogs,log}

4. 初始化数据库,在所有服务器上:
$ sudo -i
# su - mysql
$ mysql_install_db --user=mysql --datadir=/opt/mysql/data/
$ exit
# exit
$ sudo /etc/init.d/mysql start

5. 创建授权用户 root@'%' 以便通过 mysqlreplicate 来进行主从复制的配置,在所有服务器上:
$ mysql -uroot

mysql> grant all on *.* to root@'%' identified by 'pass' with grant option;
mysql> quit;

6. 创建复制所需的用户,在所有服务器上:
$ mysql -uroot

mysql> grant replication slave on *.* to 'rpl'@'%' identified by 'rpl';
mysql> quit;

7. 配置主从复制,可选择任意一台服务器操作:
[dong.guo@demoenv-trial-1 ~]$ mysql -uroot

mysql> use mysql;
mysql> drop user root@'demoenv-trial-1';
mysql> quit;

[dong.guo@demoenv-trial-1 ~]$ mysqlreplicate --master=root:pass@'demoenv-trial-1':3306 --slave=root:pass@'demoenv-trial-2':3306 --rpl-user=rpl:rpl

# master on demoenv-trial-1: ... connected.
# slave on demoenv-trial-2: ... connected.
# Checking for binary logging on master...
# set up replication...
# ...done.

阅读全文 »

, ,

No Comments

XCP/XenServer自动化创建并初始化VM

参考资料:http://wiki.xenproject.org/wiki/XCP_Beginners_Guide

在我们的生产环境中,之前一直使用的是EC2的Instances做的前端服务器,在访问量增加的时候,通过设置一个阈值,超过阈值的就自动触发创建一定数量的新的Instances,在访问量低于某一个值的时候,就自动删除一定数量的Instances;由于AWS可以根据设置好的模板复制出一个新主机并且给予一个新的IP地址,所以只需要管理好主机名就是了;这方面,我们通过一个Redis数据库来管理主机名的ID,创建主机的时候会自动根据最大的ID依次递增,而删除主机的时候会自动根据最大的ID依次递减。
但这并不是我这篇文章要讲的重点,要实现这种自动伸缩,方法有很多,我们就是通过很多简单的脚本来实现的。

后来,我们建立了本地机房,购买了一定数量的物理服务器,每台服务器安装了XCP,并打算在上面创建虚拟机。之前我们一直通过的是XenCenter的方式,图形化的操作来创建,但是要实现和上面EC2一样的自动化创建主机的话,我们遇到了一个问题,那就是,每台新建的VM,其IP地址与主机名等在复制之后,不能自动更新。我请教过一些同行,可能是他们并没有这样大规模的使用XCP/XenServer,所以都是在XenCenter里面创建好机器,然后通过console进去修改IP地址和主机名等等。

于是乎,我就在Google上反复搜索,最终找到了一个解决办法。那就是通过修改VM的内核引导程序,将自定义的参数传递给一个叫PV-args的内核参数,这样在VM启动之后就可以通过/proc/cmdline中获取到参数了,在获取到之后,VM在第一次启动时,会执行一个Shell脚本,来根据自定义的参数更新IP地址和主机名等;这样,一台新创建好的VM就可以自动连接到Puppet这样的管理工具了,接着再自动拉取最新的配置,完成整个服务器的自动化配置,然后上线。

环境介绍:
xenhost1 一台物理XCP/XenServer主机
vm-template 之前定义好的模板
vm-host-1 将要创建的VM

以下,就是我的具体操作记录:
获取vm-template的uuid
[root@xenhost1 ~]# xe vm-list | grep -B 1 vm-template

uuid ( RO)           : c77040ae-3a50-9217-ff03-41992c34d1ec
     name-label ( RW): vm-host-1

修改内核启动方式,并传递自定义参数
[root@xenhost1 ~]# xe vm-param-set uuid=c77040ae-3a50-9217-ff03-41992c34d1ec HVM-boot-policy=""
[root@xenhost1 ~]# xe vm-param-set uuid=c77040ae-3a50-9217-ff03-41992c34d1ec PV-bootloader="pygrub"
[root@xenhost1 ~]# xe vm-param-set uuid=c77040ae-3a50-9217-ff03-41992c34d1ec PV-args="_hostname=vm-template _ipaddr=192.168.1.121 _netmask=255.255.255.0 _gateway=192.168.1.1"

启动vm-template
[root@xenhost1 ~]# xe vm-start vm=vm-template

获取自定义参数
[root@vm-template ~]# cat /proc/cmdline

ro root=/dev/mapper/vg_t-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 rd_LVM_LV=vg_t/lv_root crashkernel=129M@0M  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet  _hostname=vm-template _ipaddr=192.168.1.121 _netmask=255.255.255.0 _gateway=192.168.1.1

定义初始化脚本
[root@vm-template ~]# cat /etc/rc.local

#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local
/root/bootstrap.sh

创建具体的脚本
[root@vm-template ~]# touch /root/bootstrap.sh
[root@vm-template ~]# chmod +x /root/bootstrap.sh
阅读全文 »

, , ,

8 Comments