2017年5月1日星期一

虚拟机中网桥和vlan tag的配置

为提高物理机做虚拟化的利用率,有时物理机的上联交换机端口需要是trunk模式;为保证高可用,物理机的两块网卡需要做bonding;虚拟机的网络一般是用桥接模式;为了保证安全,虚拟机网卡只桥接到指定的bridge上。bonding,vlan tag,bridge的配置一般如下:

eth0和eth1配置:

DEVICE=eth0
ONBOOT=yes
MASTER=bond0
SLAVE=yes

bond0 配置:

#配置默认bonding,用以配置宿主机默认bridge以及宿主机管理地址
DEVICE=bond0
ONBOOT=yes
BRIDGE=bridge0
VLAN=yes
ONBOOT=yes
ARP=no

bond0.X 配置:

#配置带有tag的bonding,用以配置对应的bridge
DEVICE=bond0.X
ONBOOT=yes
BRIDGE=bridgeX
VLAN=yes
ONBOOT=yes
ARP=no

bridge0配置:

#配置默认bridge,用以配置宿主机管理地址
DEVICE=bridge0
ONBOOT=yes
TYPE=Bridge
BOOTPROTO=none
IPADDR=IPADDRESS
NETMASK=NETMASK
STP=off
DELAY=0
BRIDGING_OPTS="max_age=0 ageing_time=0"
GATEWAY=GATEWAY

bridgeX配置:

#配置业务bridge,每个bridge只转发包含相应tag的流量
#虚拟机根据业务不同,桥接到不同的bridgeX即可
DEVICE=bridgeX
ONBOOT=yes
TYPE=Bridge
BOOTPROTO=none
STP=off
DELAY=0
BRIDGING_OPTS="max_age=0 ageing_time=0"

以上配置在bond0.X处解tag,然后将流量分发到不同的bridgeX上,每个bridgeX只能转发解除tag后vlanX的流量。虚拟机桥接到bridgeX,因此也只能获取到指定的vlanX的流量,保证虚拟机隔离在一个vlan中。
还有一种配置是不在bond0上做解tag动作,而是在bridge0上设定tag,创建bridge0.X,bridge0从而可转发所有流量,虚拟机桥接到bridge0,虚拟机可以通过配置不同的vlan接口来获取所有流量,这样会带来一定的不安全因素。

PXE和iPXE

1. PXE原理概述

PXE(preboot execute environment)是Intel公司开发的技术,目前普遍应用于服务器中。PXE通过网络启动操作系统,在启动流程如下:
  • 服务器发送dhcp请求
  • dhcp-server 响应dhcp请求,分配ip地址,并且返回next-server(tftp服务器地址)和filename(一般为pxelinux.0)
  • 服务器获得ip地址,然后通过tftp协议从next-server下载pxelinux.0
  • pxelinux.0读取tftp-server上pxelinux.cfg目录下的配置
  • pxelinux.0展示界面,根据用户输入的选项进行安装或者启动
dhcp-server上/etc/dhcpd.conf的配置:
  next-server 10.127.201.199;
  filename pxelinux.0;
tftp-server一般通过xinet.d服务启动,/etc/xinetd.d/tftp配置如下:
  service tftp
  {
          socket_type             = dgram
          protocol                = udp
          wait                    = yes
          user                    = root
          server                  = /usr/sbin/in.tftpd
          server_args             = -s /var/lib/tftpboot
          disable                 = no
          per_source              = 11
          cps                     = 100 2
          flags                   = IPv4
  }
  
/var/lib/tftpboot 一般包含文件:
  • pxelinux.cfg目录,文件读取顺序为服务器MAC地址,服务器dhcp获取的ip和网段,default文件,即如下顺序:
    • pxelinux.cfg/01-MACADDRESS
    • pxelinux.cfg/C0A8000F
    • pxelinux.cfg/C0A8000
    • pxelinux.cfg/C0A800
    • pxelinux.cfg/C0A80
    • pxelinux.cfg/C0A8
    • pxelinux.cfg/C0A
    • pxelinux.cfg/C0
    • pxelinux.cfg/C
    • pxelinux.cfg/default
  • pxelinux.0
  • 操作系统kernel和initrd文件

2. IPXE 原理概述

PXE有诸多不变之处,IPXE是对PXE的修改,对PXE做了更好的扩展,支持获取服务器上更多的信息,如序列号等等。但是由于物理机目前只支持PXE的方式,所以首先要将PXE启动转换为IPXE启动,才能使用IPXE的便利之处。IPXE流程如下:
  • 服务器 第一次 发送dhcp请求
  • dhcp-server 响应dhcp请求,分配ip地址,并且返回next-server(tftp服务器地址)和filename(一般为undionly.kpxe)
  • 服务器通过tftp协议下载unidonly.kpxe文件
  • undionly.kpxe 第二次 发送dhcp请求
  • dhcp-server 响应dhcp请求,分配ip地址,并且返回一个URL
  • 服务器访问URL,并将硬件信息(如sn)作为参数传递,然后获取根据sn生成的ipxe脚本
  • 服务器执行ipxe脚本,通过http协议下载操作系统kernel和initrd
  • 服务器利用kernel和initrd正常引导
dhcp-server上/etc/dhcpd.conf的配置:
  # 如果是ipxe发送的dhcp请求,表示服务器是在第二次dhcp请求过程中,返回URL,要求服务器将sn作为参数来访问此URL
  if exists user-class and ( option user-class = "iPXE" ) {
      filename "http://10.127.201.97/cgi-bin/ipxe.py?sn=${serial}";
  }
  # 如果不是ipxe发送的dhcp请求,表示服务器是在第一次dhcp请求过程中,返回unidonly.kpxe 文件
  else {
      filename "undionly.kpxe";
  }
  
ipxe.py接收到服务器sn,然后返回对应的ipxe脚本信息,ipxe脚本信息一般如下:
  #!ipxe
  
  set net0/ip IPADDRESS
  set net0/netmask 255.255.255.0
  set net0/gateway GATEWAY
  set dns DNSSERVER
  
  :START
  menu Please choose an operating system to boot
  item --gap --          ------------------------- OS Installation --------------------------------
  item OPERATIONSYSTEM OPERATIONSYSTEM
  choose --default OPERATIONSYSTEM --timeout 5000 os
  goto ${os}
  
  :OPERATIONSYSTEM
  echo Starting install for OPERATIONSYSTEM
  set baseurl http://ks.vip.split.hdb.com/base/OPERATIONSYSTEM/images/pxeboot
  kernel ${baseurl}/vmlinuz
  initrd ${baseurl}/initrd.img
  imgargs vmlinuz text ksdevice=link ramdisk_size=8192 biosdevname=0 sshd=1 ks=http://ks.vip.split.hdb.com/ksconf/OPERATIONSYSTEM.cfg noipv6 ip=IPADDRESS netmask=255.255.255.0 gateway=GATEWAY dns=DNSSERVER
  boot || goto FAILED
  goto START
  

2014年3月27日星期四

利用virsh和virt-install安装管理虚拟机

配置环境+构建思想:

1 宿主机采用kvm做虚拟化
2 网络采用bridge模式
3 硬盘采用lvm管理
4 根据宿主机配置,每台宿主机上分配12个计算单元,根据计算单元计算虚拟机使用的内存,cpu个数,lv数量
5 宿主机初始化的时候创建12个lvfree-XX命名的lv,假定虚拟机使用4个部署单元
6 创建虚拟机的时候,删除4个lvfree-XX,创建一个lvused-XX-4
7 根据统计lvfree-XX的个数,可以知道宿主机的剩余资源
8 虚拟机下线的时候,删除配置文件,删除lvused-XX-4,创建4个lvfree-XX

 

宿主机安装:

前期基本与普通机器安装相同,所有操作在ks的%post 阶段处理。

1 创建bonding和桥,配置:

内核启动参数加上biosdevname=0,避免将网卡识别为em

ifcfg-eth0:
DEVICE=eth0
ONBOOT=yes
MASTER=bond0
SLAVE=yes

ifcfg-bond0:
DEVICE=bond0
ONBOOT=yes
BONDING_OPTS="''"
BRIDGE=br0

ifcfg-br0:
DEVICE=br0
ONBOOT=yes
TYPE=Bridge
IPADDR=192.168.0.1
NETMASK=255.255.255.0
STP=off
DELAY=0
BRIDGING_OPTS="max_age=0 ageing_time=0"

/etc/modprobe.d/bond0.conf
alias bond0 bonding
options bond0 miimon=100 mode=1 primary=eth0

a) bonding 配置需要加入到modprobe.d 中,否则网络有问题
b) BRIDGE需要加入max-age和ageing-time的配置,否则虚拟机安装时,dhcp无法取得地址

2 创建lvm

vgcreate pool /dev/sda1
for i in `1 12`; do lvcreate -n free$i -L120G pool ; done

3 启动messagebus和libvirtd服务

 若使用默认网络配置libvirtd还依赖avahi-daemon服务,并会同时启动dnsmasq
/etc/init.d/messagebus start
/etc/init.d/libvirtd start

4 删除默认的nat网络

virsh net-destroy default
virsh net-undefine default

5 初始化 storage-pool,设置pool自动启动,pool-refresh中,lv自动转化为storage volume.

virsh pool-create-as pool logical --target /dev/pool
virsh pool-dumpxml pool >pool.xml
virsh pool-define pool.xml
virsh pool-autostart pool
virsh pool-refresh pool

6 添加virsh console支持

echo ttyS0 >>/etc/securetty

7 宿主机内核参数调整:

for i in /proc/sys/net/bridge/bridge-nf-*; do echo 0 >$i  ; done

宿主机安装完毕,重启即可。
 

虚拟机安装

假定虚拟机使用4个计算单元

1 删除lvfree,创建lvused

for i in `seq 1 4`; do  virsh vol-delete --pool pool lvfree$i  ;done
virsh vol-create-as --pool pool --name lvused-XX-4 --capacity=480G

2 virt-install

virt-install --hvm                                        #全虚拟化
--wait=-1                                                 #virt-install运行时的超时时间,不设置为-1,虚拟机安装完毕无法自动启动
--graphics vnc,listen=0.0.0.0,port=5900      #vnc设置
--virt-type=kvm                                         #虚拟化软件
--autostart                                                #宿主机启动后,虚拟机自动启动
--noautoconsole                                        #安装时候不连接console
-n guest_v1                                               # virsh list 时候显示的名字,为方便,直接设置为主机名
-r 4096                                                     #内存4G
--vcpus 8                                                  #使用 8个cpu
--disk vol=pool/lvused-XX-4,bus=virtio         #硬盘格式为storage volume,指定方式为 POOL/VOLUME,使用virtio驱动,在虚拟机中识别为vda
--mac==00:16:3e:aa:bb:cc                        #mac地址
--network bridge=br0,model=virtio              #网络采用桥接,使用virtio驱动
-l http://192.168.0.1/repo/rh62-x86-64        #指定安装源,系统会自动寻找kernel和initrd文件
-x "console=ttyS0 serial pip=192.168.1.1 phn=guest_v1 ks=http://192.168.0.1/ksconf/rh62-x86-64.cfg papp=guest" #内核额外参数,console保证可以连接;后面设置了ip,主机名,ks.cfg路径,以及ks安装的时候采用的应用配置

3 虚拟机调整/etc/adjtime 最后一行由LOCAL为UTC

虚拟机下线

删除lvused,创建lvfree

virsh destroy guest_v1
virsh undefine guest_v1
virsh vol-delete --pool pool lvused-XX-4
for i in `seq 1 4`; do  virsh vol-create-as --pool pool --name lvfree-$i --capacity=120G

其他

1 virt-install 高版本支持--clock=LOCAL参数,加此参数后,无需调整虚拟机的/etc/adjtime
2 virt-install 和 virsh加入--connect=qemu+ssh://192.168.1.2/system 后,可以通过ssh通道远程安装和管理虚拟机,除了采用ssh外,还可以采用TLS验证,原理是证书验证,需要下发server和client证书

2012年4月17日星期二

DNS 主从同步的NOTIFY机制

DNS的NOTIFY机制是主从同步使用的,master所控制的zone的序列号变动了以后,会主动通知slave更新,详情可见rfc1996 

1 过程
master slave使用 udp 53端口进行通讯,首先 master 向 slave 的udp53发送一个NOTIFY请求包,slave接收后,向master的udp53发送一个NOTIFY响应包,然后 slave 连接到 master 查询SOA信息,根据序列号判断是否请求进行IXFR传输。

2 相关配置
NOTIFY 的对象默认是有变动的zone的所有NS记录。除此之外,在bind中还通过配置also-notify 指定需要将NOTIFY请求发送到哪些服务器,这些服务器被称为 Stealth Server。bind中还有个配置选项notify,取值可以为yes,no,explicit。yes是默认选项,no表示不发送NOTIFY请求,explicit表示仅发送NOTIFY请求给also-notify中的服务器。

master如果配置了多个IP,则可以通过 notify-source 指定源IP地址。否则如果slave配置了其它的IP为自己的master,则会造成slave误以为收到了错误的NOTIFY请求而无法同步。(rfc1996 3.10)为保证安全,还可以配置allow-notify,来限制哪些master可以向本机发送NOTIFY请求。

如果使用udp进行通讯,master为了避免同时并发量太高,会间隔一段时间(60秒)再发送NOTIFY请求,如果发送请求次数超过5次,则不再向slave发送NOTIFY请求。但是在bind中,我未发现配置选项。

如果配置了多个master,这些master数据由于延时原因可能会不一致,因此slave会向发送NOTIFY请求的master进行同步。

slave 收到相同的NOTIFY请求后,在本次更新结束前,将暂缓响应其它的NOTIFY请求。

2012年4月8日星期日

shell 按行读取变量的值或者命令的输出

shell 中可以使用 while 按行读取一个文件,同时也可以使用 while 按行读取一个变量的值,或者一个命令的输出。方法有4种,分别是进程替换,管道,here document 和here string.

进程替换:  

#! /bin/bash
var=$(cat urfile)
echo "Process Substitution"
while read line
do
    echo "$line"
done < <(echo "$var")

管道:

#! /bin/bash
var=$(cat urfile)
echo "Pipe"
echo "$var" | while read line
do
    echo "$line"
done

here document:

#! /bin/bash
var=$(cat urfile)
echo "Here Document"
while read line
do
    echo "$line"
done <<EOF
$var
EOF


here string:

#! /bin/bash
var=$(cat urfile)
echo "Here String"
while read line
do
    echo "$line"
done <<< "$var"

2012年3月18日星期日

Xwindow 的相关概念



X 就像http,ftp一样是个网络协议,目前的版本是11,release号是7。该协议同样具有Server和Client的概念。X Server的作用是接收客户的请求,绘制客户请求的图形,并把客户的消息传递给X Client端。即X Server的用途是绘图,具体该如何绘制,则是由X Client端提供了绘图数据。根据X Server接收请求和绘制图形这两个功能,可以清楚的看出X Server管理的是客户的输入设备(鼠标键盘)和输出设备(显示器)。所以运行在本地机器上的程序是X Server,远程服务器上的程序是X Client。

设想如下情况:用户点击了FireFox的关闭按钮之后的事情:X Server 通知 FireFox(Client端),客户点击关闭按钮了,你不打算做点神马事情?FireFox 于是开始执行退出命令,并告诉X Server,让我消失吧。于是X Server 不再显示FireFox的窗口。

再设想如下情况:用户通过ssh到远程服务器A,启动一个 X Client 程序(比如FireFox),让该程序通过网络连接到本地的X Server绘制图形;然后用户通过ssh到远程服务器B,启动一个X Client程序(比如xterm),也让该程序通过网络连接到本地的X Server绘制图形。这时,用户可以在自己的终端上同时看到A机器的FF和B机器的xterm。

X Client只提供了绘图数据,至于窗口在显示器的什么位置,X Client是完全不知道的。同时启动两个X client后,X Server 该如何排列窗口呢?这就需要Window Manage了。 最简单的Window Manage是twm。

以上是概念,openSUSE 使用的 XServer是 Xorg,配置文件在/etc/X11/xorg.conf.d,使用的WM是Kwin。X client 就很明显了,进行图形输出的程序都是X client。

可以运行 startx 启动 X server。 startx 是个shell脚本,主要用来读取 Xserver 和 X Client 的配置,然后调用 xinit 启动X server 和 X Client。读取参数的顺序:
  • X server 的参数方面:
    1. 使用 startx 后面接的参数;
    2. 若无参数,则找寻使用者HOME目录的文件,亦即 ~/.xserverrc
    3. 若无上述两者,则以 /etc/X11/xinit/xserverrc
    4. 若无上述三者,则运行 /usr/bin/X
  • X client 的参数方面:
    1. 使用 startx 后面接的参数;
    2. 若无参数,则找寻使用者家目录的文件,亦即 ~/.xinitrc
    3. 若无上述两者,则以 /etc/X11/xinit/xinitrc
    4. 若无上述三者,则运行 xterm
分析openSUSE的 /etc/X11/xinit/xserverc 文件,可以看出实际就是调用X命令来启动X Server的,只是在调用命令前,又通过读取一些文件,配置了环境变量。调用 X 启动 X Server 后,Xorg 会去读取 /etc/X11/xorg.conf 这个配置文件。单纯的 X 启动时,会看到画面漆黑,中心有个可以移动的鼠标的光标。

分析openSUSE的 /etc/X11/xinit/xinitrc 文件,可以看出最后实际调用startkde 或者 gnome-session 来启动桌面环境。

直接调用 X 命令自行启动X Server:X :1 &。:1 表示将X Server启动在哪个终端上,调用该命令后,通过切换终端可以看到一个黑色背景加一个光标。
运行 xterm -display :1 &,可以在终端上看到一个xterm,但是这个xterm没有标题栏,无法移动,可以在里面敲几个命令观察一下。
再次运行 xterm -display :1 &,可以在终端上看到一个全新的xterm,这个xterm覆盖了第一次启动的xterm,同样没有标题栏,无法移动,第一次启动的xterm找不到了。
可以通过启动一个窗口管理器(如twm)来解决此问题。运行twm -display :1 &,可以看到xterm有了标题栏,可以关闭,拖动等等。
这就是X Server,X Client 和 WM 之间的关系。

本地的 X Server 和 X Client 通过socket来通讯,因此6000端口默认是看不到开放的。

更详细的可以参考鸟哥:http://vbird.dic.ksu.edu.tw/linux_basic/0590xwindow.php



2012年3月1日星期四

主从dns服务器view中的数据利用Tsig同步

TSIG同步有两个要点,搞清楚这两个要点,就不会配置错了。
1 每个view需要match一个不同的key,并且allow-transfer中也配置此key。
2 slave的ip不能在master的任何一个view中(any这个view例外)。原因:slave在同步的时候会向master查询对应zone的SOA序列号,如果slave的ip在master中的某个view中,将导致每次查询的soa记录都是此view中的记录,而并非对应的key的view中的记录,因此可能造成无法同步数据,或者同步了其它view中的数据。
 
简单的方式可以这么做:master 的 match-clients 只有 key 而没有任何 ip。这种情况下 master 只能用来更新dns记录并传输记录,而不能作为授权 dns 或者 local dns 使用。这样就避免了在master的match-clients中配置多个诸如 !10.0.0.1 这种acl了。

EXAMPLE:

Master 10.20.149.60
Slave 10.20.149.36

主dns配置:
view "view1" {
        match-clients {key idc-key;};
        allow-transfer {key idc-key;};
        allow-update {key idc-key;};
        also-notify {10.20.149.36;};
        server 10.20.149.36 { keys {idc-key;}; };
        zone "example.com" IN {
        type master;
        file "view/idc/hosts.example.com";
    };
};

从dns配置:
view "view1" {
        match-clients {key idc-key; 10.0.0.0/8; };
        allow-transfer {key idc-key;};
        server 10.20.149.60 {keys idc-key;};
        zone "example.com" IN {
        type slave;
        masters { 10.20.149.60; };
        file "view/idc/hosts.example.com";
    };
};

从dns也可以如此配置:
view "view1" {
        match-clients {key idc-key; 10.0.0.0/8; };
        allow-transfer {key idc-key;};
        zone "example.com" IN {
        type slave;
        masters { 10.20.149.60 keys idc-key;};
        file "view/idc/hosts.example.com";
    };
};