PVE虚拟机搭建K8s集群

admin2024-09-11  22

PVE虚拟机搭建K8s集群

创建虚拟机

选择 pve3节点安装虚拟机,此节点的内网网段为 172.110.0.0,在不同的局域网段

PVE虚拟机搭建K8s集群,image-20240810114401053,第1张

选择本地提供的镜像

PVE虚拟机搭建K8s集群,image-20240810114113357,第2张

PVE虚拟机搭建K8s集群,image-20240810114130234,第3张

存储页磁盘总线选择SATA,存储选择HDD卷PVE虚拟机搭建K8s集群,image-20240810114445375,第4张

Master 节点设置的CPU数量为16(不能超过20)

PVE虚拟机搭建K8s集群,image-20240810115044099,第5张

这里的内存应该给的再多一点,因为发现内存的使用率一直在 90%左右

PVE虚拟机搭建K8s集群,image-20240810114526010,第6张

选择vmbr1网卡,这个网卡只能在内网网段使用

PVE虚拟机搭建K8s集群,image-20240810114548123,第7张

PVE虚拟机搭建K8s集群,image-20240810115107465,第8张

PVE虚拟机搭建K8s集群,image-20240810115316725,第9张

PVE虚拟机搭建K8s集群,image-20240810121050291,第10张

创建的虚拟机相关配置

虚拟机名称IP地址主机名称用户名用途
120(group4-ubuntu22.04-Master)172.100.0.106k8s-masterpublicK8S控制平面接点(主节点)
118(group4-ubuntu22.04-node1)172.100.0.104node1publicK8S工作节点1
119(group4-ubuntu22.04-node2)172.100.0.105node2publicK8S工作节点2

PVE虚拟机搭建K8s集群,外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传,第11张

搭建集群

安装前准备

关闭防火墙
sudo systemctl disable --now ufw
设置服务器时区

Ubuntu安装完成之后默认不是中国时区,需要执行以下命令设置为中国上海时区,因为关系到集群机器之间的通信,需要一个时间同步大家的行为。

# 设置为亚洲的上海时区
sudo timedatectl set-timezone Asia/Shanghai
# 重启时间同步服务
sudo systemctl restart systemd-timesyncd.service
# 确保时间同步服务正常运行
timedatectl status	

PVE虚拟机搭建K8s集群,image-20240810121618832,第12张

关闭swap分区

需要关闭所有swap分区,可以修改 /etc/fstab 文件:

sudo vi /etc/fstab

PVE虚拟机搭建K8s集群,image-20240810121728424,第13张

上面是永久关闭,下面可以执行这行命令临时关闭:

sudo swapoff -a
关闭SELinux

Ubuntu默认关闭了selinux,通过以下命令确保selinux已关闭

# 安装policycoreutils软件包
sudo apt install -y policycoreutils
# 检查selinux关闭状态
sestatus

PVE虚拟机搭建K8s集群,image-20240810122034161,第14张

配置hosts配置文件

需要修改 /etc/hosts 配置文件,通过下面命令:

这里文件修改的主要意义是,当工作节点加入集群时,可以通过这个文件,将工作节点的IP映射为名称

sudo vi /etc/hosts

然后注释掉原来的主机名称配置,并将下面这几行解析添加到文件最后(注意修改为自己的IP地址):

172.100.0.106 k8s-master
172.100.0.104 node1
172.100.0.105 node2

PVE虚拟机搭建K8s集群,image-20240810122445911,第15张

转发 IPv4 并让 iptables 看到桥接流量

开这个的原因是让各个主机承担起网络路由的角色,因为后续还要安装网络插件,要有一个路由器各个 Pod 才能互相通信。

执行下述指令:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# 应用 sysctl 参数而不重新启动
sudo sysctl --system

通过运行以下指令确认 br_netfilteroverlay 模块被加载:

lsmod | grep br_netfilter
lsmod | grep overlay

​ 通过运行以下指令确认 net.bridge.bridge-nf-call-iptablesnet.bridge.bridge-nf-call-ip6tablesnet.ipv4.ip_forward 系统变量在你的 sysctl 配置中设置为 1:

sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward

PVE虚拟机搭建K8s集群,image-20240810123043894,第16张

安装容器运行时

安装containerd的容器运行时,下载地址:https://github.com/containerd/containerd/releases/download/v1.7.13/cri-containerd-cni-1.7.13-linux-amd64.tar.gz,可以通过下面命令进行下载:

curl -L --output cri-containerd-cni-1.7.13-linux-amd64.tar.gz https://github.com/containerd/containerd/releases/download/v1.7.13/cri-containerd-cni-1.7.13-linux-amd64.tar.gz

PVE虚拟机搭建K8s集群,image-20240810123723019,第17张

解压到根目录:

sudo tar -zxvf cri-containerd-cni-1.7.13-linux-amd64.tar.gz -C /

启动 containerd 并且开机自启:

sudo systemctl start containerd
sudo systemctl enable containerd

查看安装的版本

containerd -v

PVE虚拟机搭建K8s集群,image-20240810123741471,第18张

通过下面命令创建配置文件目录:

sudo mkdir /etc/containerd

containerd config default | sudo tee /etc/containerd/config.toml

然后修改一下这个文件

sudo vi /etc/containerd/config.toml

修改 sandbox_image 值为 registry.aliyuncs.com/google_containers/pause:3.9

修改 SystemdCgrouptrue(这个配置指定是否使用 systemd 来管理 cgroup,如果 etcd 一直重启的话就开启这个选项试试)

这两个地方不修改,会导致在初始化时,创建沙箱 pod 镜像拉取失败

PVE虚拟机搭建K8s集群,image-20240810133432319,第19张

PVE虚拟机搭建K8s集群,image-20240810133412790,第20张

保持退出之后通过下面命令启动 containerd:

# 重启
sudo systemctl restart containerd
# 设置开机自启动
sudo systemctl enable --now containerd

安装Kubernetes

出现问题的重灾区

在正常的官网的下载安装流程是这样的

更新 apt 包索引并安装使用 Kubernetes apt 仓库所需要的包:

# 保证源都是新的
sudo apt-get update
sudo apt upgrade -y
# 安装一些必要工具
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 次要版本以匹配你所需的次要版本

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

在这一步中,由于服务器无法访问外网,导致密钥无法下载,后续的工具更无法安装,网上有提到使用这个仓库地址,但是,使用后更新 sudo apt-get update 会报错

deb http://apt.kubernetes.io/ kubernetes-xenial main
sudo apt-get update
Hit:1 http://us.archive.ubuntu.com/ubuntu jammy InRelease
Hit:2 http://us.archive.ubuntu.com/ubuntu jammy-updates InRelease
Hit:3 http://us.archive.ubuntu.com/ubuntu jammy-backports InRelease                           
Hit:4 http://security.ubuntu.com/ubuntu jammy-security InRelease                              
Ign:5 https://packages.cloud.google.com/apt kubernetes-xenial InRelease   
Err:6 https://packages.cloud.google.com/apt kubernetes-xenial Release
  404  Not Found [IP: 74.125.142.139 443]
Reading package lists... Done
E: The repository 'https://apt.kubernetes.io kubernetes-xenial Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

在这里使用国内阿里云的镜像网站,并添加 apt 仓库(这里的仓库地址我也是找了比较久,实测仓库密钥没有问题,但是下载的k8s的版本似乎是固定的,目前还没尝试成功调整成为其他的版本,不过v1.28倒也可以用,要注意的是注意其他工具的版本兼容问题)

curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# 要注意kubernetes-xenial main和前面的斜杠之间是有一个空格的,这个空格是必须的
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main' | sudo tee  /etc/apt/sources.list.d/kubernetes.list

最后!!终于可以更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本,防止软件更新(这里直接 -y 只会下载最新版本的,如果要注意不同k8s的版本要求,不兼容的话会出现问题):

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

启动 kubelet ,并且设置开机自启(这里如果不设置开机启动的话,重启服务器的时候,会有kube-system 的一些 pod 出现问题,比如不是Running,变成了Pending等):

sudo systemctl enable --now kubelet

查看版本

kubeadm version

PVE虚拟机搭建K8s集群,image-20240810140010935,第21张

初始化集群

提前拉取镜像

上一步已经确定了安装了v1.28.2 的版本,接下来可以在主节点上执行这行命令将主节点的镜像提前拉取下来:

sudo kubeadm config images pull \
--image-repository=registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.28.2 \
--cri-socket=unix:///run/containerd/containerd.sock

PVE虚拟机搭建K8s集群,image-20240810140539757,第22张

这里也可以使用 yaml 文件拉取

生成文件

kubeadm config print init-defaults > init.default.yaml

编辑文件内容

vi init.default.yaml
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 1.2.3.4
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: k8s-master
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.20.0
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
scheduler: {}

主要修改imageRepository:

k8s.gcr.io -> registry.aliyuncs.com/google_containers

修改完后,要记得重启

systemctl restart kubelet	

通过配置下载镜像

sudo kubeadm config images pull --config=init.default.yaml

PVE虚拟机搭建K8s集群,image-20240810163704614,第23张

可以使用

kubeadm config images list

来查看相关的镜像配置版本是否兼容

初始化节点
sudo kubeadm init \
--apiserver-advertise-address=172.100.0.106 \
--image-repository=registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.28.2 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket=unix:///run/containerd/containerd.sock
# --control-plane-endpoint=k8s-master \

在这一步,也会出现很多问题,比如[kubelet-check] Initial timeout of 40s passed等等

详细错误信息参考

PVE虚拟机搭建K8s集群,image-20240809222326573,第24张

如果出现了问题,就查看日志,排查问题,这里我卡了很久

journalctl -xeu kubelet

要注意每次排查完问题,重新初始化的时候,要重置 kubeadm

sudo kubeadm reset

如果,你非常的幸运,又或者排除万errors,最终会走到初始化成功这一步

PVE虚拟机搭建K8s集群,image-20240810212815569,第25张

​ 首先需要在本机上执行这三条命令,(这里应该是建立环境变量,没有执行的话,在主节点没办法与API server通信(error图片忘记留了),使用kubectl get 等命令时是得不到响应的)

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

同时,这里的 token 是需要保存一下的,因为工作节点加入集群是需要这个token的,同时 token 的有效期大概是24h

 # 如果忘记了 Master 的 Token,可以在 Master 上输入以下命令查看
kubeadm token list
# 默认token的有效期为24小时,当过期之后,该token就不可用了。解决方法如下:
# 重新生成新的token
kubeadm token create
 
# --discovery-token-ca-cert-hash 的查看方法,在 Master 运行以下命令查看 要注意有空格
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

然后在所有工作节点上执行这行命令(注意修改为自己的token),注意后面拼接上 --cri-socket=unix:///var/run/containerd/containerd.sock 参数:(这里我忘了自己的token了,随便粘贴一个网上的例子,大概样子是这样的)

sudo kubeadm join 172.100.0.106:6443 --token jkw9gq.wdjmxylrghz23r3d \
--discovery-token-ca-cert-hash sha256:4fb1b85884d63cd5773ad14822567cd62b4dc5c3b45b6f8f8cfc41a202667f66 \
--cri-socket=unix:///run/containerd/containerd.sock

PVE虚拟机搭建K8s集群,image-20240810213518904,第26张

安装网络插件

​ 本来呢,我觉得,到了上面一步,就已经结束了,但是我发现,我的集群中的节点的状态,全部都是 NotReady ,查了一下原因是因为没有网络插件,因为集群只是在主节点上初始化了,其他机器要想加入集群,还得使用网络插件将它们连接起来,所以得安装一个网络插件,主流的网络插件有很多个,常见的是 Calico 和 flannel,但是这两个插件在安装的时候,出现了各种问题,最后换用了 Cilium 插件

安装 helm
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3

chmod 700 get_helm.sh

./get_helm.sh
安装cilium
helm repo add cilium https://helm.cilium.io

helm install cilium cilium/cilium    --namespace kube-system    --set hubble.relay.enabled=true     --set hubble.ui.enabled=true    --set prometheus.enabled=true    --set operator.prometheus.enabled=true    --set hubble.enabled=true    --set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,http}"


kubectl rollout restart daemonset cilium -n kube-system

安装成功

PVE虚拟机搭建K8s集群,image-20240811152019041,第27张

节点均变为 Ready,系统 Pod 也均正常运行

PVE虚拟机搭建K8s集群,image-20240811160748388,第28张

PVE虚拟机搭建K8s集群,image-20240811214526870,第29张

关于 Calico 和 flannel 安装的一些问题

Calico安装

安装Tigera Calico操作符和自定义资源定义:

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/tigera-operator.yaml

如果报错连接不上的话将文件手动下载下来再执行

wget https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/tigera-operator.yaml
# 或者
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/tigera-operator.yaml

kubectl create -f tigera-operator.yaml 

下载下来后不能用 kubectl apply -f 来执行,会报错

这里没有报错就没有问题

但运行完之后要查看一下 tigera-operator 运行是否正常,如果状态为Running 则继续执行下面的步骤

这里可能会出现 容器创建失败 的情况,查看日志一般是因为镜像拉取失败,查看配置文件关于镜像的部分,这里需要单独拉取镜像

PVE虚拟机搭建K8s集群,image-20240812121415117,第30张

sudo ctr images pull quay.io/tigera/operator:v1.32.5

拉取之后,重新创建配置,一般就没有问题了

kubectl delete -f tigera-operator.yaml 
kubectl create -f tigera-operator.yaml 

第二步将配置文件下载下来,因为要改内容:

# 下载客户端资源文件
curl -LO https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/custom-resources.yaml

这个文件中的 192.168.0.0 为你刚才 init 时指定的 --pod-network-cidr

PVE虚拟机搭建K8s集群,image-20240812122116864,第31张

# 修改pod的网段地址
sed -i 's/cidr: 192.168.0.0/cidr: 10.244.0.0/g' custom-resources.yaml

最后根据这个文件创建资源,执行下面这行命令:

kubectl create -f custom-resources.yaml

但是,在最后这部分,初始化的网络插件,总会出现镜像拉取失败的问题,但是相关的配置文件中,并没有找到镜像相关的配置,且日志中也没有提到拉取哪个镜像失败,至此 Calico 安装失败

Flannel 安装

kube-flannel.yml(使用国内镜像源)

Flannel 安装,参考K8S安装网络插件flannel

# 下载配置文件
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 执行配置文件安装
kubectl apply -f kube-flannel.yml

但是同样镜像拉取,会出现问题,这里需要查看配置文件所需要的镜像,然后在国内的源拉取,打上配置文件的标签(当然也可以直接去配置文件中,更改镜像源地址,但是配置文件非常多,一行一行找效率并不高)

PVE虚拟机搭建K8s集群,image-20240812123304824,第32张

这里粘贴一下源地址https://docker.aityp.com/r/docker.io/flannel/flannel?page=1

ctr images pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel:v0.25.5
ctr images tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel:v0.25.5  docker.io/flannel/flannel:v0.25.5
ctr images pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1
ctr images tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1  docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1

镜像拉取之后,删除文件配置并重新创建

kubectl delete -f kube-flannel.yml
kubectl create -f kube-flannel.yml

至此,flannel 创建没有问题,但是查看网络插件发现,仅有主节点的 flannel pod是Running状态,工作节点的状态均有问题,只有主节点的状态变为了 Ready,工作节点仍未 NotReady ,查日志并没查到问题,没有解决。
/flannel:v0.25.5
ctr images tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel:v0.25.5 docker.io/flannel/flannel:v0.25.5
ctr images pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1
ctr images tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1 docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1


镜像拉取之后,删除文件配置并重新创建

```shell
kubectl delete -f kube-flannel.yml
kubectl create -f kube-flannel.yml

至此,flannel 创建没有问题,但是查看网络插件发现,仅有主节点的 flannel pod是Running状态,工作节点的状态均有问题,只有主节点的状态变为了 Ready,工作节点仍未 NotReady ,查日志并没查到问题,没有解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!