文档说明

本文档视频教程地址:https://www.bilibili.com/video/BV1HN4y167fQ/

网络拓扑

我之前写过关于在CentOS7上安装单主节点的文章:https://blog.csdn.net/m0_51510236/article/details/130842122。本篇文章讲解如何在CentOS7上搭建多主节点的高可用Kubernetes集群,两种集群的拓扑差别:
在这里插入图片描述

可以看到多主节点集群的node节点和master节点之间还需要一层负载均衡去负载API Server的请求。

IP地址规划

官网建议主节点数量是不低于3的奇数。因为服务器资源的限制,本篇文章讲解的是搭建两个主节点。下表是关于本篇文章的IP地址规划:

IP地址主机名称用途安装的软件
192.168.1.160k8s-master01k8s的第一个主节点kubectl、kubeadm、kubelet、keepalived、haproxy
192.168.1.161k8s-master02k8s的第二个主节点kubectl、kubeadm、kubelet、keepalived、haproxy
192.168.1.162K8s-node01k8s的第一个工作节点kubectl、kubeadm、kubelet
192.168.1.163-负载均衡的虚拟IP地址

keepalived和haproxy最好是单独一个集群。为了节省服务器,本篇文章将使用k8s-master01和k8s-master02做负载均衡集群,其中keepalived的虚拟IP地址为 192.168.1.163。如图三台服务器我已经准备好:
在这里插入图片描述

三台服务器配置如下:

  • cpu:2核心
  • 内存:2g
  • 硬盘:40g

配置可以根据你的需求决定,但建议不要低于这个配置。

安装步骤

环境准备

这个阶段步骤有点多,注意别漏了哦。

关闭防火墙

使用下面这行命令永久关闭防火墙:

systemctl disable --now firewalld

三台服务器都要停止:
在这里插入图片描述

关闭SELinux

这个步骤也是三台服务器都要运行,执行下面这两行命令永久关闭SELinux:

sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0

关闭Swap分区

执行这行命令修改 /etc/fstab 配置文件:

vi /etc/fstab

注释掉带swap的这一行:
在这里插入图片描述

上面修改文件是永久关闭swap,接下来执行这行命令临时关闭swap:

swapoff -a

使用 free -h 命令查看分区情况,看到swap分区大小为0则代表swap关闭成功:
在这里插入图片描述

修改主机名称解析

使用以下命令设置主机名称解析,但是需要注意要改为对应你们自己的IP地址哦:

cat >> /etc/hosts << EOF
192.168.1.160 k8s-master01
192.168.1.161 k8s-master02
192.168.1.162 k8s-node01
EOF

设置主机名称

每台服务器执行的命令:

  • 192.168.1.160: hostnamectl set-hostname k8s-master01
  • 192.168.1.161: hostnamectl set-hostname k8s-master02
  • 192.168.1.162: hostnamectl set-hostname k8s-node01

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

执行下述指令:

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

modprobe overlay
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 参数而不重新启动
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

升级操作系统内核

因为默认的CentOS7内核版本比较低,对ipvs的支持不够好,所以执行这个步骤对CentOS7的内核进行升级到最新的长期维护版本:

导入elrepo gpg key
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
安装elrepo YUM源仓库
yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
安装kernel-lt版本

ml为长期稳定版本,lt为长期维护版本:

yum --enablerepo="elrepo-kernel" install -y kernel-lt.x86_64
设置grub2默认引导为0
grub2-set-default 0
重新生成grub2引导文件
grub2-mkconfig -o /boot/grub2/grub.cfg
重启

然后使用下面命令重启操作系统:

shutdown -r now

然后使用 uname -r 命令就可以查看到系统的内核版本了:
在这里插入图片描述

时间同步

需要保证三台服务器时间同步,执行以下命令在阿里云的时间服务器上同步时间:

yum install ntpdate -y
ntpdate time1.aliyun.com

安装ipset及ipvsadm

请求多的时候可能会导致响应过慢,安装这两个软件能够在一定程度上提升ipvs转发速度:

yum install -y ipset ipvsadm

配置ipvsadm模块加载方式

添加需要加载的模块:

cat > /etc/sysconfig/modules/ipvs.modules << EOF
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

检查结果:
在这里插入图片描述

安装Containerd

下载并安装Containerd

使用下面命令下载containerd的压缩包:

curl -LO https://github.com/containerd/containerd/releases/download/v1.6.24/cri-containerd-cni-1.6.24-linux-amd64.tar.gz

可以看到三台服务器都已经下载成功:
在这里插入图片描述

然后需要执行下面命令执行解压安装:

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

接下来就可以使用这行命令查看containerd的版本号:

containerd -version

可以看到containerd版本号为 v1.6.24
在这里插入图片描述

生成containerd的配置文件

可以使用下面这行命令创建目录并生成containerd的配置文件:

mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml

配置文件(/etc/containerd/config.toml)需要将 sandbox_image 的版本号改一下版本号和镜像地址,因为默认的镜像地址是在谷歌上的,谷歌国内访问不到

默认值:sandbox_image = “registry.k8s.io/pause:3.6”

目标值:sandbox_image = “registry.aliyuncs.com/google_containers/pause:3.9”

修改结果:
在这里插入图片描述

还需要将SystemdCgroup改为true:
在这里插入图片描述

接下来需要配置镜像加速(此步骤可以跳过),可以来到自己的阿里云账号的镜像加速器这里复制镜像加速器地址:
在这里插入图片描述

找到 [plugins."io.containerd.grpc.v1.cri".registry.mirrors] 然后在下面配置如下内容:

[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
          # 注意修改自己的镜像加速器地址
          endpoint = ["https://***.mirror.aliyuncs.com"]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
          endpoint = ["https://registry.aliyuncs.com/google_containers"]

配置如图:
在这里插入图片描述

安装runc

可以看到默认自带的runc运行是会报错的:
在这里插入图片描述

安装 libseccomp

安装runc之前需要先安装一个runc的 libseccomp 依赖,先用下面命令下载 libseccomp 包的源码:

curl -LO https://github.com/opencontainers/runc/releases/download/v1.1.9/libseccomp-2.5.4.tar.gz

可以看到下载成功:
在这里插入图片描述

然后执行下面命令去安装libseccomp的依赖和gcc编译器:

yum install -y gcc gperf

然后执行下面命令进行安装:

tar -zxvf libseccomp-2.5.4.tar.gz
cd libseccomp-2.5.4
./configure
make && make install
安装runc

先来执行下面这行命令来现在runc:

curl -LO https://github.com/opencontainers/runc/releases/download/v1.1.9/runc.amd64

runc下载完成:
在这里插入图片描述

执行下面命令即可安装runc:

rm -rf /usr/local/sbin/runc
chmod +x runc.amd64
mv runc.amd64 /usr/local/sbin/runc

然后执行runc即可看到runc的帮助文档,证明runc安装完成:
在这里插入图片描述

最后需要执行下面这行命令来启动containerd并让它开机自启动:

systemctl enable --now containerd

搭建API Server的负载均衡器

有关kubernetes官方建议的负载均衡器文档地址为:https://github.com/kubernetes/kubeadm/blob/main/docs/ha-considerations.md#options-for-software-load-balancing

安装keepalived和haproxy

在本篇文章最开始讲到需要使用负载均衡来负载API Server。官方文档当中推荐使用的负载均衡器为keepalived和haproxy。在IP地址规划当中,已经规划了将这两个软件安装到 k8s-master01k8s-master02 当中,生产环境建议还是单独的几台服务器构成 keepalived 和 haproxy 的集群。执行下面这一行命令即可安装 keepalived 和 haproxy:

yum install -y keepalived haproxy

修改keepalived的配置文件

这个配置文件的位置位于 /etc/keepalived/keepalived.conf ,其中内容可以直接替换为:

! Configuration File for keepalived
global_defs {
    router_id LVS_DEVEL
}
vrrp_script check_apiserver {
  script "/etc/keepalived/check_apiserver.sh"
  interval 3
  weight -2
  fall 10
  rise 2
}

vrrp_instance VI_1 {
    # 状态,主节点为MASTER,从节点为BACKUP
    state MASTER
    # 修改为你自己网卡的名字
    interface ens33
    virtual_router_id 51
    # MASTER当中使用101,BACKUP当中使用100
    priority 101
    authentication {
        auth_type PASS
        # 设置好你的密码,keepalived集群当中需要保证这个值的一致
        auth_pass xiaohh
    }
    virtual_ipaddress {
        # 注意这里修改为你自己的虚拟IP地址
        192.168.1.163
    }
    track_script {
        check_apiserver
    }
}

配置内容:
在这里插入图片描述

因为配置文件当中编写了一个check_apiserver来检查apiserver是否存活,那么需要在 /etc/keepalived/check_apiserver.sh 当中编写这个脚本。脚本内容为:

#!/bin/sh

errorExit() {
    echo "*** $*" 1>&2
    exit 1
}

curl --silent --max-time 2 --insecure https://localhost:6553/ -o /dev/null || errorExit "Error GET https://localhost:6553/"
if ip addr | grep -q 192.168.1.163; then
    curl --silent --max-time 2 --insecure https://192.168.1.163:6553/ -o /dev/null || errorExit "Error GET https://192.168.1.163:6553/"
fi

注意要修改其中的虚拟IP地址和端口,我会将keepalived的6554端口负载均衡到kubernetes集群的6443端口上。然后还需要将这个文件赋予执行权限,执行下面命令:

chmod +x /etc/keepalived/check_apiserver.sh

修改haproxy的配置文件

安装kubernetes官方提示,需要将 /etc/haproxy/haproxy.cfg 改为以下内容:

# /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log /dev/log local0
    log /dev/log local1 notice
    daemon

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 1
    timeout http-request    10s
    timeout queue           20s
    timeout connect         5s
    timeout client          20s
    timeout server          20s
    timeout http-keep-alive 10s
    timeout check           10s

#---------------------------------------------------------------------
# apiserver frontend which proxys to the control plane nodes
#---------------------------------------------------------------------
frontend apiserver
    # 注意负载均衡的端口要与keepalived里面的配置保持一致
    bind *:6553
    mode tcp
    option tcplog
    default_backend apiserver

#---------------------------------------------------------------------
# round robin balancing for apiserver
#---------------------------------------------------------------------
backend apiserver
    option httpchk GET /healthz
    http-check expect status 200
    mode tcp
    option ssl-hello-chk
    balance     roundrobin
        # 多个主节点直接拼接到后面即可
        server k8s-master01 192.168.1.160:6443 check
        server k8s-master02 192.168.1.161:6443 check

注意修改负载均衡的端口和k8s-master列表。

启动keepalived和haproxy

需要启动keepalived和haproxy并配置其开机自启,可以使用以下两行命令:

systemctl enable --now keepalived
systemctl enable --now haproxy

执行完成后可以看到虚拟IP地址在keepalived的主节点上已经运行成功了:
在这里插入图片描述

搭建Kubernetes多主集群

安装 kubeadm、kubectl、kubelet

上一个步骤我们搭建了keepalived和haproxy的负载均衡器并负载到两个主节点当中,且暴露了6553端口。接下来可以直接安装kubernetes了。执行下面命令添加阿里云的kubernetes的rpm镜像:

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/kubernetes/yum/doc/rpm-package-key.gpg
EOF

然后可以直接执行下面命令安装1.26.9版本的kubectl、kubeadm和kubelet:

yum install -y kubeadm-1.26.9 kubectl-1.26.9 kubelet-1.26.9

可以看到三台服务器都已经安装完成:
在这里插入图片描述

初始化Kubernetes集群

在任意 一个 主节点当中执行这行即可:

kubeadm init \
--apiserver-advertise-address=192.168.1.160 \
--control-plane-endpoint "192.168.1.163:6553" \
--upload-certs \
--image-repository=registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.26.9 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket=unix:///var/run/containerd/containerd.sock
  • –apiserver-advertise-address=192.168.1.160:k8s-master的地址,在哪个master执行就写那个master节点的地址,注意修改为自己的master地址
  • –control-plane-endpoint “192.168.1.163:6553”:keepalived的虚拟IP地址和端口,keepalived和haproxy会将其负载均衡到各个master节点当中
  • –upload-certs:标志用来将在所有控制平面实例之间的共享证书上传到集群
  • –image-repository=registry.aliyuncs.com/google_containers:默认的镜像拉取地址在谷歌,所以这里改为阿里云的镜像地址
  • –kubernetes-version=v1.26.9:kubernetes的版本号
  • –service-cidr=10.96.0.0/12:service的网段
  • –pod-network-cidr=10.244.0.0/16:pod的网段地址,注意之后安装Calico网络插件的时候还会用到这个地址
  • –cri-socket=unix:///var/run/containerd/containerd.sock:设置cri的socket使用containerd的sock

可以看到初始化的结果:
在这里插入图片描述

需要在已经初始化的主节点当中执行这几行命令:

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

主节点加入集群

这个集群当中有两个主节点,但是值初始化了一个,接下来另一个也需要加入集群。需要在上一步的加入命令后面添加上 --cri-socket=unix:///var/run/containerd/containerd.sock 内容,所以完整的加入命令为(⚠️复制你自己的):

kubeadm join 192.168.1.163:6553 --token jxbuxf.z9e5jytyl8ipdrar \
--discovery-token-ca-cert-hash sha256:563acac93d6a44bacca801cf34a04c2874d95cd4d92eb42e49d5304130c90d84 \
--control-plane --certificate-key 8aaa559e0d5a3b81ec03045bd395b453cb2cfe9df2330a50484777a7987c9193 \
--cri-socket=unix:///var/run/containerd/containerd.sock

加入成功后就可以看到集群是一个拥有两个主节点的集群了:
在这里插入图片描述

从节点加入集群

按照提示还需要在加入从节点的命令后面加上 --cri-socket=unix:///var/run/containerd/containerd.sock 内容,所以从节点加入集群的命令为(⚠️复制你自己的):

kubeadm join 192.168.1.163:6553 --token jxbuxf.z9e5jytyl8ipdrar \
--discovery-token-ca-cert-hash sha256:563acac93d6a44bacca801cf34a04c2874d95cd4d92eb42e49d5304130c90d84 \
--cri-socket=unix:///var/run/containerd/containerd.sock

显示工作节点加入成功:
在这里插入图片描述

配置kubelet开机自启动

最后需要在所有节点上配置kubelet开机自启动,执行下面命令:

systemctl enable kubelet

如图三台服务器都要执行:
在这里插入图片描述

安装calico网络插件

calico网络插件官网地址:https://docs.tigera.io/calico/latest/getting-started/kubernetes/quickstart

可以使用官网的这行命令在master当中执行安装Calico:
在这里插入图片描述

命令内容为:

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

执行结果:
在这里插入图片描述

输入以下命令查看内容是否创建成功:

kubectl get all -o wide -n tigera-operator

运行成功:
在这里插入图片描述

接下来还需要创建calico的客户端资源。我们不能直接按照官网提示直接执行那个文件,需要将其拉下来并修改一下内容。执行下面这行命令可以将 custom-resources.yaml 的资源清单文件给拉下来:

curl -LO https://raw.githubusercontent.com/projectcalico/calico/v3.26.3/manifests/custom-resources.yaml

很显然这个网段地址不是我们初始化集群时候用的网段地址:
在这里插入图片描述

执行下面这行命令即可修改好里面的内容:

sed -i 's/cidr: 192.168.0.0/cidr: 10.244.0.0/g' custom-resources.yaml

可以看到网段地址修改成功:
在这里插入图片描述

直接执行下面这行命令就可以创建客户端资源了:

kubectl create -f custom-resources.yaml

因为创建需要在国外拉取镜像,所以比较慢。可以使用这行命令监控内容的创建:

watch kubectl get all -o wide -n calico-system

在一段时间之后可以看到calico安装成功:
在这里插入图片描述

安装Metallb

如果我们需要在自己的Kubernetes中暴露LoadBalancer的应用,那么Metallb是一个不错的解决方案。Metallb官网地址:https://metallb.universe.tf/installation/。首先如图需要修改一下kube-proxy的configmap:
在这里插入图片描述

执行这行命令:

kubectl edit configmap -n kube-system kube-proxy

按照文档修改一下strictARP和mode:
在这里插入图片描述

然后执行下面命令安装Metallb:

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml

执行结果:
在这里插入图片描述

使用这行命令检查是否部署完成:

watch kubectl get all -o wide -n metallb-system

当STATUS都为Running,并且READY的值都为 1/1 那么Metallb就安装完成了:
在这里插入图片描述

因为可能会创建多个对外暴露的Service,所以需要分配多个没有用到的IP地址给MetalLB,新增一个 metallb-ip-pool.yaml 文件,文件内容为:

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  # 注意改为你自己为MetalLB分配的IP地址
  - 192.168.1.164-192.168.1.169

---

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool

执行这个文件可以看到创建成功:
在这里插入图片描述

部署应用

Kubernetes已经搭建好了,现在来部署一个应用程序来试试这个集群。使用这行命令创建一个nginx应用:

kubectl create deployment nginx-deploy --image='docker.io/library/nginx:1.21.6' --replicas=1 --port=80
# or
kubectl create deployment nginx-deploy --image='registry.cn-shenzhen.aliyuncs.com/xiaohh-docker/nginx:1.21.6' --replicas=1 --port=80

执行下面命令可以看到nginx是否部署成功:

kubectl get pod -o wide

可以看到nginx部署成功:
在这里插入图片描述

接下来直接使用这行命令使用LoadBalancer的方式暴露这个nginx:

kubectl expose deployment nginx-deploy --name=nginx-svc --port=80 --target-port=80 --protocol=TCP --type=LoadBalancer

可以看到Service创建成功,并通过LoadBalancer在上一步创建的地址池当中暴露了一个地址:
在这里插入图片描述

访问这个地址发现nginx访问成功:
在这里插入图片描述

多主的高可用Kubernetes集群就已经搭建成功了,祝你们编码愉快

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐