高可用Kubernetes集群搭建
一、前言介绍
1.1 重要概念
cluster
cluster是 计算、存储和网络资源的集合,k8s利用这些资源运行各种基于容器的应用。
master
master是cluster的大脑,他的主要职责是调度,即决定将应用放在那里运行。master运行linux操作系统,可以是物理机或者虚拟机。为了实现高可用,可以运行多个master。
node
node的职责是运行容器应用。node由master管理,node负责监控并汇报容器的状态,同时根据master的要求管理容器的生命周期。node运行在linux的操作系统上,可以是物理机或者是虚拟机。
pod
pod是k8s的最小工作单元。每个pod包含一个或者多个容器。pod中的容器会作为一个整体被master调度到一个node上运行。
controller
k8s通常不会直接创建pod,而是通过controller来管理pod的。controller中定义了pod的部署特性,比如有几个副本,在什么样的node上运行等。为了满足不同的业务场景,k8s提供了多种controller,包括deployment、replicaset、daemonset、statefulset、job等。
deployment
是最常用的controller。deployment可以管理pod的多个副本,并确保pod按照期望的状态运行。
replicaset
实现了pod的多副本管理。使用deployment时会自动创建replicaset,也就是说deployment是通过replicaset来管理pod的多个副本的,我们通常不需要直接使用replicaset。
daemonset
用于每个node最多只运行一个pod副本的场景。正如其名称所示的,daemonset通常用于运行daemon。
statefuleset
能够保证pod的每个副本在整个生命周期中名称是不变的,而其他controller不提供这个功能。当某个pod发生故障需要删除并重新启动时,pod的名称会发生变化,同时statefulset会保证副本按照固定的顺序启动、更新或者删除。
job
用于运行结束就删除的应用,而其他controller中的pod通常是长期持续运行的。
service
deployment可以部署多个副本,每个pod 都有自己的IP,外界如何访问这些副本呢?答案是service
k8s的 service定义了外界访问一组特定pod的方式。service有自己的IP和端口,service为pod提供了负载均衡。
k8s运行容器pod与访问容器这两项任务分别由controller和service执行。
namespace
可以将一个物理的cluster逻辑上划分成多个虚拟cluster,每个cluster就是一个namespace。不同的namespace里的资源是完全隔离的。
二、系统架构
2.1 架构基本需求
- 配置三台机器 kubeadm 的最低要求 给主节点
- 配置三台机器 kubeadm 的最低要求 给工作节点
- 在集群中,所有计算机之间的完全网络连接(公网或私网)
- 所有机器上的 sudo 权限
- 每台设备对系统中所有节点的 SSH 访问
- 在所有机器上安装 kubeadm 和 kubelet,kubectl 是可选的。
2.2 架构图
三、环境准备
3.1 云服务或虚拟机清单
准备4台,2G或更大内存,2核或以上CPU,30G以上硬盘 物理机或云主机或虚拟机 2、系统centos 7.x
服务器 | 主机名 | IP | 最低配置 |
---|---|---|---|
虚拟机 | master01 | 10.211.55.xx | 2C2G |
虚拟机 | master02 | 10.211.55.xx | 2C2G |
虚拟机 | master03 | 10.211.55.xx | 2C2G |
虚拟机 | worker01 | 10.211.55.xx | 2C2G |
3.2 网络配置(针对使用vmware虚拟机用户需要操作)
用ip addr命令查询网络配置的文件,如果没有ip则需要配置 ls /etc/sysconfig/network-scripts/
查看当前目录下的文件,一般该文件是以ifcfg-eno开头的文件 编辑该文件;把最后的ONBOOT,要设为yes. 在root权限下输入shutdown -r now
, 此时再输入ip add,查看ip,记下它,如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8VVw27fy-1680347853785)(/Users/laiql/Library/Application Support/typora-user-images/image-20230401190245837.png)]
为了让虚拟机IP固定,我们关闭DHCP设置,并设置固定IP。
3.3 虚拟机网络设置(NAT网络配置)
3.4 Centos7网络设置
我们需要进入网卡存放目录,执行如下命令:
cd /etc/sysconfig/network-scripts #查看网卡列表 ls #找到需要修改的网卡 ifcfg-ens33(一般来说就是第一个) vi ifcfg-ens33
3.5 修改网卡(重点)
主要修改IP规划
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
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="eth0"
DEVICE="eth0"
ONBOOT="yes"
DNS1="8.8.8.8"
NETMASK="255.255.255.0"
#以下是网卡需要修改项
BOOTPROTO="static"
#每一台机器不一样,copy需要注意
UUID="fd77c3c8-18b6-4c75-b0aa-5f30a8f42f44"
#IP规划,根据自己网段来配置
IPADDR="xxxx"
#网关地址
GATEWAY="xxxx"
以上就是网卡配置,配置完成我们需要重启一下网卡,执行如下命令:
systemctl restart network
3.6 设置hostname
配置各个虚拟机的hostname,确保集群各个虚拟机的hostname不一样。
#根据规划设置主机名
#master01节点执行
hostnamectl set-hostname master01
#master02节点执行
hostnamectl set-hostname master02
#master03节点执行
hostnamectl set-hostname master03
#worker01节点执行
hostnamectl set-hostname worker01
3.7 修改hosts文件映射(注意替换你的规划每一台机器的IP)
给所有主机添加hosts文件内容,使其能互相通过主机名访问。
#在所有机器上执行
cat >> /etc/hosts << EOF
10.211.55.xx k8svip
10.211.55.xx master01
10.211.55.xx master02
10.211.55.xx master03
10.211.55.xx worker01
EOF
3.8 关闭防火墙
这里为了简单直接关闭防火墙,必要情况下可以开启防火墙然后开启以下端口即可:
组件 | 端口 | 参数 | 默认值 | 协议 | 必须开启 | 说明 |
---|---|---|---|---|---|---|
kube-apiserver | 安全端口 | –secure-port | 6443 | HTTPS | 是 | - |
kube-apiserver | 非安全端口 | –insecure-port | 8080 | HTTP | 否,0表示关闭 | deprecated |
kubelet | 健康检测端口 | –healthz-port | 10248 | HTTP | 否,0表示关闭 | - |
kube-proxy | 指标端口 | –metrics-port | 10249 | HTTP | 否,0表示关闭 | - |
kubelet | 安全端口 | –port | 10250 | HTTPS | 是 | 认证与授权 |
kube-scheduler | 非安全端口 | –insecure-port | 10251 | HTTP | 否,0表示关闭 | deprecated |
kube-controller-manager | 非安全端口 | –insecure-port | 10252 | HTTP | 否,0表示关闭 | deprecated |
kubelet | 非安全端口 | –read-only-port | 10255 | HTTP | 否,0表示关闭 | - |
kube-proxy | 健康检测端口 | –healthz-port | 10256 | HTTP | 否,0表示关闭 | - |
kube-controller-manager | 安全端口 | –secure-port | 10257 | HTTPS | 否,0表示关闭 | 认证与授权 |
kube-scheduler | 安全端口 | –secure-port | 10259 | HTTPS | 否,0表示关闭 | 认证与授权 |
配置建议(如果没有特殊需求,可以关闭防火墙)
除了四个安全端口以外,其他端口都建议关闭。另外,kube-apiserver、kube-controller-manager、kube-scheduler的非安全端口这个参数在未来的版本中会被废弃掉。
#关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
3.9 禁用swap分区
kubernetes的想法是将实例紧密包装到尽可能接近100%。 所有的部署应该与CPU /内存限制固定在一起。 所以如果调度程序发送一个pod到一台机器,它不应该使用交换。 设计者不想交换,因为它会减慢速度,关闭swap主要是为了性能考虑。
#关闭
swap swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab
3.10 关闭selinux
关于selinux的原因(关闭selinux以允许容器访问宿主机的文件系统)
#关闭
selinux sed -i 's/enforcing/disabled/' /etc/selinux/config && setenforce 0
3.11 时间同步
同步pod和宿主机时区
#时间同步
yum install ntpdate -y && ntpdate time.windows.com
四、 安装Docker(所有节点安装)
4.1 开始docker安装服务
给所有机器都执行下面命令进行Docker安装
sudo yum -y install docker-ce-20.10.0
4.2 安装docker问题记录
- 如果出现docker镜像下载不了,超时情况,这个时候说明你的网络被强了,这里提供两个方向的解决思路,第一个:通过VPN访问,第二个:更换软件源,这里只说更换软件源。
# Step 1: 添加软件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 2: 更新并安装Docker-CE
sudo yum makecache fast
# Step 3:重新执行安装Docker命令
sudo yum -y install docker-ce-20.10.0
\2. 如果安装成功,但是出现拉取镜像慢的情况,那可能你的网络被强了,所以此时我们还是只能通过更换为国内镜像加速地址。
# docker镜像加速,"https://xxxx.mirror.aliyuncs.com"这个地址建议自己登陆阿里云,在容器镜像服务中找到。
# 可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxx.mirror.aliyuncs.com"]
}
EOF
#加载daemon配置和重启docker
sudo systemctl daemon-reload && sudo systemctl restart docker
五、 安装Kubernetes(所有节点安装)
K8s软件版本清单
软件 | 版本 |
---|---|
CentOS | 7.4 |
Kubernetes | v1.21.3 |
Docker | 20.10.0 |
pause | 3.4.1 |
etcd | 3.4.13-0 |
coredns | v1.8.0 |
5.1 开始安装k8s组件
给所有机器都执行下面命令进行k8s组件安装,下面命令是安装v1.21.3版本
#在4台机器运行
yum install -y kubelet-1.21.3 kubeadm-1.21.3 kubectl-1.21.3 && systemctl enable kubelet && systemctl start kubelet
5.2 安装k8s组件问题记录
执行上面命令出现很慢,可能是网络问题,如果你本地不能访问国外网站,那你可能需要更换软件源,此时你需要执行如下命令操作。
#添加kubernetes阿里YUM源
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
#重新执行安装k8s组件命令
yum install -y kubelet-1.21.3 kubeadm-1.21.3 kubectl-1.21.3 && systemctl enable kubelet && systemctl start kubelet
六、keepalived + haproxy 搭建高用集群(节点准备完成后开始搭建高可用)
6.1 haproxy+keepalived高可用负载均衡原理
在两台Haproxy的主机上分别运行着一个Keepalived实例,这两个Keepalived争抢同一个虚IP地址,两个Haproxy也尝试去绑定这同一个虚IP地址上的端口。显然,同时只能有一个Keepalived抢到这个虚IP,抢到了这个虚IP的Keepalived主机上的Haproxy便是当前的MASTER。Keepalived内部维护一个权重值,权重值最高的Keepalived实例能够抢到虚IP。同时Keepalived会定期check本主机上的HAProxy状态,状态OK时权重值增加。
6.2 开始安装keepalived 和 haproxy
在三台master集群节点上安装高可用负载均衡组件keepalived和 haproxy 。
#在3台master机器运行
#安装keepalived 和 haproxy
yum install haproxy keepalived -y
6.3 配置keepalived 和 haproxy
首先我们先把原始的keepalived和haproxy配置都统一备份一下,以便后续操作。然后我们在/etc/keepalived/
目录新建keepalived.conf
文件和check_apiserver.sh
,在/etc/haproxy
目录创建haproxy.cfg
文件。
#step 1: 在三台master集群节点上运行备份命令
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
6.3 .1 keepalived.conf (修改配置注意【#需要修改成你的vpi虚拟IP】提示修改项)
keepalived配置
全局定义块:对整个 Keepalive 配置生效的,不管是否使用 LVS; VRRP 实例定义块:是 Keepalived 的核心; 虚拟服务器(LVS)定义块:LVS 配置只在使用 Keepalived 来配置和管理 LVS 时才需要使用,如果仅仅使用 Keepalived做 HA,LVS 的配置完全是不需要的
#在3台master机器运行
#############################keepalived.conf start################################
! /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 {
state MASTER
interface ens33
virtual_router_id 51
priority 98
authentication {
auth_type PASS
auth_pass 1111
}
#需要修改成你的vpi虚拟IP
virtual_ipaddress {
10.211.55.xx/24
}
track_script {
check_apiserver
}
}
#需要按需修改的参数
#state MASTE/SLAVE
#interface 主网卡名称
#虚拟id
#优先级priority
#virtual_ipaddress 虚拟ip
#############################keepalived.conf end################################
6.3 .2 check_apiserver.sh
check_apiserver脚本用于检测校验apiserver服务,添加完成后需要给check_apiserver.sh添加权限。
#在3台master机器运行
#############################check_apiserver.sh start################################
#!/bin/bash
#需要修改成你的vpi虚拟IP
APISERVER_VIP=10.211.55.xx
APISERVER_DEST_PORT=6443
errorExit() {
echo "*** $*" 1>&2
exit 1
}
curl --silent --max-time 2 --insecure https://localhost:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://localhost:${APISERVER_DEST_PORT}/"
if ip addr | grep -q ${APISERVER_VIP}; then
curl --silent --max-time 2 --insecure https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/"
fi
#记得给此文件执行权限
#chmod +x /etc/keepalived/check_apiserver.sh
#需要修改的参数
#APISERVER_VIP 虚拟ip
#############################check_apiserver.sh end################################
6.3.3 haproxy.cfg
haproxy的配置文件通常分为三部分: global(全局配置部分) defaults(默认配置部分) listen(应用组件部分)
#在3台master机器运行
#############################haproxy.cfg################################
# /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
log /dev/log local0
log /dev/log local1 notice
daemon
#--------------------------------------------