vCenter 虚拟机迁移至 PVE
vCenter 虚拟机导出及 PVE 侧导入手记
vCenter 虚拟机导出及 PVE 侧导入手记
由于暑假到了以及天气原因,学校的k8s集群暂时关闭了,但是目前还是有使用k8s的需求,花了2个小时又重新搭了一下;
由于国内网络的问题,导致github包、镜像都很难拉下来,因此本文的内容更适合国内需求环境。
源代码:
该部分内容来自于 K8S 官方文档:
Linux 主机。Kubernetes 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令。2 GB 或更多的 RAM(如果少于这个数字将会影响你应用的运行内存)。CPU 2 核心及以上。MAC 地址或 product_uuid。| IP Address | Hostname | CPU | Memory | Storage | OS Release | Role |
|---|---|---|---|---|---|---|
| 192.168.117.200 | k1 | 4C | 8G | 100GB | Debian 12 | Master |
| 192.168.117.201 | k2 | 4C | 8G | 100GB | Debian 12 | Worker |
| 192.168.117.202 | k3 | 4C | 8G | 100GB | Debian 12 | Worker |
虚拟机安装、配置部分不再赘述了!
主要包括下面几个方面:
参考:
新版本的 k8s 和 docker 底层都依赖 containerd 容易造成冲突,直接卸载docker:
sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extrassudo rm -rf /var/lib/dockersudo rm -rf /var/lib/containerdsudo rm -rf /etc/docker使用阿里云的时钟源:
timedatectl set-timezone Asia/Shanghai# 安装 chronyapt-get install -y chrony# 修改为阿里的时钟源sed -i "s/pool 2.debian.pool.ntp.org iburst/server ntp.aliyun.com iburst/g" /etc/chrony/chrony.conf# 启用并立即启动 chrony 服务systemctl restart chronysystemctl enable chrony# 查看与 chrony 服务器同步的时间源chronyc sources在 Kubernetes 中,ipset 和 ipvsadm 的用途:
ipset 主要用于支持 Service 的负载均衡和网络策略。它可以帮助实现高性能的数据包过滤和转发,以及对 IP 地址和端口进行快速匹配。ipvsadm 主要用于配置和管理 IPVS 负载均衡器,以实现 Service 的负载均衡。执行:
apt-get install -y ipset ipvsadm 关闭 swap、防火墙等:
# 关闭所有已激活的 swap 分区swapoff -a# 禁用系统启动时自动挂载 swap 分区sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab# 停止 AppArmor 服务systemctl stop apparmor.service# 禁用 AppArmor 服务systemctl disable apparmor.service# 禁用 Uncomplicated Firewall(ufw)ufw disable# 停止 ufw 服务systemctl stop ufw.service# 禁用 ufw 服务systemctl disable ufw.service创建一个名为 kubernetes.conf 的内核配置文件,并写入以下配置内容:
cat > /etc/sysctl.d/kubernetes.conf << EOF# 允许 IPv6 转发请求通过iptables进行处理(如果禁用防火墙或不是iptables,则该配置无效)net.bridge.bridge-nf-call-ip6tables = 1# 允许 IPv4 转发请求通过iptables进行处理(如果禁用防火墙或不是iptables,则该配置无效)net.bridge.bridge-nf-call-iptables = 1# 启用IPv4数据包的转发功能net.ipv4.ip_forward = 1# 禁用发送 ICMP 重定向消息net.ipv4.conf.all.send_redirects = 0net.ipv4.conf.default.send_redirects = 0# 提高 TCP 连接跟踪的最大数量net.netfilter.nf_conntrack_max = 1000000# 提高连接追踪表的超时时间net.netfilter.nf_conntrack_tcp_timeout_established = 86400# 提高监听队列大小net.core.somaxconn = 1024# 防止 SYN 攻击net.ipv4.tcp_syncookies = 1net.ipv4.tcp_max_syn_backlog = 2048net.ipv4.tcp_synack_retries = 2# 提高文件描述符限制fs.file-max = 65536# 设置虚拟内存交换(swap)的使用策略为0,减少对磁盘的频繁读写vm.swappiness = 0EOF加载或启动内核模块 br_netfilter,该模块提供了网络桥接所需的网络过滤功能
modprobe br_netfilter查看是否已成功加载模块:
lsmod | grep br_netfilter将读取该文件中的参数设置,并将其应用到系统的当前运行状态中:
sysctl -p /etc/sysctl.d/kubernetes.conf参考:
将自定义在系统引导时自动加载的内核模块:
# 将自定义在系统引导时自动加载的内核模块cat > /etc/modules-load.d/kubernetes.conf << EOF# /etc/modules-load.d/kubernetes.conf# Linux 网桥支持br_netfilter# IPVS 加载均衡器ip_vsip_vs_rrip_vs_wrrip_vs_sh# IPv4 连接跟踪nf_conntrack_ipv4# IP 表规则ip_tablesEOF添加可执行权限:
chmod a+x /etc/modules-load.d/kubernetes.conf以下指令适用于 Kubernetes 1.28!
安装 containerd:
# cri-containerd 比 containerd 多了 runcwget https://github.com/containerd/containerd/releases/download/v1.7.21/cri-containerd-1.7.21-linux-amd64.tar.gztar xf cri-containerd-1.7.21-linux-amd64.tar.gz -C /# 创建目录,该目录用于存放 containerd 配置文件mkdir /etc/containerd# 创建一个默认的 containerd 配置文件containerd config default > /etc/containerd/config.toml# 修改配置文件中使用的沙箱镜像版本sed -i 's#registry.k8s.io/pause:3.8#registry.aliyuncs.com/google_containers/pause:3.9#' /etc/containerd/config.toml# 设置容器运行时(containerd + CRI)在创建容器时使用 Systemd Cgroups 驱动sed -i '/SystemdCgroup/s/false/true/' /etc/containerd/config.toml# 修改存储目录# mkdir /data1/containerd# sed -i 's#root = "/var/lib/containerd"#root = "/data1/containerd"#' /etc/containerd/config.toml配置启动脚本:
/lib/systemd/system/containerd.service
[Unit]Description=containerd container runtimeDocumentation=https://containerd.ioAfter=network.target local-fs.target[Service]ExecStartPre=-/sbin/modprobe overlayExecStart=/usr/local/bin/containerdType=notifyDelegate=yesKillMode=processRestart=alwaysRestartSec=5LimitNPROC=infinityLimitCORE=infinityTasksMax=infinityOOMScoreAdjust=-999[Install]WantedBy=multi-user.target执行配置:
# 启用并立即启动 containerd 服务systemctl enable --now containerd.service# 检查 containerd 服务的当前状态systemctl status containerd.service# 检查 containerd crictl runc 的版本containerd --versioncrictl --versionrunc --versioncrictl config runtime-endpoint unix:///run/containerd/containerd.sock更新 apt 包索引并安装使用 Kubernetes apt 仓库所需要的包:
sudo apt-get update# apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包sudo apt-get install -y apt-transport-https ca-certificates curl gpg#下载用于 Kubernetes 软件包仓库的公共签名密钥。所有仓库都使用相同的签名密钥,因此你可以忽略URL中的版本:curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg#添加 Kubernetes apt 仓库。 请注意,此仓库仅包含适用于 Kubernetes 1.28 的软件包; 对于其他 Kubernetes 次要版本,则需要更改 URL 中的 Kubernetes 次要版本以匹配你所需的次要版本 (你还应该检查正在阅读的安装文档是否为你计划安装的 Kubernetes 版本的文档)。# 此操作会覆盖 /etc/apt/sources.list.d/kubernetes.list 中现存的所有配置。echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list#更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本:sudo apt-get updatesudo apt-get install -y kubelet=1.28.13-1.1 kubeadm=1.28.13-1.1 kubectl=1.28.13-1.1#锁定版本sudo apt-mark hold kubelet kubeadm kubectl#说明:在 Debian 12 和 Ubuntu 22.04 之前的早期版本中,默认情况下不存在 /etc/apt/keyrings 目录; 你可以通过运行 sudo mkdir -m 755 /etc/apt/keyrings 来创建它。配置 kubelet 开机启动:
systemctl enable kubelet本小节在 master 节点执行!
生成配置文件:
kubeadm config print init-defaults > kubeadm.yaml配置文件如下:
kubeadm.yaml
apiVersion: kubeadm.k8s.io/v1beta3bootstrapTokens:- groups: - system:bootstrappers:kubeadm:default-node-token token: abcdef.0123456789abcdef ttl: 24h0m0s usages: - signing - authenticationkind: InitConfiguration#localAPIEndpoint:# advertiseAddress: 192.168.2.232# bindPort: 6443nodeRegistration: criSocket: unix:///run/containerd/containerd.sock imagePullPolicy: IfNotPresent# name: node taints: null---apiServer: timeoutForControlPlane: 4m0sapiVersion: kubeadm.k8s.io/v1beta3certificatesDir: /etc/kubernetes/pkiclusterName: kubernetescontrollerManager: {}dns: {}etcd: local: dataDir: /var/lib/etcd# 指定阿里云镜像以及k8s版本imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containerskind: ClusterConfigurationkubernetesVersion: 1.28.13# 新增controlPlaneEndpoint: 192.168.117.200:6443 # 修改为masterIP!networking: dnsDomain: cluster.local serviceSubnet: 10.254.0.0/16 podSubnet: 10.255.0.0/16 # 指定pod网段scheduler: {}# 新增如下:---apiVersion: kubelet.config.k8s.io/v1beta1kind: KubeletConfigurationcgroupDriver: systemd---apiVersion: kubeproxy.config.k8s.io/v1alpha1kind: KubeProxyConfigurationmode: ipvs验证镜像仓配置是否生效。
kubeadm config images list --config=kubeadm.yaml提前拉取镜像。
kubeadm config images pull --config=kubeadm.yaml查看镜像是否下载。
crictl images开始初始化。
kubeadm init --config=kubeadm.yaml安装完会有加入集群的相关指令:
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 control-plane nodes by copying certificate authoritiesand service account keys on each node and then running the following as root: kubeadm join 192.168.117.200:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:91a2398cbadf3967950dc6900e7411d5319e82ad30e139a1163896f9a8c61234 \ --control-plane Then you can join any number of worker nodes by running the following on each as root:kubeadm join 192.168.117.200:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:91a2398cbadf3967950dc6900e7411d5319e82ad30e139a1163896f9a8c61234此小节在 worker 节点执行!
执行加入脚本:
kubeadm join 192.168.117.200:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:91a2398cbadf3967950dc6900e7411d5319e82ad30e139a1163896f9a8c61234等待后即可加入!
默认情况下 Master 节点为 control-plane,无法部署服务;
可以通过执行:
# 查看污点kubectl describe node k1 |grep TaintsTaints: node-role.kubernetes.io/control-plane:NoSchedule# 删除污点kubectl taint node k1 node-role.kubernetes.io/control-plane:NoSchedule-启用 master 节点调度!
其他节点默认是无法直接使用 kubectl 管理集群的,我们只需要将配置文件复制到其他节点即可!
方法一:拷贝master节点的/etc/kubernetes/admin.conf 到nodes节点中的同样的目录/etc/kubernetes/ ,然后再配置环境变量
[root@k8s-node1 qq-5201351]# scp k8s-master:/etc/kubernetes/admin.conf /etc/kubernetes/admin.conf然后再配置环境变量:
echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> ~/.bash_profilesource ~/.bash_profile 方法二:拷贝master节点的/etc/kubernetes/admin.conf 到nodes节点的$HOME/.kube目录,并且命名为config
因为默认是没有 $HOME/.kube 目录的,先进行创建:
k8s 部署完成后还不能使用,需要配置网络插件,从而为 Pod 分配 IP,打通网络等等。
Calico是 目前开源的最成熟的纯三层网络框架之一, 是一种广泛采用、久经考验的开源网络和网络安全解决方案,适用于 Kubernetes、虚拟机和裸机工作负载。 Calico 为云原生应用提供两大服务:工作负载之间的网络连接和工作负载之间的网络安全策略。
Calico 访问链接:projectcalico.docs.tigera.io/about/
在这里使用 calico 来做为集群的网络插件,官网提供2种安装方式:
curl https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/calico.yaml -O配置:
CALICO_IPV4POOL_CIDR 为我们的网段(本文为:10.254.0.0/16)CALICO_IPV4POOL_IPIP 为 Always 启用 ipip 协议;- # - name: CALICO_IPV4POOL_CIDR- # value: "192.168.0.0/16"+ - name: CALICO_IPV4POOL_CIDR+ value: "10.254.0.0/16"# Enable IPIP+ - name: CALICO_IPV4POOL_IPIP+ value: "Always"修改镜像地址:
搜索 image: 将镜像修改:
- image: docker.io/calico/cni:v3.28.1+ image: registry.cn-hangzhou.aliyuncs.com/jasonkay/cni:v3.28.1- image: docker.io/calico/node:v3.28.1+ image: registry.cn-hangzhou.aliyuncs.com/jasonkay/node:v3.28.1- image: docker.io/calico/kube-controllers:v3.28.1+ image: registry.cn-hangzhou.aliyuncs.com/jasonkay/kube-controllers:v3.28.1即,将:
docker.io/calico替换为registry.cn-hangzhou.aliyuncs.com/jasonkay(我在阿里云上同步的镜像)!
随后执行:
kubectl apply -f calico.yaml等待部署完成即可!
验证 coredns dns 转发是否正常:
# 安装dns工具apt install -y dnsutils# 获取dns ip地址kubectl get svc -n kube-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkube-dns ClusterIP 10.254.0.10 <none> 53/UDP,53/TCP,9153/TCP 15h# 测试能够解析dig -t a www.baidu.com @10.254.0.10部署 nginx 进行测试:
nginx-deploy.yaml
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deployment labels: app: nginxspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: registry.cn-hangzhou.aliyuncs.com/jasonkay/nginx:latest ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: nginx-servicespec: type: NodePort selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 31080应用:
kubectl apply -f nginx-deploy.yaml然后访问 k8s-ip:31080,能够正常访问 Nginx!
Helm 是 Kubernetes 的一个包管理工具,类似于 Linux 的 Apt 或 Yum;
这个工具能帮助开发者和系统管理员更方便地管理在 Kubernetes 集群上部署、更新、卸载应用。
Helm 中的三个主要概念:
| 概念 | 描述 |
|---|---|
| Chart | 在 Kubernetes 集群上部署应用所需的所有资源定义的包 |
| Release | 在 Kubernetes 集群上部署的 Chart 的实例 |
| Repository | Chart 的存储位置,类似软件仓库,用于分发和分享 Chart |
安装脚本:
1. 添加 Helm 的官方 GPG keyroot@k8s-master:~# curl https://baltocdn.com/helm/signing.asc | gpg --dearmor -o /usr/share/keyrings/helm-keyring.gpg2. 添加 Helm 的官方 APT 仓库root@k8s-master:~# echo "deb [signed-by=/usr/share/keyrings/helm-keyring.gpg] https://baltocdn.com/helm/stable/debian/ all main" | tee /etc/apt/sources.list.d/helm-stable-debian.list3. 更新 apt 源root@k8s-master:~# apt-get update4. 安装 Helmroot@k8s-master:~# apt-get install -y helm5. 检查 Helm 是否已正确安装root@k8s-master:~# helm versionversion.BuildInfo{Version:"v3.13.3", GitCommit:"c8b948945e52abba22ff885446a1486cb5fd3474", GitTreeState:"clean", GoVersion:"go1.20.11"}官方提供的面板不太好用,这里推荐使用 KubeSphere;
配置下载区域:
export KKZONE=cn安装也很简单,使用 helm 即可,而且支持国内:
helm upgrade --install -n kubesphere-system \ --create-namespace ks-core \ https://charts.kubesphere.com.cn/main/ks-core-1.1.4.tgz \ --debug --wait \ --set global.imageRegistry=swr.cn-southwest-2.myhuaweicloud.com/ks \ --set extension.imageRegistry=swr.cn-southwest-2.myhuaweicloud.com/ks等待所有 Pod 就绪后,安装完成,显示:
NOTES:Thank you for choosing KubeSphere Helm Chart.Please be patient and wait for several seconds for the KubeSphere deployment to complete.1. Wait for Deployment Completion Confirm that all KubeSphere components are running by executing the following command: kubectl get pods -n kubesphere-system2. Access the KubeSphere Console Once the deployment is complete, you can access the KubeSphere console using the following URL: http://192.168.6.10:308803. Login to KubeSphere Console Use the following credentials to log in: Account: admin Password: P@88w0rdNOTE: It is highly recommended to change the default password immediately after the first login.For additional information and details, please visit https://kubesphere.io.执行以下命令检查 Pod 状态。
kubectl get pods -n kubesphere-system当 Pod 状态都为 Running 时,使用默认的账户和密码 (admin/P@88w0rd) 通过 <NodeIP>:30880 访问 KubeSphere Web 控制台!
推荐安装 kubectx,可以切换k8s上下文(管理多个集群);
并且 kubectx 自带了另一个工具:kubens,可以方便切换默认的 namespace;
安装:
apt install -y kubectxnerdctl 可以提供在宿主机上类 docker 的操作(操作 containerd),可以提升用户体验:
cd /tmpwget https://github.com/containerd/nerdctl/releases/download/v1.7.6/nerdctl-1.7.6-linux-amd64.tar.gztar xf nerdctl-1.7.6-linux-amd64.tar.gzmv nerdctl /usr/sbin参考文章:
源代码:
Veeam Backup & Replication 是一款领先的虚拟化数据保护解决方案,专为 VMware vSphere 平台(包括 ESXi 主机)设计,能够提供高效、可靠的虚拟机备份、还原与复制功能。它通过与 vSphere 深度集成,实现无代理、无中断的备份方式,支持基于镜像的增量备份(使用 VMware CBT 变更块追踪技术),大大减少了备份窗口和存储占用。
从外部导入到ESXi的虚拟机需要自行转换一下磁盘格式才能在ESXi平台上使用。
在ESXi中可能会出现直通显卡到虚拟机之后无法启动虚拟机,并报错“电源启动失败”,此时在虚拟机vmx文件中添加如下参数即可。
在vmware中安装Ubuntu Server,因为没有图形界面,因此需要手动在终端内安装vmtools。
有一说一尽管没有什么用,没有vmtools也能认网卡,但是挂上驱动总比不挂好,也能避免各种奇奇怪怪的问题。