标签(空格分隔): kubernetes系列
一:kubevirt 的简介
KubeVirt是一个Kubernetes插件,它为Kubernetes提供了在与容器相同的基础结构上提供、管理和
控制虚拟机的能力。KubeVirt是由云原生计算基金会(CNCF)赞助的开源项目,目前正处于孵化阶段。
KubeVirt使Kubernetes能够使用与容器化工作负载相同的工具来调度、部署和管理虚拟机,
从而消除了使用不同监视和管理工具的单独环境的必要性。为虚拟机和Kubernetes一起工作提供了可能。
使用KubeVirt,您可以声明:
创建虚拟机
在Kubernetes群集上调度虚拟机
启动虚拟机
停止虚拟机
删除虚拟机
虚拟机运行在Kubernetes pod中,并利用标准的Kubernetes网络和存储。
如果你嫌上面的架构图太繁琐,这里还有一个简化版:
重要组件:
1. virt-api
(1) HTTP API Server作为所有涉及虚拟化相关的处理流程的入口(Entry Point),负责更新、
验证VMI CRDs;
(2) 提供RESTful API来管理集群中虚拟机,Kubevirt采用CRD的工作方式,virt-api
提供自定义的API请求处理流程,如VNC、 Console、 Start/Stop虚拟机;
2. virt-controller
(1) 该控制器负责监控虚拟机实例VMI对象和管理集群中每个虚拟机实例VMI的状态以及与其相关的Pod;
(2) VMI对象将在其生命周期内始终与容器关联,但是,由于VMI的迁移,容器实例可能会随时间变化。
3. virt-handler
(1) 在K8S的计算节点上,virt-handler运行于Pod中,作为DaemonSet;
(2) 类似于virt-controller都是响应式的,virt-handler负责监控每个虚拟机实例的状态变化,
一旦检测到状态变化就响应并确保相应操作能达到所需(理想)状态;
(3) virt-handler负责以下几方面:保持集群级VMI Spec与相应libvirt域之间的同步;
报告Libvirt域状态和集群Spec的变化;调用以节点为中心的插件以满足VMI Spec定义的网络和存储要求。
4.virt-launcher
(1) 每个虚拟机实例(VMI)对象都会对应一个Pod,该Pod中的基础容器中运行着Kubevirt
核心组件virt-launcher;
(2) K8S或者Kubelet是不负责运行VMI的运行的,取而代之的是,群集中每个节点上的守护进程会
负责为每个Pod启动一个与VMI对象关联的VMI进程,无论何时在主机上对其进行调度。
(3) virt-launcher Pod的主要功能是提供cgroups和名称空间并用于托管VMI进程。
(4) virt-handler通过将VMI的CRD对象传递给virt-launcher来通知virt-launcher启动VMI。
然后virt-launcher在其容器中使用本地libvirtd实例来启动VMI。从此开始,
virt-launcher将监控VMI进程,并在VMI实例退出后终止;
(5) 如果K8S的Runtime在VMI退出之前试图关闭virt-launcher Pod时,
virt-launcher会将信号从K8S转发给VMI进程,并尝试推迟pod的终止,直到VMI成功关闭。
5.Libvirtd
(1) 每个VMI实例对应的Pod都会有一个libvirtd实例;
(2) virt-launcher借助于libvirtd来管理VMI实例的生命周期;
二:kubevirt实验安装
2.1 系统介绍与初始化
系统:
CentOS7.9x64
主机名:
cat /etc/hosts
----
172.16.10.11 flyfish11
172.16.10.12 flyfish12
172.16.10.13 flyfish13
172.16.10.14 flyfish14
172.16.10.15 flyfish15
172.16.10.16 flyfish16
172.16.10.17 flyfish17
-----
本次安装前4台机器,每个机器8core/8G/硬盘/dev/sda 100G,/dev/sdb 150G,/dev/sdc 100G,/dev/sdd
100G
ceph-rook 硬盘分配:
/dev/sda 系统盘
/dev/sdb metadevice 盘
/dev/sdc osd 盘
/dev/sdd osd 盘
vmware在线刷新硬盘命令
echo "- - -" >> /sys/class/scsi_host/host0/scan
echo "- - -" >> /sys/class/scsi_host/host1/scan
echo "- - -" >> /sys/class/scsi_host/host2/scan
系统关闭selinux / firewalld 清空 iptables 防火墙规则 做好无密钥认证登录。
yum -y install wget jq psmisc vim net-tools nfs-utils telnet yum-utils device-mapper-persistent-data lvm2 git network-scripts tar curl -y
# 关闭交换分区
sed -ri 's/.*swap.*/#&/' /etc/fstab
swapoff -a && sysctl -w vm.swappiness=0
cat /etc/fstab
# /dev/mapper/centos-swap swap swap defaults 0 0
#
## 关闭 SeLinux
# setenforce 0
# sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
# 修改内核参数
yum -y install bridge-utils
modprobe br_netfilter
vim /etc/sysctl.conf
-----
net.ipv4.ip_forward = 1
net.ipv6.conf.all.disable_ipv6 = 1
net.bridge.bridge-nf-call-arptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
-----
sysctl -p
cat <<EOF >> /etc/security/limits.conf
* hard nofile 655360
* soft nofile 655360
* hard nproc 655360
* soft nproc 655360
* soft core 655360
* hard core 655360
root hard nofile 655360
root soft nofile 655360
EOF
###系统依赖包
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git
### 开启ipvs 转发
modprobe br_netfilter
cat > /etc/sysconfig/modules/ipvs.modules << EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules
bash /etc/sysconfig/modules/ipvs.modules
lsmod | grep -e ip_vs -e nf_conntrack
2.2 升级系统内核 [所有节点]
内核升级
centos 内核版本为3.10 ,但是kubernetes 1.24.3(后续简称k8s)安装环境对内核版本有要求,
我们需要升级到最新的内核版本
#查看当前内核版本
uname -r
#添加内核rpm 下载源
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
# 安装最新内核
yum --enablerepo=elrepo-kernel install -y kernel-lt
# 设置开机从新内核启动
grub2-set-default 'CentOS Linux (5.4.206-1.el7.elrepo.x86_64) 7 (Core)'
# 升级内核后需要重新启动
reboot
# 查看当前内核版本
uname -r
5.4.197-1.el7.elrepo.x86_64
# 卸载旧内核
yum remove -y kernel kernel-tools
# 重启系统,可以发现旧内核已经没有了
reboot
• 升级系统依赖和常用工具
# 升级系统依赖$
yum update -y
# 安装常用工具
yum install -y nano net-tools wget bind-utils
2.3 安装docker
1) RPM 包安装方法:
提供的官方网址
官方文档:https://docs.docker.com
# 安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加Docker软件包源
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
## 查看所有的可用版本
yum list docker-ce --showduplicates | sort -r
# 安装Docker CE
yum install -y docker-ce 【直接安装最新版本】
## 安装所需要的指定版本
#yum install docker-ce-19.03.15-3.el7 docker-ce-cli-19.03.15-3.el7
yum install docker-ce-20.10.23-3.el7 docker-ce-cli-20.10.23-3.el7 docker-ce-rootless-extras-20.10.23-3.el7
## 阿里云镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://dfmo7maf.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "2048m"
},
"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl enable docker
## 添加镜像加速
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
# 启动Docker服务并设置开机启动
systemctl start docker
systemctl enable docker
2.4 安装k8s集群
## 在所有节点上配置k8s源
# cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kube
EOF
## 在所有节点上安装kubelet、kubeadm、kubectl
## 先查看当前yum源仓库有哪些kubernetes版本
# yum list kubeadm --showduplicates
## 使用yum list将列出最新版本
# yum list kubeadm
# yum install -y kubelet-1.23.17 kubeadm-1.23.17 kubectl-1.23.17
# systemctl enable kubelet.service
## 查看默认的初始化配置
# kubeadm config print init-defaults
## 查看默认要拉取的镜像信息
# kubeadm config images list
## 可以使用以下命令先拉取镜像
# kubeadm config images pull #默认会从国外站点拉取,会超时
## 使用以下命令从阿里云仓库拉取镜像
# kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers
##创建kubeadm-config.yaml配置文件
# kubeadm config images list
# kubeadm config print init-defaults
# cat > kubeadm-config.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.23.17
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
controlPlaneEndpoint: "172.16.10.11:6443" #master节点ip:port
networking:
serviceSubnet: "10.96.0.0/12"
podSubnet: "10.244.0.0/16"
dnsDomain: "cluster.local"
EOF
## 查看完整配置选项 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
## 在master节点初始化集群
[root@flyfish11 ~]# kubeadm init --config=kubeadm-config.yaml --upload-certs
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join 172.16.10.11:6443 --token bibtup.rn9j3z8bep910m6u \
--discovery-token-ca-cert-hash sha256:18f8bc7a4ce769dc88febd10d88c1cdc90186ffedc3566d56fdf390cb72c978d \
--control-plane --certificate-key d676e1b8085fbd4a4717367aa9f1a7a919c199e3c0431f708f979eec2c8a8dc6
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 172.16.10.11:6443 --token bibtup.rn9j3z8bep910m6u \
--discovery-token-ca-cert-hash sha256:18f8bc7a4ce769dc88febd10d88c1cdc90186ffedc3566d56fdf390cb72c978d
## 若果2小时后node节点还没有加入集群,此时上述加入命令就会失效,需要在master节点重新执行以下命令获取加入
# kubeadm init phase upload-certs --upload-certs
## 只在 master 节点上执行以下命令,用于获得node节点加入集群的命令参数
[root@flyfish11 ~]# kubeadm token create --print-join-command
kubeadm join 172.16.10.11:6443 --token ohyznr.s8nho4ups3g8mm1a --discovery-token-ca-cert-ha
## 再根据上述命令重新将node节点加入k8s集群
在其它worker 节点上面执行:
kubeadm join 172.16.10.11:6443 --token bibtup.rn9j3z8bep910m6u \
--discovery-token-ca-cert-hash sha256:18f8bc7a4ce769dc88febd10d88c1cdc90186ffedc3566d56fdf390cb72c978d
kubectl get node
2.5 安装kube-ovn
配置k8s集群的网络插件:
## 安装kube-ovn也非常简单,有一键安装脚本
# wget https://github.com/kubeovn/kube-ovn/archive/refs/tags/v1.10.7.tar.gz
# tar zxvf v1.10.7.tar.gz
# cd kube-ovn-1.10.7/dist/images
## 修改install.sh脚本中以下三项即可!
POD_CIDR="10.244.0.0/16"
POD_GATEWAY="10.244.0.1"
SVC_CIDR="10.96.0.0/12"
## 详细可以考官方中文文档: https://kubeovn.github.io/docs/v1.10.x/guide/setup-options/
## 最后执行install.sh脚本完成安装
# ./install.sh
./install.sh
一直运行到最后显示如下结果表示安装完成。
kubectl get node
三:部署 kubevirt
kubevirt 的前置条件:
https://kubevirt.io/user-guide/operations/installation/
KubeVirt是Kubernetes的一个虚拟化插件
安装前提条件
安装好kubernetes集群.
kubernetes 的apiserver 必须开启了 --allow-privileged=true ,这个kubernetes是默认开启的.
有 kubectl 工具
支持的容器运行时Container Runtime
docker
crio(with runv)
其他不使用虚拟化特性的容器运行时也应该也支持,只是没有经过测试。
硬件虚拟化支持
使用 virt-host-validate 命令来确保你的主机能够运行虚拟化工作负载(该命令需要安装libvirtclient)
yum install -y qemu-kvm libvirt virt-install bridge-utils 【所有节点全部安装】
virt-host-validate qemu
关于告警WARN
vim /etc/default/grub
---
加上: intel_iommu=on
GRUB_CMDLINE_LINUX="crashkernel=auto spectre_v2=retpoline rd.lvm.lv=centos/root rhgb quiet numa=off xhci-hcd.quirks=262144 kvm-intel.nested=1 intel_iommu=on"
---
grub2-mkconfig -o /boot/grub2/grub.cfg
dmesg | grep -e DMAR | grep -i iommu
在kubernetes中安装kubevirt
github 地址:
https://github.com/kubevirt/kubevirt/ 下载最新版本的kubevirt的插件yaml 使用0.58 的版本
# kubectl apply -f kubevirt-operator.yaml
# kubectl apply -f kubevirt-cr.yaml
安装最新版本:
# export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases | grep tag_name | grep -v -- '-rc' | head -1 | awk -F': ' '{print $2}' | sed 's/,//' | xargs)
# kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml
# kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml
kubectl get pod -n kubevirt
各组件用途:
virt-api
kubevirt是以CRD形式去管理vm pod, virt-api就是所有虚拟化操作的入口,包括常规的CRD更新
验证以及vm start、stop
virt-controlller
virt-controller会根据vmi CRD,生成对应的virt-lancher pod,并维护CRD的状态
virt-handler
Virt-handler会以Daemonset形式部署在每个节点上,负责监控节点上每个虚拟机实例状态变化,
一旦检测到状态变化,会进行响应并确保相应操作能达到所需(理想)状态。
Virt-handler保持集群级VMI Spec与相应libvirt域之间的同步;报告Libvirt域状态和集群Spec的变
化;调用以节点为中心的插件以满足VMI Spec定义的网络和存储要求。
virt-launcher
每个virt-lanuncher pod对应着一个VMI, kubelet只是负责virt-lanuncher pod运行状态,不会去关
心VMI创建情况。
virt-handler会根据CRD参数配置去通知virt-lanuncher去使用本地libvirtd实例来启动VMI, virtlanuncher就会如果pid去管理VMI,pod生命周期结束,virt-lanuncher也会去通知VMI去终止。
每个virt-lanuncher pod对应一个libvirtd,virt-lanuncher通过libvirtd去管理VM的生命周期,这样做
到去中心化,不再是以前虚拟机那套做法,一个libvirtd去管理多个VM。
virtctl
virctl 是kubevirt自带类似kubectl命令,它是越过virt-lancher pod这层去直接管理vm,可以控制vm
的start、stop、restart。
VirtualMachineInstance(VMI)
类似于 kubernetes Pod,是管理虚拟机的最小资源。一个 VirtualMachineInstance 对象即表示一台
正在运行的虚拟机实例,包含一个虚拟机所需要的各种配置。
VirtualMachine(VM)
为群集内的 VirtualMachineInstance 提供管理功能,例如开机/关机/重启虚拟机,确保虚拟机实例
的启动状态,与虚拟机实例是 1:1 的关系,类似与 spec.replica 为 1 的 StatefulSet。
VirtualMachineInstanceReplicaSet
类似 ReplicaSet
保证指定数量的 VirtualMachineInstance运行,可以配置 HPA。
安装cdi:
github 下载地址:
https://github.com/kubevirt/containerized-data-importer/ 下载最新版本的 1.56 的yaml
安装最新版本:
# export VERSION=$(curl -s https://github.com/kubevirt/containerized-data-importer/releases | grep -o "v[0-9]\.[0-9]*\.[0-9]*"| head -1)
# kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/cdi-operator.yaml
# kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/cdi-cr.yaml
### pod 的启动顺序:
virt-operator-->virt-api-->virt-controller-->virt-handler
kubectl apply -f cdi-operator.yaml
kubectl apply -f cdi-cr.yaml
kubectl get pod -n cdi
virtctl命令部署:
virtctl是kubevirt一个命令行工具
# export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases | grep tag_name | grep -v -- '-rc' | head -1 | awk -F': ' '{print $2}' | sed 's/,//' | xargs)
# curl -L -o /usr/local/bin/virtctl https://github.com/kubevirt/kubevirt/releases/download/$VERSION/virtctl-$VERSION-linux-amd64
# chmod +x /usr/local/bin/virtctl
cp -p virtctl-v0.58.0-linux-amd64 /usr/bin/virtctl
chmod +x /usr/bin/virtctl/
virtctl --help
官方测试模板:
curl https://kubevirt.io/labs/manifests/vm.yaml
kubectl apply -f https://kubevirt.io/labs/manifests/vm.yaml
kubectl get vm
kub
启动虚拟机:
virtctl start testvm
kubectl get vmi
进入虚拟机
virtctl console testvm
cirros/gocubsgo
ctrl+] 可以退出虚拟机
virtctl expose virtualmachine testvm --name vmiservice --target-port 22 --port 8022 --type NodePort
对外发布端口
ssh -p30822 [email protected]
创建默认存储(StorageClass)
说明:由于等会我们需要上传镜像,需要使用PV,PVC,PVC它会给我们自动创建,但是PV,需要我们自己创建。
我们知道创建PV,PVC有两种方法,一个是静态,一个是动态。
静态就是:手动编写PV,PVC资源清单,然后在将他们进行绑定。
动态就是:我们创建一个存储类:StorageClass,然后我们只需要编写PVC的资源清单即可,
它会给我们自动创建PV,然后和PVC进行绑定。
我们这里采用动态的方式:
1、部署NFS服务
# 在每个机器。
yum install -y nfs-utils
# 在flyfish11 主节点上面 执行以下命令
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
# 执行以下命令,启动 nfs 服务;创建共享目录
mkdir -p /nfs/data
# 在flyfish11执行
systemctl enable rpcbind
systemctl enable nfs-server
systemctl start rpcbind
systemctl start nfs-server
# 使配置生效
exportfs -r
#检查配置是否生效
exportfs
2、配置存储类
文件如下:
只需要修改两部分:就是把NFS服务端的IP修改为自己的即可。
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get","create","list", "watch","update"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-provisioner
containers:
- name: nfs-client-provisioner
image: lizhenliang/nfs-client-provisioner
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: storage.pri/nfs
- name: NFS_SERVER
value: 172.16.10.11
- name: NFS_PATH
value: /nfs/data
volumes:
- name: nfs-client-root
nfs:
server: 172.16.10.11
path: /nfs/data
---
kubectl apply -f pvc.yaml
创建storageclass
vi storageclass-nfs.yaml
----
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: storage-nfs
allowVolumeExpansion: true
provisioner: storage.pri/nfs
reclaimPolicy: Delete
----
kubectl apply -f storageclass-nfs.yaml
#扩展"reclaim policy"有三种方式:Retain、Recycle、Deleted。
Retain
#保护被PVC释放的PV及其上数据,并将PV状态改成"released",不将被其它PVC绑定。集群管理员手动通过如下步骤释放存储资源:
手动删除PV,但与其相关的后端存储资源如(AWS EBS, GCE PD, Azure Disk, or Cinder volume)仍然存在。
手动清空后端存储volume上的数据。
手动删除后端存储volume,或者重复使用后端volume,为其创建新的PV。
Delete
删除被PVC释放的PV及其后端存储volume。对于动态PV其"reclaim policy"继承自其"storage class",
默认是Delete。集群管理员负责将"storage class"的"reclaim policy"设置成用户期望的形式,否则需要用
户手动为创建后的动态PV编辑"reclaim policy"
Recycle
保留PV,但清空其上数据,已废弃
kubectl get storageclass
改变默认sc
https://kubernetes.io/zh/docs/tasks/administer-cluster/change-default-storage-class/#%e4%b8%ba%e4%bb%80%e4%b9%88%e8%a6%81%e6%94%b9%e5%8f%98%e9%bb%98%e8%ae%a4-storage-class
kubectl patch storageclass storage-nfs -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
验证nfs动态供应
创建pvc
vim pvc.yaml
-----
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-claim-01
#annotations:
# volume.beta.kubernetes.io/storage-class: "storage-nfs"
spec:
storageClassName: storage-nfs #这个class一定注意要和sc的名字一样
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi
-----
kubectl apply -f pvc.yaml
使用pvc
vi testpod.yaml
----
kind: Pod
apiVersion: v1
metadata:
name: test-pod
spec:
containers:
- name: test-pod
image: busybox
command:
- "/bin/sh"
args:
- "-c"
- "touch /mnt/SUCCESS && exit 0 || exit 1"
volumeMounts:
- name: nfs-pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: pvc-claim-01
-----
kubectl apply -f testpod.yaml
上传镜像
KubeVirt 可以使用 PVC 作为后端磁盘,使用 filesystem 类型的 PVC 时,默认使用的时 /disk.img 这个镜像,用户可以将镜像上传到 PVC,在创建 VMI 时使用此 PVC。使用这种方式需要注意下面几点:
一个 PVC 只允许存在一个镜像,只允许一个 VMI 使用,要创建多个 VMI,需要上传多次
/disk.img 的格式必须是 RAW 格式
CDI 提供了使用使用 PVC 作为虚拟机磁盘的方案,在虚拟机启动前通过下面方式填充 PVC:
通过 URL 导入虚拟机镜像到 PVC,URL 可以是 http 链接,s3 链接
Clone 一个已经存在的 PVC
通过 container registry 导入虚拟机磁盘到 PVC,需要结合 ContainerDisk 使用
通过客户端上传本地镜像到 PVC
通过命令行 virtctl,结合 CDI 项目,可以上传本地镜像到 PVC 上,支持的镜像格式有:
.img
.qcow2
.iso
压缩为 .tar,.gz,.xz 格式的上述镜像
我们的目标是安装 Windows 10 虚拟机,所以需要将上面下载好的 Windows 镜像上传到 PVC:
如下操作:
vim upload4.sh
-----
virtctl image-upload \
--image-path='/root/win10.iso' \
--pvc-name=iso-win10 \
--pvc-size=7G \
--uploadproxy-url=https://10.107.165.11 \
--insecure --wait-secs=240
-----
./upload4.sh
增加 hostDisk 支持
Kubevirt 默认没有开启对 hostDisk 的支持,需要手动开启,这里我们直接editKubeVirt1的ConfigMap
vim kubevirt-config.yaml
---
apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
name: kubevirt
namespace: kubevirt
spec:
configuration:
developerConfiguration:
featureGates:
- HardDisk
- DataVolumes
- HostDisk
---
kubectl apply -f kubevirt-config.yaml
创建虚拟机
vim vm-win10.yaml
---
apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachine
metadata:
name: win10
spec:
running: false
template:
metadata:
labels:
kubevirt.io/domain: win10
spec:
domain:
cpu:
cores: 4
devices:
disks:
- bootOrder: 1
cdrom:
bus: sata
name: cdromiso
- disk:
bus: virtio
name: harddrive
- cdrom:
bus: sata
name: virtiocontainerdisk
interfaces:
- masquerade: {}
model: e1000
name: default
machine:
type: q35
resources:
requests:
memory: 6G
networks:
- name: default
pod: {}
volumes:
- name: cdromiso
persistentVolumeClaim:
claimName: iso-win10
- name: harddrive
hostDisk:
capacity: 50Gi
path: /data/disk.img
type: DiskOrCreate
- containerDisk:
image: kubevirt/virtio-container-disk
name: virtiocontainerdisk
---
这里用到了 3 个 Volume:
cdromiso : 提供操作系统安装镜像,即上文上传镜像后生成的 PVC iso-win10。
harddrive : 虚拟机使用的磁盘,即操作系统就会安装在该磁盘上。这里选择 hostDisk
直接挂载到宿主机以提升性能,如果使用分布式存储则体验非常不好。
containerDisk : 由于 Windows 默认无法识别 raw 格式的磁盘,所以需要安装 virtio 驱动。
containerDisk 可以将打包好 virtio 驱动的容器镜像挂载到虚拟机中。
关于网络部分,spec.template.spec.networks 定义了一个网络叫 default,
这里表示使用 Kubernetes 默认的 CNI。
spec.template.spec.domain.devices.interfaces 选择定义的网络 default,并开启 masquerade,
以使用网络地址转换 (NAT) 来通过 Linux 网桥将虚拟机连接至 Pod 网络后端。
安装 virtvnc 工具:
下载地址:
https://github.com/wavezhang/virtVNC/tags
tar -zxvf virtVNC-0.1.tar.gz
cd /root/kubevirt/virtVNC-0.1/k8s
vim virtvnc.yaml
---
将:extensions/v1beta1
改为:apps/v1
----
kubectl apply -f virtvnc.yaml
kubectl get pod -n kubevirt
kubectl get svc -n kubevirt
打开浏览器
http://172.16.10.11:31417
kubectl get vm
安装centos7
virtctl image-upload \
--image-path='/root/centos7.iso' \
--pvc-name=iso-centos \
--pvc-size=4G \
--uploadproxy-url=https://10.109.235.197 \
--insecure \
--wait-secs=240
vim centos7.yaml
---
apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachine
metadata:
name: centos7.9
spec:
running: false
template:
metadata:
labels:
kubevirt.io/domain: centos7.9
spec:
domain:
cpu:
cores: 4
devices:
disks:
- bootOrder: 1
cdrom:
bus: sata
name: cdromiso
- disk:
bus: sata
name: harddrive
interfaces:
- masquerade: {}
model: e1000
name: default
machine:
type: q35
resources:
requests:
memory: 8G
networks:
- name: default
pod: {}
volumes:
- name: cdromiso
persistentVolumeClaim:
claimName: iso-centos
- name: harddrive
hostDisk:
capacity: 50Gi
path: /data/vms/disk.img
type: DiskOrCreate
----
kubectl apply -f centos7.yaml
四:安装ceph-rook
安装可参考官档 https://rook.github.io/docs/rook/v1.10/Getting-Started/Prerequisites/prerequisites/
先到github下载 https://github.com/rook/rook
作为存储节点,需要存储节点有相应的raw设备,即空闲未使用的硬盘,如每个节点增加sdb盘
修改cluster.yaml(rook-1.10.6/deploy/examples目录下)文件,指定mon、mgr节点个数以及资源
使用限制;另外,需指定osd节点信息,并初始化相应磁盘
下载rook-1.10.6.tar.gz
mkdir rook/
cd rook/
tar -zxvf rook-1.10.6.tar.gz
cd /root/rook/rook-1.10.6/deploy/examples/
vim cluster.yaml
----
provider: host # 第92 行
storage: # cluster level storage configuration and selection ## 第 225 行
useAllNodes: false ## 第 226 行
useAllDevices: false ## 第 227 行
metadataDevice: "/dev/sdb" ### 第231 行
----
nodes:
- name: "flyfish11"
devices: # specific devices to use for storage can be specified for each node
- name: "sdc"
- name: "sdd" # multiple osds can be created on high performance devices
- name: "flyfish12"
devices: # specific devices to use for storage can be specified for each node
- name: "sdc"
- name: "sdd" # multiple osds can be created on high performance devices
- name: "flyfish13"
devices: # specific devices to use for storage can be specified for each node
- name: "sdc"
- name: "sdd" # multiple osds can be created on high performance devices
- name: "flyfish14"
devices: # specific devices to use for storage can be specified for each node
- name: "sdc"
- name: "sdd" # multiple osds can be created on high performance devices
修改:operator.yaml中 ROOK_DISCOVER_DEVICES_INTERVAL值,将间隔调小,默认为60m
vim operator.yaml
---
- name: ROOK_DISCOVER_DEVICES_INTERVAL
value: "2m"
---
kubectl taint node flyfish11 node-role.kubernetes.io/master-
# DISK="/dev/sdb";sgdisk --zap-all $DISK;dd if=/dev/zero of="$DISK" bs=1M count=100 oflag=direct
# cd ./rook-1.10.6/deploy/examples
### 查看需要准备镜像
cat images.txt
----
quay.io/ceph/ceph:v17.2.5
quay.io/cephcsi/cephcsi:v3.7.2
quay.io/csiaddons/k8s-sidecar:v0.5.0
registry.k8s.io/sig-storage/csi-attacher:v4.0.0
registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.5.1
registry.k8s.io/sig-storage/csi-provisioner:v3.3.0
registry.k8s.io/sig-storage/csi-resizer:v1.6.0
registry.k8s.io/sig-storage/csi-snapshotter:v6.1.0
rook/ceph:v1.10.6
----
docker pull rook/ceph:v1.10.6
docker pull quay.mirrors.ustc.edu.cn/ceph/ceph:v17.2.5
docker pull quay.mirrors.ustc.edu.cn/cephcsi/cephcsi:v3.7.2
docker pull quay.mirrors.ustc.edu.cn/csiaddons/k8s-sidecar:v0.5.0
docker tag quay.mirrors.ustc.edu.cn/ceph/ceph:v17.2.5 quay.io/ceph/ceph:v17.2.5
docker tag quay.mirrors.ustc.edu.cn/cephcsi/cephcsi:v3.7.2 quay.io/cephcsi/cephcsi:v3.7.2
docker tag quay.mirrors.ustc.edu.cn/csiaddons/k8s-sidecar:v0.5.0 quay.io/csiaddons/k8s-sidecar:v0.5.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/csi-attacher:v4.0.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/csi-node-driver-registrar:v2.5.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/csi-resizer:v1.6.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/csi-snapshotter:v6.1.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/csi-provisioner:v3.3.0
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/csi-attacher:v4.0.0 registry.k8s.io/sig-storage/csi-attacher:v4.0.0
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/csi-node-driver-registrar:v2.5.1 registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.5.1
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/csi-provisioner:v3.3.0 registry.k8s.io/sig-storage/csi-provisioner:v3.3.0
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/csi-resizer:v1.6.0 registry.k8s.io/sig-storage/csi-resizer:v1.6.0
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/csi-snapshotter:v6.1.0 registry.k8s.io/sig-storage/csi-snapshotter:v6.1.0
# kubectl create -f crds.yaml -f common.yaml
# kubectl apply -f operator.yaml
# kubectl apply -f cluster.yaml
# kubectl apply -f toolbox.yaml
kubectl get pod -n rook-ceph
进入rook-ceph-tools 的pod 检查 ceph状态
kubectl exec -it rook-ceph-tools-855b7ccc5b-s9sts -n rook-ceph -- /bin/sh
cd /var/lib/rook
tree .
pvscan
安装 ceph 的dashboard
# cd /root/rook/rook-1.10.6/deploy/examples
# kubectl apply -f dashboard-external-https.yaml
# kubectl get secret -n rook-ceph
# kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}"
---
VH15XFFVIishLGE6cW46XzJVYzM=
---
echo VH15XFFVIishLGE6cW46XzJVYzM= |base64 -d
---
T}y\QU"+!,a:qn:_2Uc3
---
kubectl get svc -n rook-ceph
打开web:
https://172.16.10.11:32471
admin/T}y\QU"+!,a:qn:_2Uc3
将ceph配置成为 k8s的默认storageClass
cd /root/rook/rook-1.10.6/deploy/examples/csi/rbd
# 修改 storageclass.yaml 中副本数为2,默认是3 [如果你的机器大于3台就写3 也可以]
vim storageclass.yaml
---
spec:
failureDomain: host
replicated:
size: 3
---
kubectl apply -f storageclass.yaml
kubectl get sc
rook-ceph 的删除过程:
kubectl delete -f toolbox.yaml
kubectl delete -f cluster.yaml
kubectl edit cephclusters.ceph.rook.io -n rook-ceph rook-ceph //删除 finalizers: 和下一行
kubectl delete -f operator.yaml
kubectl delete -f crds.yaml -f common.yaml
# 删除 /var/lib/rook/ 下相关文件,如果是重建集群,osd数据要保留,则不能删除。
# rm -rf /var/lib/rook/*
kubectl proxy --port=8081 &
kubectl get pod -A|grep Terminating|awk '{print "kubectl delete -n "$1" pod/"$2" --force"}'|sh
ns=`kubectl get ns|grep Terminating|awk '{print $1}'`
mkdir -p /tmp/terminating
for v in $ns; do
echo $v
kubectl get namespace $v -o json |jq 'del(.spec.finalizers)' > /tmp/tmp.json
curl -k -H "Content-Type: application/json" -X PUT --data-binary @/tmp/tmp.json http://127.0
done
sleep 1
ps -ef |grep "kubectl proxy" |grep -v grep |awk '{print $2}'|xargs kill
五: 创建测试虚拟机
官方测试模板:
curl https://kubevirt.io/labs/manifests/vm.yaml
kubectl apply -f https://kubevirt.io/labs/manifests/vm.yaml
virtctl expose virtualmachine testvm --name vmiservice --target-port 22 --port 8022 --type NodePort
对外发布端口
镜像上传
上传镜像时会调用 cdi-uploadserver 创建pod,完成后销毁
查看uploadproxy-url的svc 地址:
kubectl get svc -n cdi
上传镜像:cirros-0.4.0-x86_64-disk.img
virtctl image-upload \
--image-path="/root/kubevirt/cirros-0.4.0-x86_64-disk.img" \
--storage-class=rook-ceph-block \
--pvc-name=img-cirros-0.4.0 \
--pvc-size=5Gi \
--uploadproxy-url=https://10.104.23.34 \
--insecure \
--wait-secs=240
基于上传的镜像创建虚拟机
# 创建DV
vim dv.yaml
---
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
name: dv-cirros
namespace: default
spec:
source:
pvc:
namespace: default
name: img-cirros-0.4.0
pvc:
storageClassName: "rook-ceph-block"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
volumeMode: Block
-----
kubectl apply -f dv.yaml
dv其实是跨名称空间复制pvc,可以将任意名称空间的pvc复制到指定名称空间
为实例申请一个可启动pvc,dataSource指向上面创建的dv,即pvc克隆
说明:如果是通过 virtctl image-upload 命令上传的镜像,不创建上面的dv,dataSource直接指
向 virtctl image-upload 命令上传--pvc-name也可以
kubectl get dv
创建实例,将卷指向上面创建的pvc
vim vm-crrios.yaml
----
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-cirros-bootdisk
namespace: default
spec:
storageClassName: "rook-ceph-block"
volumeMode: Block
accessModes:
- ReadWriteMany
dataSource:
kind: PersistentVolumeClaim
name: dv-cirros
resources:
requests:
storage: 5Gi
----
kubectl apply -f vm-crrios.yaml
vim vm-crrios1.yaml
----
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: vm-cirros01
spec:
running: false
template:
metadata:
labels:
kubevirt.io/size: thin
kubevirt.io/domain: vm-cirros01
spec:
domain:
devices:
disks:
- name: root-disk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- name: root-disk
persistentVolumeClaim:
claimName: pvc-cirros-bootdisk
----
kubectl apply -f vm-crrios.yaml
kubect get pvc
kubectl get vm
标签:kubectl,kubevirt,k8s1.23,name,17,--,yaml,io From: https://blog.51cto.com/flyfish225/6241349