Fork me on GitHub
Suzf  Blog

Archive Linux

KVM 主机克隆

*** 克隆必须为关闭或者暂停状态下进行 ***

1. virt-clone

virt-clone -o hello_kvm -n hello_world -f /opt/data/kvm/images/hello_kitty.img

-o ORIGINAL_GUEST, --original=ORIGINAL_GUEST    原始客体的名称
-n NEW_NAME, --name=NEW_NAME                    新客户端的名称
-f NEW_DISKFILE, --file=NEW_DISKFILE            作为新客户端磁盘映像的新文件

2. 通过复制虚拟机的配置文件和磁盘映像文件进行克隆
复制文件 修改配置
详细过程 略

 

KVM 磁盘管理

获取磁盘信息
# qemu-img  info /opt/data/kvm/images/hello_kvm.img
image: /opt/data/kvm/images/hello_kvm.img
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 1.1G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: true
创建磁盘镜像文件
# qemu-img create -f qcow2 ubuntu.img 20G
磁盘扩容
# qemu-img resize /opt/data/kvm/images/hello_kvm.img  +5G
Image resized.
# qemu-img  info /opt/data/kvm/images/hello_kvm.img
image: /opt/data/kvm/images/hello_kvm.img
file format: qcow2
virtual size: 15G (16106127360 bytes)
disk size: 1.1G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: true

# virsh destroy hello_kvm
# virsh start   hello_kvm
# virsh console hello_kvm

# fdisk  /dev/vda
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p

Disk /dev/vda: 16.1 GB, 16106127360 bytes, 31457280 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000dd1eb

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048     1026047      512000   83  Linux
/dev/vda2         1026048    20971519     9972736   8e  Linux LVM

Command (m for help): n
Partition type:
   p   primary (2 primary, 0 extended, 2 free)
   e   extended
Select (default p): p
Partition number (3,4, default 3):
First sector (20971520-31457279, default 20971520):
Using default value 20971520
Last sector, +sectors or +size{K,M,G} (20971520-31457279, default 31457279):
Using default value 31457279
Partition 3 of type Linux and of size 5 GiB is set

Command (m for help): p   

Disk /dev/vda: 16.1 GB, 16106127360 bytes, 31457280 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000dd1eb

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048     1026047      512000   83  Linux
/dev/vda2         1026048    20971519     9972736   8e  Linux LVM
/dev/vda3        20971520    31457279     5242880   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
# 分区生效
partprobe
# 查看分区
# df -Th --total
Filesystem              Type      Size  Used Avail Use% Mounted on
/dev/mapper/centos-root xfs       8.5G  788M  7.7G  10% /
devtmpfs                devtmpfs  236M     0  236M   0% /dev
tmpfs                   tmpfs     245M     0  245M   0% /dev/shm
tmpfs                   tmpfs     245M  4.4M  241M   2% /run
tmpfs                   tmpfs     245M     0  245M   0% /sys/fs/cgroup
/dev/vda1               xfs       497M  120M  378M  25% /boot
total                   -         9.9G  912M  9.1G   9% -
# 创建物理卷
# pvcreate /dev/vda3
  Physical volume "/dev/vda3" successfully created

# vgs
  VG     #PV #LV #SN Attr   VSize VFree
  centos   1   2   0 wz--n- 9.51g 40.00m
把物理卷分区加进卷组
# vgextend centos /dev/vda3
  Volume group "centos" successfully extended

# vgs
  VG     #PV #LV #SN Attr   VSize  VFree
  centos   2   2   0 wz--n- 14.50g 5.04g

# lvextend -L +2G /dev/mapper/centos-root
  Size of logical volume centos/root changed from 8.47 GiB (2168 extents) to 10.47 GiB (2680 extents).
  Logical volume root successfully resized


XFS
# xfs_growfs /dev/mapper/centos-root
meta-data=/dev/mapper/centos-root isize=256    agcount=4, agsize=555008 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=2220032, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2220032 to 2744320

EXT
resize2fs /dev/mapper/centos-root
添加虚拟磁盘
# mkdir /opt/data/kvm/disk
# qemu-img create -f qcow2 /opt/data/kvm/disk/hello_kvm.qcow2 5G

# virsh destroy hello_kvm
# virsh edit hello_kvm
添加新的磁盘
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/opt/data/kvm/disk/hello_kvm.qcow2'/>
      <target dev='vdb' bus='virtio'/>
    </disk>


# virsh start hello_kvm
[[email protected] ~]# fdisk -l /dev/vdb

Disk /dev/vdb: 5368 MB, 5368709120 bytes, 10485760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


# mkfs [-t <type>] /dev/vdb
# vim /etc/fstab
# mount -a

KVM console 配置

*** All os system is CentOS7 *** 通过 vnc 等软件 控制虚拟机及难免显得有些麻烦。 使用 virsh console 来进行登录来管理无疑是个不错的选择。

KVM 虚拟机安装

两种方式:

virt-manager
virt-install

virt-manager
virt-manager 是基于 libvirt 的图像化虚拟机管理软件,请注意不同的发行版上 virt-manager 的版本可能不同,图形界面和操作方法也可能不同。创建KVM虚拟机最简单的方法是通过virt-manager接口。

1. 需要对localhost进行连接配置
2. 对虚拟网络进行配置,默认为nat方式的“default”,可以新添加网桥方式,也可以使用btctl创建
3. 创建或添加存储,可以是逻辑卷,也可以硬盘文件

安装
yum install virt-manager -y

图形操作直接略过, 多点几下就会用了基本上。

virt-install
你可以通过使用 virt-install 命令行来创建客户虚拟机。
virt-install也可以以一种交互的形式  或者使用一部分的脚本来自动化创建虚拟机。
也可以将 virt-install 和 ks 文件结合起来 实现自动部署

查看帮助
# virt-install --help

请注意,你需要以root权限进行的virt-install命令。qemu-img 是一个相关的命令在virt-安装配置存储选项 之前可以使用。
一个重要的选项是--graphics选项,允许一个虚拟机的图形化安装。

举个栗子
本地安装

virt-install \
--connect qemu:///system \
--name kvm_node_name \
--ram 512 \
--vcpus 1 \
--hvm \
--disk path=/opt/data/kvm/images/kvm_node_name.img,size=10 \
--os-type linux \
--os-variant rhel7 \
--network bridge=br0 \
--noautoconsole \
--graphics vnc,listen=0.0.0.0 \
--location=/opt/data/kvm/iso/CentOS-7-x86_64-Minimal-1503-01.iso

通过网络安装 虚拟机

virt-install \
--name smile \
--ram 512 \
--vcpus 1 \
--disk path=/opt/data/kvm/images/smile.img,size=10 \
--os-type linux \
--os-variant rhel7 \
--network bridge=br0 \
--graphics none \
--console pty,target_type=serial \
--extra-args 'console=ttyS0,115200n8 serial' \
--location=http://mirrors.163.com/centos/6.7/os/x86_64/

指定 KS 文件

--extra-args="ks=ftp://lab.suzf.net/ks/myks.cfg"
or
--extra-args "ks=file:/myks.cfg"

指定 console

--console pty,target_type=serial \
--extra-args='console=tty0 console=ttyS0,115200n8 serial'

 

KVM 虚拟机管理

常用 virsh 命令
# virsh help
# virsh version

显示所有虚拟机
# virsh list --all

获取 domain ID
# virsh domid {domain-name or domain-uuid}

获取 domain name
# virsh domname {domain-id or domain-uuid}

获取 UUID
# virsh domuuid {domain-id or domain-name}

获取 虚拟机信息
# virsh dominfo {domain-id, domain-name or domain-uuid}

登录到指定的虚拟机
# virsh console domain-name
之后按回车键进入

# virsh console hello_kvm
Connected to domain hello_kvm
Escape character is ^]

[[email protected] ~]#

按 ctrl + ] 退出

暂停/恢复
# virsh suspend domain-name
# virsh resume  domain-name

保存/加载
# virsh save domain-name filename
# virsh restore filename

编辑虚拟机xml文件
# virsh edit domain-name

使用文本编辑器修改xml 使其生效
# virsh define  /path/to/domain-name.xml

启动/停止/强制停止/重启
# virsh start     domain-name
# virsh shutdown  domain-name
# virsh reboot    domain-name
注:
直接 shutdown/reboot 是不行的,使用的 acpid 接口 ,现在没有这个 接口,需要安装
yum install -y acpid acpid-sysvinit
/etc/init.d/acpid start

# virsh destroy   domain-name

开机自启动/取消
# virsh autostart domain-name
# virsh autostart --disable domain-name

彻底删除虚拟机
# virsh destroy  domain-name
# virsh undefine domain-name
# rm -rf /etc/libvirt/qemu/domain-name.xml
# rm -rf /var/lib/libvirt/images/domain-name.img

 

How-to setup KVM on CentOS7

概述
KVM即基于内核的虚拟机英语:Kernel-based Virtual Machine,缩写为 KVM),是一种用于Linux内核中的虚拟化基础设施,可以将Linux内核转化为一个hypervisor。KVM在2007年2月被导入Linux 2.6.20核心中,以可加载核心模块的方式被移植到FreeBSDillumos上。 KVM目前由Red Hat等厂商开发,对CentOS/Fedora/RHEL等Red Hat系发行版支持极佳。
系统架构图
kvm_arch  
性能构架概述
以下几点提供了 KVM 的简要概述,它适用于系统性能和进程/线程的管理: 使用 KVM 时,客机作为一个 Linux 的进程在主机上运行。 虚拟 CPU(vCPU)作为正常线程执行,由 Linux 调度器执行。 客机会继承诸如内核中的 NUMA 和大页面一类的功能。 主机中的磁盘和网络 I/O 设置对性能有显著影响。 网络流量通常通过基于软件的网桥传送。

[译] 使用 Docker 容器应该避免的 10 个事情

当你最后投入容器的怀抱,发现它能解决很多问题,而且还具有众多的优点:

第一:它是不可变的 – 操作系统,库版本,配置,文件夹和应用都是一样的。您可以使用通过相同QA测试的镜像,使产品具有相同的表现。

第二:它是轻量级的 – 容器的内存占用非常小。不需要几百几千MB,它只要对主进程分配内存再加上几十MB。

第三:它很快速 – 启动一个容器与启动一个单进程一样快。不需要几分钟,您可以在几秒钟内启动一个全新的容器。

但是,许多用户依然像对待典型的虚拟机那样对待容器。但是他们都忘记了除了与虚拟机相似的部分,容器还有一个很大的优点:它是一次性的。

容器的 准则 :
“容器是临时的”。


这个特性“本身”促使用户改变他们关于使用和管理容器的习惯;我将会向您解释在容器中不应该做这些事,以确保最大地发挥容器的作用。

1. 不要在容器中存储数据 –  容器可能被停止,销毁,或替换。一个运行在容器中的程序版本1.0,应该很容易被1.1的版本替换且不影响或损失数据。有鉴于此,如果你需要存储数据,请存在卷中,并且注意如果两个容器在同一个卷上写数据会导致崩溃。确保你的应用被设计成在共享数据存储上写入。

2. 不要将你的应用发布两份 –  一些人将容器视为虚拟机。他们中的大多数倾向于认为他们应该在现有的运行容器里发布自己的应用。在开发阶段这样是对的,此时你需要不断地部署与调试;但对于质量保证与生产中的一个连续部署的管道,你的应用本该成为镜像的一部分。记住:容器应该保持不变。

3. 不要创建超大镜像 – 一个超大镜像只会难以分发。确保你仅有运行你应用/进程的必需的文件和库。不要安装不必要的包或在创建中运行更新(yum更新)。

4. 不要使用单层镜像 – 要对分层文件系统有更合理的使用,始终为你的操作系统创建你自己的基础镜像层,另外一层为安全和用户定义,一层为库的安装,一层为配置,最后一层为应用。这将易于重建和管理一个镜像,也易于分发。

5. 不要为运行中的容器创建镜像 – 换言之,不要使用“docker commit”命令来创建镜像。这种创建镜像的方法是不可重现的也不能版本化,应该彻底避免。始终使用Dockerfile或任何其他的可完全重现的S2I(源至镜像)方法。

6. 不要只使用“最新”标签 – 最新标签就像Maven用户的“快照”。标签是被鼓励使用的,尤其是当你有一个分层的文件系统。你总不希望当你2个月之后创建镜像时,惊讶地发现你的应用 无法运行,因为最顶的分层被非向后兼容的新版本替换,或者创建缓存中有一个错误的“最新”版本。在生产中部署容器时应避免使用最新。

7. 不要在单一容器中运行超过一个进程 – 容器能完美地运行单个进程(http守护进程,应用服务器,数据库),但是如果你不止有一个进程,管理、获取日志、独立更新都会遇到麻烦。

8. 不要在镜像中存储凭据。使用环境变量 –不要将镜像中的任何用户名/密码写死。使用环境变量来从容器外部获取此信息。有一个不错的例子是postgres镜像。

9. 使用非root用户运行进程 – “docker容器默认以root运行。(…)随着docker的成熟,更多的安全默认选项变得可用。现如今,请求root对于其他人是危险的,可能无法在所有环境中可用。你的镜像应该使用USER指令来指令容器的一个非root用户来运行。”(来自 Docker镜像作者指南)

10. 不要依赖IP地址 – 每个容器都有自己的内部IP地址,如果你启动并停止它地址可能会变化。如果你的应用或微服务需要与其他容器通讯,使用任何命名与(或者)环境变量来从一个容器传递合适信息到另一个。

译文:使用 Docker 容器应该避免的 10 个事情  

作者:skyvoice7, 社会主义好

 

How-to setup Kubernetes to manage Docker Cluster on CentOS7

环境介绍
操作系统: CentOS Linux release 7.3.1611 (Core)
Kubernetes 版本: 1.5.2
Etcd 版本: 3.2.7
Docker 版本: 1.12.6
Flannel 版本: 0.7.1
主机信息

Role       service                               Hostname               IP Address
Master     kube-APIServer kubelet proxy etcd     k8s-master.suzf.net    172.16.9.50
Node1      kubelet proxy flannel docker          k8s-node1.suzf.net     172.16.9.60
Node2      kubelet proxy flannel docker          k8s-node2.suzf.net     172.16.9.70

准备工作
关闭防火墙

systemctl stop firewalld
systemctl disable firewalld

关闭selinux

sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0


Master 安装与配置

Etcd 安装与配置

yum install etcd -y
PS: 本文并没有搭建etcd集群,如果需要参见官方搭建etcd集群的指导教程
yum安装的etcd默认配置文件在/etc/etcd/etcd.conf。
编辑配置文件

# grep -v ^# /etc/etcd/etcd.conf
ETCD_NAME=k8s
ETCD_DATA_DIR="/var/lib/etcd/k8s.etcd"
ETCD_LISTEN_PEER_URLS="http://172.16.9.50:2380"
ETCD_LISTEN_CLIENT_URLS="http://172.16.9.50:4001,http://localhost:4001"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.9.50:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://172.16.9.50:4001"

启动 etcd 服务

# systemctl start  etcd.service

查看健康状态

# etcdctl cluster-health
member 9026e369ffe8e114 is healthy: got healthy result from http://172.16.9.50:4001
cluster is healthy

查看成员列表

# etcdctl member list
9026e369ffe8e114: name=k8s peerURLs=http://172.16.9.50:2380 clientURLs=http://172.16.9.50:4001 isLeader=true

Kube Master 安装与配置

yum install kubernetes -y

修改Master节点kubernetes的全局配置文件 /etc/kubernetes/config

# grep -v '^#\|^$' /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=2"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://127.0.0.1:8080"

修改Master节点kubernetes apiserver的配置文件 /etc/kubernetes/apiserver

# grep -v '^#\|^$' /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=2"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://127.0.0.1:8080"
[[email protected] ~]# grep -v '^#\|^$' /etc/kubernetes/apiserver
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
KUBE_API_PORT="--port=8080"
KUBELET_PORT="--kubelet-port=10250"
KUBE_ETCD_SERVERS="--etcd-servers=http://172.16.9.50:4001"
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=192.168.0.0/16"
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"

启动Master节点的相关服务:etcd、kube-apiserver、kube-scheduler、kube-controller-manager,并将这些服务设为开机自动启动。

for SRV in etcd kube-apiserver kube-scheduler kube-controller-manager;
do
    sudo systemctl start ${SRV}
    sudo systemctl enable ${SRV}
    sudo systemctl status ${SRV}
done

在Master节点修改etcd的配置,设定Node中flannel所使用的子网范围为192.168.1.0 ~ 192.168.60.0(每一个Node节点都有一个独立的flannel子网)。

# etcdctl mk /suzf.net/network/config '{"Network":"192.168.0.0/16", "SubnetMin": "192.168.1.0", "SubnetMax": "192.168.60.0"}'
{"Network":"192.168.0.0/16", "SubnetMin": "192.168.1.0", "SubnetMax": "192.168.60.0"}

Node 安装与配置

yum install kubernetes-node docker flannel -y

修改Node上flannel的配置/etc/sysconfig/flanneld,设定etcd的相关信息,其中172.16.9.50 为master的IP地址。

Flannel 网络配置

# grep -v '^#\|^$'  /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://172.16.9.50:4001"
FLANNEL_ETCD_PREFIX="/suzf.net/network"

Kube node 配置

# grep -v '^#\|^$'  /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://172.16.9.50:8080"


# grep -v '^#\|^$' /etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=0.0.0.0"
KUBELET_PORT="--port=10250"
KUBELET_HOSTNAME=""
KUBELET_API_SERVER="--api-servers=http://172.16.9.50:8080"
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
KUBELET_ARGS=""

在Node上启动相关服务:flanneld、docker、kube-proxy、kubelet,并将这些服务设为开机自启动

for SRV in flanneld docker kube-proxy kubelet;
do
    sudo systemctl start ${SRV}
    sudo systemctl enable ${SRV}
    sudo systemctl status ${SRV}
done

在Master节点查看k8s集群状态

# kubectl get nodes -o wide
NAME             STATUS     AGE       EXTERNAL-IP
horse.suzf.net   Ready      6d        <none>
zebra            Ready      7m        <none>

查看flannel子网分配情况

# etcdctl ls /suzf.net/network/subnets
/suzf.net/network/subnets/192.168.53.0-24
/suzf.net/network/subnets/192.168.42.0-24

在Node节点通过ip a查看flannel和docker网桥的网络配置信息,确认是否与etcd中/coreos.com/network/subnets的信息一致。