部署Kubernetes(k8s)多主的高可用集群
在CentOS7上安装Kubernetes多主节点的集群,并且安装calico网络插件和metallb。使用keepalived和haproxy进行负载均衡。最后部署应用
文档说明
本文档视频教程地址: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.160 | k8s-master01 | k8s的第一个主节点 | kubectl、kubeadm、kubelet、keepalived、haproxy |
192.168.1.161 | k8s-master02 | k8s的第二个主节点 | kubectl、kubeadm、kubelet、keepalived、haproxy |
192.168.1.162 | K8s-node01 | k8s的第一个工作节点 | 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_netfilter
和 overlay
模块被加载:
lsmod | grep br_netfilter
lsmod | grep overlay
通过运行以下指令确认 net.bridge.bridge-nf-call-iptables
、net.bridge.bridge-nf-call-ip6tables
和 net.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-master01
和 k8s-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集群就已经搭建成功了,祝你们编码愉快
更多推荐
所有评论(0)