使用kubeadm搭建多节点Kubernetes集群

2022-11-02 23:10:54 浏览数 (1)

一、前言|

安装kubernetes集群,有很多种方式,比如,minikube,kind,kubeadm,但是相较于kubeadm,前2种方式还是有各种不足之处,鉴于此,社区里就出现了一个专门用来在集群中安装 Kubernetes 的工具,名字就叫“kubeadm”,意思就是“Kubernetes 管理员”。

二、kubeadm的安装原理

kubeadm logokubeadm logo

kubeadm安装原理是用容器和镜像来封装 Kubernetes 的各种组件,但它的目标不是单机部署,而是要能够轻松地在集群环境里部署 Kubernetes,并且让这个集群接近甚至达到生产级质量。而在保持这个高水准的同时,kubeadm 只要很少的几条命令,如 init、join、upgrade、reset 就能够完成 Kubernetes 集群的管理维护工作,这让它不仅适用于集群管理员,也适用于开发、测试人员,具有较高的易用性。

三、集群安装

1,背景:

多节点集群,要求服务器应该有两台或者更多,为了简化我们只取最小值,所以这个 Kubernetes 集群就只有两台主机,一台是 Master 节点,另一台是 Worker 节点。当然,在完全掌握了 kubeadm 的用法之后,你可以在这个集群里添加更多的节点。Master 节点需要运行 apiserver、etcd、scheduler、controller-manager 等组件,管理整个集群,所以对配置要求比较高,至少是 2 核 CPU、4GB 的内存

本次实验条件拓扑如下:

kubenets集群拓扑kubenets集群拓扑

2,安装前置条件

  • 配置底层系统参数,<主机名、防火墙、iptables过滤组件、swap设置>
  • 安装底层容器驱动,这里使用docker

3, 安装过程

首先,系统配置

  • 配置主机名,确保节点主机名不一致,这里以master,work为列,修改文件:/etc/hostname
  • 禁用防火墙
代码语言:javascript复制
 sudo ufw disable   禁止开机启动防火墙
 sudo ufw status    查看状态
  • 关闭swap交换分区

Kubernetes 1.8 开始要求关闭系统的 Swap,如果不关闭,默认配置下 kubelet 将无法启动

代码语言:javascript复制
sed -i '/ swap / s/^/#/' /etc/fstab

通过free -mh 可以看到交换分区内存已经禁用了

如下:

查看swap交换分区查看swap交换分区

其次,安装Docker

代码语言:javascript复制
命令如下:
apt install docker.io

大致如下图:

docker安装过程docker安装过程

到这里,docker一般就安装完了,但是鉴于国内的网站访问docker.hub,可能涉及到网络问题,这里一般建议加个国内源,绕开这个问题。设置如下:

代码语言:javascript复制
更新 cgroupdriver 为 systemd,并更新下载源。

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://uy35zvn6.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

随后,重新加载一下docker ,让命令生效

代码语言:javascript复制
systemctl reload docker
systemctl restart docker 

我们可以通过docker version 查看当前的docker 版本。

查看docker版本查看docker版本

第三,配置节点iptables链

代码语言:javascript复制
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

第四,安装kubeadm

kubeadm 可以直接从 Google 自己的软件仓库下载安装,但国内的网络不稳定,很难下载成功,需要改用其他的软件源,这里我选择了国内的某云厂商

代码语言:javascript复制

sudo apt install -y apt-transport-https ca-certificates curl

curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -

cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF

sudo apt update
sudo apt-get update

更新了软件仓库,我们就可以用 apt install 获取 kubeadm、kubelet 和 kubectl 这三个安装必备工具了。apt 默认会下载最新版本,比如使用和 minikube 相同的“1.23.3”:

命令如下:

代码语言:javascript复制
sudo apt-get install -y  kubeadm=1.23.3-00 kubelet=1.23.3-00 kubectl=1.23.3-00

截图如下:

安装完成之后,你可以用 kubeadm version、kubectl version 来验证版本是否正确:

kubeadm version

那么这样就安装成功。

注意 按照 Kubernetes 官网的要求,我们最好再使用命令 apt-mark hold ,锁定这三个软件的版本,避免意外升级导致版本错误:

代码语言:javascript复制
sudo apt-mark hold kubeadm kubelet kubectl

第五 下载 Kubernetes 组件镜像

kubeadm 把 apiserver、etcd、scheduler 等组件都打包成了镜像,以容器的方式启动 Kubernetes,但这些镜像不是放在 Docker Hub 上,而是放在 Google 自己的镜像仓库网站 gcr.io,而它在国内的访问很困难,直接拉取镜像几乎是不可能的。

那怎么办?

我们可以提前在国内某云的镜像内,把此类的镜像提前下载下来,我们可以先查看此master节点需要下载那些组件?

可以通过如下API查看需要的组件详细信息

代码语言:javascript复制
kubeadm config images list --kubernetes-version v1.23.3

大概需要的组件信息如下:

那么我们现在就去某镜像源去下载匹配这类的镜像资源。通过如下API

代码语言:javascript复制
kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version v1.23.3

大概就让他下载就行

下载kubernetes组件镜像下载kubernetes组件镜像

确认下载信息无误后,那么到这里,搭建集群的准备工作就完成了。

第六 安装Master节点

kubeadm 的用法非常简单,只需要一个命令 kubeadm init 就可以把组件在 Master 节点上运行起来,不过它还有很多参数用来调整集群的配置,你可以用 -h 查看。这里我只说一下我们实验环境用到的 3 个参数:--pod-network-cidr,设置集群里 Pod 的 IP 地址段。--apiserver-advertise-address,设置 apiserver 的 IP 地址,对于多网卡服务器来说很重要(比如 VirtualBox 虚拟机就用了两块网卡),可以指定 apiserver 在哪个网卡上对外提供服务。--kubernetes-version,指定 Kubernetes 的版本号

那我这里的设置如下:

代码语言:javascript复制
kubeadm init 
 --kubernetes-version v1.23.3 
 --pod-network-cidr=10.10.0.0/16 
 --apiserver-advertise-address=192.168.50.101 
 --image-repository registry.aliyuncs.com/google_containers 
 --ignore-preflight-errors=all

截图如下:

初始化master节点初始化master节点

根据提示,这步,也操作一下,大意就是要操作kubectl配置文件拷贝:

代码语言:javascript复制
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

其他节点要加入集群必须要用指令里的 token 和 ca 证书,所以这条命令务必拷贝后保存好:

代码语言:javascript复制
        sudo 
        kubeadm join 192.168.50.101:6443 --token 1ayc8g.kalx22bjd3rgmlat 
        --discovery-token-ca-cert-hash sha256:179175bde8bdc11b61185d78da1db56f94537df4890e9b1dd77b6caed5c1748a 

安装完成后,你就可以使用 kubectl version、kubectl get node 来检查 Kubernetes 的版本和集群的节点状态了

查看kubernets版本查看kubernets版本

第七 安装Flannel网络

机器如果没有安装网络插件,节点状态是不正常的。Kubernetes 定义了 CNI 标准,有很多网络插件,这里我选择最常用的 Flannel 它安装也很简单,只需要使用项目的“kube-flannel.yml”在 Kubernetes 里部署一下就好了。不过因为它应用了 Kubernetes 的网段地址,你需要修改文件里的“net-conf.json”字段,把 Network 改成刚才 kubeadm 的参数 --pod-network-cidr 设置的地址段。比如在这里,就要修改成“10.10.0.0/16” 参考:https://github.com/flannel-io/flannel/

代码语言:javascript复制

  net-conf.json: |
    {
      "Network": "10.10.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }

改好后,你就可以用 kubectl apply 来安装 Flannel 网络了:

代码语言:javascript复制
kubectl apply -f kube-flannel.yml

也可以在后面加个 --v=9,打印详细过程

再通过kubectl get node ,我们就可以看到master节点状态恢复正常了

Master 节点状态Master 节点状态

Master 节点的状态是“Ready”,表明节点网络也工作正常了,至此,Master节点工作搭建完成。

第七 安装work节点

除上面的第六步不执行外,其他操作都要全部执行一次。省略。

第八 加入master认证节点,搭建集群。

执行如下命令,一定sudo:

代码语言:javascript复制
sudo 
 kubeadm join 192.168.50.101:6443 --token 1ayc8g.kalx22bjd3rgmlat 
 --discovery-token-ca-cert-hash sha256:179175bde8bdc11b61185d78da1db56f94537df4890e9b1dd77b6caed5c1748a 

返回如下信息,表示节点加入成功。

加入管理集群加入管理集群

它会连接 Master 节点,然后拉取镜像,安装网络插件,最后把节点加入集群.

Worker 节点安装完毕后,执行 kubectl get node ,就会看到两个节点都是“Ready”状态:

注意,如果加入后,发现work节点的status没有ready,可以重新kubeadm reset ,然后再加入就好了

四,集群测试

创建一个pod,命令如下:

代码语言:javascript复制
kubectl run ngx --image=nginx:alpine    

发现,pod建好了,分配在10.10.0.5这个节点上。

五、问题汇总

1,在work节点执行kubectl get node时,节点状态一直未好,解决办法:重新加入

2,若果出现port in use占用的情况,可以通过kubeadm reset进行重置

3,The connection to the server localhost:8080 was refused - did you specify the right host or port?

参考:https://www.cnblogs.com/Ao0216/p/15903134.html https://blog.csdn.net/CEVERY/article/details/108753379

4,创建容器时,一直在creating阶段,可能是网络问题,Failed to create sandbox for pod" err="rpc error: code = Unknown desc = failed to set up sandbox conta>

11月 02 17:16:50 Master kubelet[976180]: E1102 17:16:50.225069 976180 kuberuntime_manager.go:832] "CreatePodSandbox for pod failed" err="rpc error: code = Unknown desc = failed to set up sandbox conta>

11月 02 17:16:50 Master kubelet[976180]: E1102 17:16:50.225136 976180 pod_workers.go:918] "Error syncing pod, skipping" err="failed to "CreatePodSandbox

参考:https://www.likecs.com/show-305671586.html https://blog.csdn.net/sinat_28371057/article/details/113954836

5,the HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed wit 参考:

https://blog.csdn.net/qq_43762191/article/details/125567365

6,终极大招:

代码语言:javascript复制
Kubernetes 还原
集群初始化如果遇到问题,可以使用下面的命令进行清理
# 1. 卸载服务
 
kubeadm reset
 
# 2. 删除相关容器  #删除镜像
 
docker rm $(docker  ps -aq) -f
docker rmi $(docker images -aq) -f
 
# 3. 删除上一个集群相关的文件
 
rm -rf  /var/lib/etcd
rm -rf  /etc/kubernetes
rm -rf $HOME/.kube
rm -rf /var/etcd
rm -rf /var/lib/kubelet/
rm -rf /run/kubernetes/
rm -rf ~/.kube/
 
# 4. 清除网络
 
systemctl stop kubelet
systemctl stop docker
rm -rf /var/lib/cni/*
rm -rf /var/lib/kubelet/*
rm -rf /etc/cni/*
ifconfig cni0 down
ifconfig flannel.1 down
ifconfig docker0 down
ip link delete cni0
ip link delete flannel.1
systemctl start docker
 
# 5. 卸载工具
 
apt autoremove -y kubelet kubectl kubeadm kubernetes-cni
删除 /var/lib/kubelet/ 目录,删除前先卸载
 
for m in $(sudo tac /proc/mounts | sudo awk '{print $2}'|sudo grep /var/lib/kubelet);do
 
sudo umount $m||true
 
done
 
# 6. 删除所有的数据卷
 
sudo docker volume rm $(sudo docker volume ls -q)
 
# 7. 再次显示所有的容器和数据卷,确保没有残留

8,常见的调试API:

代码语言:javascript复制
1,journalctl -xeu kubelet    #查看运行日志
2,kubectl logs pod-id --namespace spaceid
3, kubectl describe podid 
4, kubectl get pod -o yaml    --查看pod的相关配置
5, kubectl get pod -A 
6, kubectl get pod -o wide 
7, kubectl describe pod pod-id
8, kubectl run xxx --v=9  详细打印其过程
9,如果是单master节点,需要去污才能使用。

0 人点赞