本文简介
外面所说的Kubernetes都没有点出高可用什么,扫荡官网最后也只得来一个为防止master单点故障需要高可用部署。而真正的主要部分却被一语带过,只点出需要负载均衡把Api-Server暴露给工作节点。但是,并没有说名过程怎么处理,而这挖了一个坑让你填。
这部分的负载均衡可不是Service那个利用Kube-proxy实现的那个东西。这里需要被负载均衡的是Api-Server那个集群入口,不然集群入口挂了,整体设定再多还是死翘翘。
Kubernetes组件有两种运行方式或者说安装Kubernetes集群有两种方法
第一、所有组件以守护进程的方式部署(二进制那种)
第二、所有组件以Pod托管运行在Kubernetes的(Kubeadm)
本文使用kubeadm有两个原因。第一,官方发布。第二,他解决了5组证书问题。以上原因使用它。
5组证书由来(为什么,简单来说为了安全。实际在集群两种含义作用,一、认证。二、数据加密。)
Etcd集群所需(作为内部集群维持点对点证书一组,作为服务端向外部提供服务一组)
Api-server所需(作为服务端与其他内部组件联系一组,作为服务端与各个节点通信各一组)。
总结一下
Etcd集群维持内部通信一组对外提供服务一组(两组)
Kube-Proxy、Kubelet与Api-server通信分别用一组(两组)
Controller manager、Scheduler与Api-server共用一组
废话少说,正文。
集群高可用架构说明:
| 核心组件 | 高可用模式 | 高可用实现方式 |
|---|---|---|
| Api-server | 集群 | lvs+keepalived |
| Controller-manager | 主备 | leader election |
| Scheduler | 主备 | leader election |
| Etcd(对叠) | 集群 | kubeadm |
Api-server:这里使用LVS+KEEPALIVED实现高可用,通过VIP将请求发给平面控制节点的Api-server。
Controller-manager、Scheduler:在Kubernetes的组件中,Scheduler和Controller-manager两个组件是有leader选举的(--leader-elect这个参数控制,默认是开得true),这个选举机制是Kubernetes对于这两个组件的高可用保障。即正常情况下,多副本只有一个是处于运行状态。其它副本则不断的尝试去获取锁,竞争leader,直到自己成为leader。若运行中的leader,因某种原因导致当前进程退出,或者锁丢失。则有其它副本去竞争成为新的leader,继续执行业务逻辑。
Etcd:通过Kubeadm运行初始化,自动创建Etcd成员形成集群高可用(部署节点为奇数不是说偶数不可以,会有另一片文章整理原因)
准备安装工作:
1、配置主机名
cat >> /etc/hosts << EOF
172.21.130.169 master
172.21.130.168 master1
172.28.17.85 master2
EOF
2、查验网卡的mac与uuid(防止是虚拟机克隆网络地址uuid没变导致异常安装失败)
cat /sys/class/net/eth0/address
cat /sys/class/dmi/id/product_uuid
[root@master ~]# cat /sys/class/net/eth0/address
00:16:3e:30:7a:fb
[root@master ~]# cat /sys/class/dmi/id/product_uuid
A35F2F71-FC1F-4A3E-BE87-A634FB2FAD26
3、有swap禁用,没有忽略(永久禁用就在/etc/fstab直接注释)
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
4、内核参数修改
使用flannel需要设置内核参数bridge-nf-call-iptables=1,要br_netfilter模块的支持。我用的是calico所以不设置这条(方法提供在下面)
但是我加载了其他参数
查看br_netfilter模块
lsmod | grep br_netfilter
加载模块
modprobe br_netfilter
开机自动加载(永久加载)
cat > /etc/rc.sysinit << EOF
#!/bin/bash
for file in /etc/sysconfig/modules/*.modules ; do
[ -x $file ] && $file
done
EOF
cat > /etc/sysconfig/modules/br_netfilter.modules << EOF
modprobe br_netfilter
EOF
chmod 755 /etc/sysconfig/modules/br_netfilter.modules
查询网桥转发配置发现没有(安装软件后自己就出来了)
网桥属于数据链路层(网络基础)。在iptables没有开启 bridge-nf时,数据会直接经过网桥转发。结果就是FORWARD的设置失效
配置后就是所有二层数据也需要经过iptables的FORWARD匹配放行
默认不开启 bridge-nf
[root@master init.d]# sysctl -a | grep bridge
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
永久生效
cat <<EOF > /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 加载
sysctl -p /etc/sysctl.d/k8s.conf
临时修改可以
sysctl net.bridge.bridge-nf-call-iptables=1
5、关闭防火墙(firewalld,别像我手欠习惯俩都关iptables不管Kube-proxy是ipvs模式还是iptables模式都需要iptables的支持)、SELINUX
systemctl stop firewalld
systemctl disable firewalld
disabled需要更改后重启生效
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
6、配置docker、Kubernetes软件源
# 新增 Docker 仓库,速度慢的可以换阿里云的源。
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 这部分用是阿里云的源,如果可以访问Google,则建议用官方的源(国内这个需要点科技感)
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 官方源配置如下
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
7、进行时间同步,确认一下同步是否成功(分布式系统时间敏感,容易出问题。实时的就更敏感了,集群中Etcd里的数据实时的。)
第二个命令前提是安装NTP为了实现与NTP服务器自动时间同步
timedatectl
timedatectl set-ntp true
安装集群:
1、安装软件docker、kubeadm、kubelet、kubectl
如果选择的版本不一样,在执行集群初始化的时候,注意 –kubernetes-version 的值。
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
yum install -y containerd.io-1.2.10 \
docker-ce-19.03.4 \
docker-ce-cli-19.03.4
yum install -y kubelet-1.20.5 kubeadm-1.20.5 kubectl-1.20.5 --disableexcludes=kubernetes
2、配置镜像加速器,并修改docker的Cgroup Drivier,存储驱动也改了
自己创建别犹豫,这文件默认没有
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"registry-mirrors":[
"https://kfwkfulq.mirror.aliyuncs.com",
"https://2lqq34jg.mirror.aliyuncs.com",
"https://pee6w651.mirror.aliyuncs.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com"
]
}
EOF
systemctl daemon-reload
3、镜像下载
cat >> images_download.sh << EOF
#!/bin/bash
set -ex
url=registry.cn-hangzhou.aliyuncs.com/google_containers
version=v1.20.5
kubeadm config images list --kubernetes-version=${version} --image-repository=${url}
if [[ `echo $?` -eq 0 ]]; then
echo "Please wait pull images......"
kubeadm config images pull --kubernetes-version=${version} --image-repository=${url}
echo "pull images ok"
fi
EOF
chmod +x images_download.sh
4、初始化master节点(临时配置VIP初始化)
cat init-config.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: 0.0.0.0
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: master
---
apiServer:
certSANs:
- master
- master1
- master2
- 172.21.130.169
- 172.21.130.168
- 172.28.17.85
- 172.16.0.1 #VIP
timeoutForControlPlane: 4m0s
controlPlaneEndpoint: "172.16.0.1:6443"
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.20.5
networking:
dnsDomain: cluster.local
serviceSubnet: 10.10.0.0/12
podSubnet: 10.20.0.0/16
scheduler: {}
controlPlaneEndpoint 高可用一定要加不然会在添加控制平面的时候报错
--apiserver-advertise-address 0.0.0.0
# API 服务器所公布的其正在监听的 IP 地址,指定“0.0.0.0”以使用默认网络接口的地址
# 切记只可以是内网IP,不能是外网IP,如果有多网卡,可以使用此选项指定某个网卡
--control-plane-endpoint
# 为控制平面指定一个稳定的 IP 地址或 DNS 名称,
--node-name master
# 指定节点的名称,不指定的话为主机hostname,默认可以不指定
--service-dns-domain cluster.local
# 为Service另外指定域名,默认"cluster.local"
--upload-certs
# 将 Control-plane 用来将在所有控制平面实例之间的共享证书上传到集群kubeadm-certs Secret。 如果正好相反,你更喜欢手动地通过控制平面节点或者使用自动化 请删除此标志
执行初始化
kubeadm init --config=init-config.yaml --upload-certs
高可用部署
IPVS安装
LVS无需安装,安装的是管理工具,第一种叫ipvsadm,第二种叫keepalive。ipvsadm是通过命令行管理,而keepalive读取配置文件管理。
yum -y install ipvsadm
加载IPVSADM模块
ipvsadm
lsmod | grep ip_vs
安装KEEPALIVED
yum -y install keepalived
配置文件
节点1
cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id lvs-keepalived01 #router_id 机器标识,通常为hostname,但不一定非得是hostname。故障发生时,邮件通知会用到。
}
vrrp_instance VI_1 { #vrrp实例定义部分
state MASTER #设置lvs的状态,MASTER和BACKUP两种,必须大写
interface eth0 #设置对外服务的接口
virtual_router_id 100 #设置虚拟路由标示,这个标示是一个数字,同一个vrrp实例使用唯一标示
priority 100 #定义优先级,数字越大优先级越高,在一个vrrp——instance下,master的优先级必须大于backup
advert_int 1 #设定master与backup负载均衡器之间同步检查的时间间隔,单位是秒
authentication { #设置验证类型和密码
auth_type PASS #主要有PASS和AH两种
auth_pass 1111 #验证密码,同一个vrrp_instance下MASTER和BACKUP密码必须相同
}
virtual_ipaddress { #设置虚拟ip地址,可以设置多个,每行一个
172.16.0.1
}
}
virtual_server 172.16.0.1 6443 { #设置虚拟服务器,需要指定虚拟ip和服务端口
delay_loop 6 #健康检查时间间隔
lb_algo wrr #负载均衡调度算法
lb_kind DR #负载均衡转发规则
#persistence_timeout 50 #设置会话保持时间,对动态网页非常有用
protocol TCP #指定转发协议类型,有TCP和UDP两种
real_server 172.21.130.169 6443 { #配置服务器节点1,需要指定real server的真实IP地址和端口
weight 10 #设置权重,数字越大权重越高
TCP_CHECK { #realserver的状态监测设置部分单位秒
connect_timeout 10 #连接超时为10秒
retry 3 #重连次数
delay_before_retry 3 #重试间隔
connect_port 6443 #连接端口为6443,要和上面的保持一致
}
}
real_server 172.21.130.168 6443 { #配置服务器节点1,需要指定real server的真实IP地址和端口
weight 10 #设置权重,数字越大权重越高
TCP_CHECK { #realserver的状态监测设置部分单位秒
connect_timeout 10 #连接超时为10秒
retry 3 #重连次数
delay_before_retry 3 #重试间隔
connect_port 6443 #连接端口为6443,要和上面的保持一致
}
}
real_server 172.28.17.85 6443 { #配置服务器节点1,需要指定real server的真实IP地址和端口
weight 10 #设置权重,数字越大权重越高
TCP_CHECK { #realserver的状态监测设置部分单位秒
connect_timeout 10 #连接超时为10秒
retry 3 #重连次数
delay_before_retry 3 #重试间隔
connect_port 6443 #连接端口为6443,要和上面的保持一致
}
}
}
节点2
cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id lvs-keepalived02 #router_id 机器标识,通常为hostname,但不一定非得是hostname。故障发生时,邮件通知会用到。
}
vrrp_instance VI_1 { #vrrp实例定义部分
state BACKUP #设置lvs的状态,MASTER和BACKUP两种,必须大写
interface eth0 #设置对外服务的接口
virtual_router_id 100 #设置虚拟路由标示,这个标示是一个数字,同一个vrrp实例使用唯一标示
priority 90 #定义优先级,数字越大优先级越高,在一个vrrp——instance下,master的优先级必须大于backup
advert_int 1 #设定master与backup负载均衡器之间同步检查的时间间隔,单位是秒
authentication { #设置验证类型和密码
auth_type PASS #主要有PASS和AH两种
auth_pass 1111 #验证密码,同一个vrrp_instance下MASTER和BACKUP密码必须相同
}
virtual_ipaddress { #设置虚拟ip地址,可以设置多个,每行一个
172.16.0.1
}
}
virtual_server 172.16.0.1 6443 { #设置虚拟服务器,需要指定虚拟ip和服务端口
delay_loop 6 #健康检查时间间隔
lb_algo wrr #负载均衡调度算法
lb_kind DR #负载均衡转发规则
#persistence_timeout 50 #设置会话保持时间,对动态网页非常有用
protocol TCP #指定转发协议类型,有TCP和UDP两种
real_server 172.21.130.169 6443 { #配置服务器节点1,需要指定real server的真实IP地址和端口
weight 10 #设置权重,数字越大权重越高
TCP_CHECK { #realserver的状态监测设置部分单位秒
connect_timeout 10 #连接超时为10秒
retry 3 #重连次数
delay_before_retry 3 #重试间隔
connect_port 6443 #连接端口为6443,要和上面的保持一致
}
}
real_server 172.21.130.168 6443 { #配置服务器节点1,需要指定real server的真实IP地址和端口
weight 10 #设置权重,数字越大权重越高
TCP_CHECK { #realserver的状态监测设置部分单位秒
connect_timeout 10 #连接超时为10秒
retry 3 #重连次数
delay_before_retry 3 #重试间隔
connect_port 6443 #连接端口为6443,要和上面的保持一致
}
}
real_server 172.28.17.85 6443 { #配置服务器节点1,需要指定real server的真实IP地址和端口
weight 10 #设置权重,数字越大权重越高
TCP_CHECK { #realserver的状态监测设置部分单位秒
connect_timeout 10 #连接超时为10秒
retry 3 #重连次数
delay_before_retry 3 #重试间隔
connect_port 6443 #连接端口为6443,要和上面的保持一致
}
}
}
取消之前的VIP
ifconfig eth0:1 172.16.0.1 netmask 255.255.0.0 down
启动KEEPALIVED
systemctl start keepalived
systemctl enable keepalived
控制节点配置
打开所在服务器的"路由"功能、关闭"ARP查询"功能并设置回环ip,三台control plane配置相同
cd /etc/rc.d/init.d/
cat realserver.sh
#!/bin/bash
SNS_VIP=172.16.0.1
case "$1" in
start)
ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP
/sbin/route add -host $SNS_VIP dev lo:0
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p >/dev/null 2>&1
echo "RealServer Start OK"
;;
stop)
ifconfig lo:0 down
route del $SNS_VIP >/dev/null 2>&1
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "RealServer Stoped"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
exit 0
chmod u+x realserver.sh
/etc/rc.d/init.d/realserver.sh start
设置开机自启动
sed -i '$a /etc/rc.d/init.d/realserver.sh start' /etc/rc.d/rc.local
chmod u+x /etc/rc.d/rc.local
其余Client常规操作即可
到此高可用结束
自动化copy证书可用
#!/bin/bash
set -ex
USER=root
CONTROL_PLANE_IPS="172.21.130.168 172.28.17.85"
for host in ${CONTROL_PLANE_IPS}; do
ssh ${USER}@${host} "if [ -d /etc/kubernetes/pki ]; then exit 0; else mkdir /etc/kubernetes/pki; fi"
scp -r /etc/kubernetes/pki/* ${USER}@${host}:/etc/kubernetes/pki/
done
浙公网安备 33010602011771号