VMware虚拟机安装Linux && 部署k8s集群
- 本文主要介绍如何部署k8s集群,对于k8s我是零基础小白,仅用CSDN+GPT完成。
- 全文超详细,包括部署中的坑填埋以及重点知识的介绍。
- 由于我只有一台服务器,所以本文借助vmware创建linux虚拟机来代替服务器。
- 前置条件:三台带有静态IP的虚拟机(能够互相内网通信),k8s基础知识(可通过GPT边部署边学习),机器间通信知识,linux相关知识,docker相关知识。
注:可选择DeepSeek+GPT共同进行,deepSeek进行框架整体流程进行,GPT解决过程中DeepSeek没有考虑到的坑。当然,也可以全程使用deepSeek开启两个窗口。
1. 建立三台虚拟机(前置环境)
创建虚拟机博文地址:
静态ip配置
先查看自己电脑上的网络信息:ipconfig
第一步:创建虚拟机
创建三台虚拟机 1 2 3。(参考上博文创建)
第二步:配置静态ip
1.设置虚拟机网络适配器为桥接模式
查看宿主机网络状态:ipconfig -all
设置虚拟机网络适配器为桥接模式,为了后续宿主机能够和我们电脑通信。
- 设置虚拟机为桥接模式
- 编辑虚拟网络
- 选择宿主机的网卡
如果虚拟机连不上网,或者无法与宿主机通信,参考下面这篇博文配置
VM中linux虚拟机配置桥接模式
2.静态ip配置修改
三台宿主机分别执行下面命令,打开网络配置
sudo vi /etc/sysconfig/network-scripts/ifcfg-ens33
下面我要创建三个静态ip,分别为192.168.1.101,192.168.1.102,192.168.1.103
三台宿主机的ifcfg-ens33
配置如下:
- 101虚拟机配置
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="3faeaf11-36aa-4cf3-8d2e-59ed8b87341e"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=192.168.0.101 # 修改为与宿主机相同子网
NETMASK=255.255.255.0
GATEWAY=192.168.0.1 # 需要修改为正确的网关
DNS1=192.168.0.1 # 如果你的网关是192.168.0.1,DNS也可以用这个
- 102虚拟机配置:
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="6f0a4178-a310-4e4d-9d63-a1f9431c4d8e"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=192.168.0.102 # 修改为与宿主机相同子网
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=8.8.8.8
- 103虚拟机配置:
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="2605fa35-089d-4294-8473-145d7311a028"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=192.168.0.103 # 修改为与宿主机相同子网
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=8.8.8.8
3.重启网络使配置生效
systemctl restart network
到这里我们《三台带有静态IP的虚拟机(能够互相内网通信》前置条件已经完成
2.k8s学习&&部署
下面我们开始边部署k8s集群边学习k8s基础知识。
借助GPT协助我们,指令如下:
1.我是一名k8s 小白,只有面板使用经验。现在需要为我们公司部署k8s,我在vmWare上创建了三台虚拟机,我已经设置了固定ip,ens33: ip分别是:192.168.0.101,192.168.0.102,192.168.0.103
前置条件我已经准备好了,这三台虚拟机之间能相互通信,也能与我电脑宿主机进行通信。
2.你需要考虑中间所有新手可能的问题及规避并解决,也需要考虑到我是一位对k8s基础知识一点不了解的小白,所以可能需要先讲解重点知识框架体系,后面边部署边简单介绍等等
3.下面开始一步一步带着我完成,每进行一步停顿一步,并告诉我下一步我需要给你提供的信息,我完成后我会告诉你进行下一步,如果部署有问题我也会告诉你,需要你带着我解决问题后在进行下一步。
第一步:环境准备(基础配置)
我们先要确保所有节点的环境满足Kubernetes的基础要求,在三台虚拟机上分别执行以下操作:
- 关闭防火墙和SELinux(防止网络拦截)
sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
- 关闭swap(K8s要求禁用swap)
sudo swapoff -a # 临时关闭
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab # 永久关闭
- 设置主机名和hosts解析(节点之间要用主机名通信)
以第一台机器(192.168.1.101)为例:
sudo hostnamectl set-hostname k8s-master # 只在101执行
# 其他两台分别执行:
# 102执行:sudo hostnamectl set-hostname k8s-node1
# 103执行:sudo hostnamectl set-hostname k8s-node2
编辑所有节点的/etc/hosts
文件,添加:
192.168.0.101 k8s-master
192.168.0.102 k8s-node1
192.168.0.103 k8s-node2
- 允许iptables检查桥接流量(网络要求)
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
- 确认时间同步(节点时间必须一致)
sudo timedatectl set-timezone Asia/Shanghai
sudo systemctl enable --now chronyd
- 测试服务连通性
在虚拟机中非本机执行其他两个命令,在宿主机中执行三个命令。
ping k8s-master
ping k8s-node1
ping k8s-node2
第二步:安装容器运行时和Kubernetes组件
在这一步中,我们将在所有三台节点(k8s-master
、k8s-node1
、k8s-node2
)上安装以下组件:
- 容器运行时:我们选择
containerd
,它是Kubernetes官方推荐的容器运行时。 - Kubernetes组件:包括
kubeadm
(用于初始化集群)、kubelet
(用于管理容器)和kubectl
(用于与集群交互)。
1. 安装containerd(容器运行时)
在所有三台节点上执行以下操作:
-
配置containerd的yum源:
cat <<EOF | sudo tee /etc/yum.repos.d/docker-ce.repo [docker-ce-stable] name=Docker CE Stable - \$basearch baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/\$basearch/stable enabled=1 gpgcheck=1 gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg EOF
-
替换为阿里云镜像源
# 备份原有的yum源配置文件: sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup # 下载阿里云的CentOS镜像源配置文件: sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo # 清理yum缓存并生成新的缓存: sudo yum clean all sudo yum makecache
-
安装containerd:
sudo yum install -y containerd.io
-
配置containerd:
sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml
-
修改containerd配置文件,启用Systemd Cgroup驱动(Kubernetes要求):
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
-
启动并启用containerd:
sudo systemctl enable --now containerd
-
验证containerd是否正常运行:
sudo systemctl status containerd
如果状态显示为
active (running)
,说明containerd已成功启动。
2. 安装Kubernetes组件
在所有三台节点上执行以下操作:
-
配置Kubernetes的yum源:
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-\$basearch enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
-
安装Kubernetes组件:
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
-
启动并启用kubelet:
sudo systemctl enable --now kubelet
-
验证安装:
- 检查
kubeadm
版本:kubeadm version
- 检查
kubectl
版本:kubectl version --client
- 检查
kubelet
状态:sudo systemctl status kubelet
注意:此时
kubelet
可能会显示active (exited)
,这是正常的,因为集群尚未初始化。
- 检查
3. 配置kubelet的Cgroup驱动
Kubernetes要求kubelet
和containerd
使用相同的Cgroup驱动(我们之前已经配置了containerd
使用systemd
驱动,现在需要配置kubelet
)。
- 编辑
kubelet
的配置文件:sudo vi /etc/sysconfig/kubelet
- 添加以下内容:
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
- 重启
kubelet
:sudo systemctl restart kubelet
太好了!既然所有命令都执行成功且没有报错,我们可以继续第三步:初始化Kubernetes集群。在这一步中,我们将在k8s-master
节点上初始化Kubernetes控制平面,然后将k8s-node1
和k8s-node2
节点加入集群。
第三步:初始化Kubernetes集群
1. 在k8s-master
节点上初始化控制平面
- 初始化集群:
在k8s-master
节点上运行以下命令:sudo kubeadm init \ --apiserver-advertise-address=192.168.0.101 \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version v1.28.0 \ --service-cidr=10.96.0.0/12 \ --pod-network-cidr=10.244.0.0/16
参数说明:
--apiserver-advertise-address
:指定Master节点的IP地址(这里是192.168.0.101
)。--image-repository
:指定镜像仓库为阿里云的镜像仓库(避免从Google的仓库拉取镜像失败)。--kubernetes-version
:指定Kubernetes版本(这里使用v1.28.0
,你可以根据需要调整)。--service-cidr
:指定Service的IP地址范围。--pod-network-cidr
:指定Pod的IP地址范围(后续安装网络插件时会用到)。
安装过程中可能会遇到如下错误
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[kubelet-check] Initial timeout of 40s passed.
解决方式:
在所有节点执行以下操作:
- 编辑containerd配置文件:
sudo vi /etc/containerd/config.toml
- 找到[plugins."io.containerd.grpc.v1.cri"] 段落下的sandbox_image配置项,将其修改为:
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
- 重启containerd服务:
sudo systemctl restart containerd
手动预拉取镜像
在k8s-master节点执行:
sudo kubeadm config images pull \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.28.0
预期输出应显示所有镜像拉取成功:
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.28.0
重新初始化集群
sudo kubeadm reset -f && sudo rm -rf /etc/kubernetes/*
sudo kubeadm init \
--apiserver-advertise-address=192.168.0.101 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.28.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
-
等待初始化完成:
初始化过程可能需要几分钟,具体时间取决于网络速度和硬件性能。如果成功,你会看到类似以下的输出:Your Kubernetes control-plane has initialized successfully! 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 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/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.0.101:6443 --token <token> \ --discovery-token-ca-cert-hash sha256:<hash>
-
配置kubectl:
根据初始化成功后的提示,执行以下命令以配置kubectl
:mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
-
验证Master节点状态:
运行以下命令,检查Master节点是否正常运行:kubectl get nodes
输出示例:
NAME STATUS ROLES AGE VERSION k8s-master NotReady control-plane 10s v1.28.0
注意:此时节点的状态为
NotReady
,因为还没有安装网络插件。
2. 安装网络插件(CNI)
我先使用的是方案二,有大坑,最后使用的方案一,解决问题。详细流程可先浏览下方案二。
方案一:
安装docker,配置镜像源
参考:服务器0-1-99 搭建docker部分(注意安装的docker版本要大于20.x)
开始安装网络插件,并检查运行状态
kubectl apply -f https://raw.gitmirror.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl get pod -A
kubectl get nodes
方案二:(有大坑)
Kubernetes需要网络插件来实现Pod之间的通信。我们选择Calico
作为网络插件。
-
安装Calico:
在k8s-master
节点上运行以下命令:kubectl apply -f https://docs.projectcalico.org/v3.25/manifests/calico.yaml
-
验证网络插件是否正常运行:
等待几分钟后,运行以下命令检查Pod状态:kubectl get pods -n kube-system
如果看到
calico
相关的Pod状态为Running
,说明网络插件已成功安装。
如果遇到超时问题,更改阿里云镜像# 删除现有错误配置(防止残留) rm -f calico.yaml # 重新下载原始文件 curl -LO https://docs.projectcalico.org/v3.25/manifests/calico.yaml # 精确执行镜像替换(注意无空格) sed -i 's|docker.io/calico/|registry.cn-hangzhou.aliyuncs.com/calico/|g' calico.yaml # 验证:精确匹配镜像行 grep 'image:' calico.yaml # 重新部署网络组件 kubectl delete -f calico.yaml kubectl apply -f calico.yaml # 查看状态 watch -n 2 kubectl get pods -n kube-system # 查看具体错误日志 kubectl describe pod -n kube-system calico-node-xxxxx # 查看具体Pod事件
-
再次检查节点状态:
运行以下命令:kubectl get nodes
如果
k8s-master
节点的状态变为Ready
,说明集群初始化成功。
3. 将k8s-node1
和k8s-node2
加入集群
-
获取加入命令:
在k8s-master
节点上运行以下命令,获取加入集群的命令:kubeadm token create --print-join-command
输出示例:
kubeadm join 192.168.0.101:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
-
在
k8s-node1
和k8s-node2
上执行加入命令:
在k8s-node1
和k8s-node2
节点上分别运行上一步获取的kubeadm join
命令。例如:sudo kubeadm join 192.168.0.101:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
-
验证节点是否成功加入:
在k8s-master
节点上运行以下命令,检查节点状态:kubectl get nodes
输出示例:
NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 10m v1.28.0 k8s-node1 Ready <none> 2m v1.28.0 k8s-node2 Ready <none> 1m v1.28.0
注意:开始踩大坑了,“只有主节点是ready状态,其他两个都没有成功启动”。这个坑花了好多天才解决,期间一直在使用gpt辅助解决,由于是新手小白,对概念和步骤等及其不熟,所以始终没解决出来。最后从这篇博客中看到了使用kube-flannel插件而不继续使用calico-插件。问题解决:地址
评论区