10 Kubernetes-高可用部署
一、相关概念
1、ETCD 高可用
ETCD集群中,使用Raft算法,实现高可用
每一个 Raft 集群中都包含多个服务器,在任意时刻,每一台服务器只可能处于 Leader、Follower 以及 Candidate 三种状态;在处于正常的状态时,集群中只会存在一个 Leader,其余的服务器都是 Follower
ETCD高可用集群:
建议 3、5、7、9个高可用节点
3个高可用节点只能有一次损坏
ETCD-CLUSTER:搭建高可用集群的方式
ETCD 框架:
2、Schedule、ControllerManager 高可用
通过与ETCD的信息绑定,决定主节点
3、Apiserver高可用
本质上为web服务,搭建多个apiserver,然后在外部搭建负载,实现高可用
4、高可用总结方案
5、高可用的实现方式
1)自动化安装工具实现
2)更改kubeadm源码实现
二、Sealos自动化工具实现高可用
-
99年证书
-
0依赖,不依赖ansible haproxy keepalived, 一个二进制工具
-
离线安装,不同kubernetes版本下载对应不同版本的资源包即可,离线包包含所有二进制文件配置文件和镜像
-
高可用通过ipvs实现的localLB,占用资源少,稳定可靠,类似kube-proxy的实现
-
几乎可兼容所有支持systemd的x86_64架构的环境
-
轻松实现集群节点的增加/删除
-
上千用户在线上环境使用sealos,稳定可靠
-
资源包放在阿里云oss上,再也不用担心网速
-
dashboard ingress prometheus等APP 同样离线打包,一键安装
sealos 架构图
基于本机的 ipvs 实现高可用
初始化集群时,通过域名指向各个节点的 ApiServer( 每个master 指向自己,node节点指向ipvs-vs )
在 pod 中运行程序,实现监听 ApiServer 的存活信息
高可用搭建步骤:
1)虚拟机准备
Ⅰ 五个节点设置
搭建环境:3个master节点,2个node节点
注意:初始化集群时,只用一张网卡
Ⅱ 关闭多余的网卡,仅留一张网卡
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens34
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens34 |grep ONBOOT
ONBOOT=no
[root@localhost ~]# systemctl restart network
# 并将剩余的网卡指向路由
Ⅲ、测试访问
[root@localhost ~]# ping www.baidu.com
PING www.a.shifen.com (14.215.177.38) 56(84) bytes of data.
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=1 ttl=127 time=31.7 ms
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=2 ttl=127 time=32.3 ms
64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=3 ttl=127 time=31.6 ms
^C
--- www.a.shifen.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 6126ms
rtt min/avg/max/mdev = 31.600/31.893/32.355/0.389 ms
2)系统初始化(所有节点)
1、设置系统主机名以及 Host 文件的相互解析
#主机名设置
#C7-1
[root@localhost ~]# hostnamectl set-hostname k8s-master01
#C7-2
[root@localhost ~]# hostnamectl set-hostname k8s-master02
#C7-3
[root@localhost ~]# hostnamectl set-hostname k8s-master03
#C7-4
[root@localhost ~]# hostnamectl set-hostname k8s-node01
#C7-5
[root@localhost ~]# hostnamectl set-hostname k8s-node02
#所有主机的hosts解析
[root@localhost ~]# vim /etc/hosts
[root@localhost ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.20.201 k8s-master01 m1
192.168.20.202 k8s-master02 m2
192.168.20.203 k8s-master03 m3
192.168.20.204 k8s-node01 n1
192.168.20.205 k8s-node02 n2
192.168.20.206 harbor.yq.com
2、安装依赖包
yum install -y conntrack ntpdate ntp ipvsadm ipset iptables curl sysstat libseccomp wget vim net-tools git
3、设置防火墙为 Iptables 并设置空规则
systemctl stop firewalld && systemctl disable firewalld
yum -y install iptables-services && systemctl start iptables && systemctl enable iptables && iptables -F && service iptables save
4、关闭 SELINUX
关闭交换分区、环比SELINUX
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
5、调整内核参数,对于 K8S
net.bridge.bridge-nf-call-iptables=1 # 经过网桥的流量经过 iptables net.bridge.bridge-nf-call-ip6tables=1 net.ipv4.ip_forward=1 # 路由转发
cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit_memory=1 # 不检查物理内存是否够用
vm.panic_on_oom=0 # 开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
sysctl -p /etc/sysctl.d/kubernetes.conf
6、调整系统时区,搭建时间同步服务器
1、所有节点设置时区
$ timedatectl set-timezone Asia/Shanghai
2、配置时间同步服务器
# master01设置chronyd服务端1
[root@localhost ~]# vim /etc/chrony.conf
[root@localhost ~]# cat /etc/chrony.conf | egrep "^server|^allow|^local"
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst
allow 192.168.20.0/24
local stratum 10
[root@localhost ~]# systemctl enable chronyd --now
[root@localhost ~]# systemctl restart chronyd
# master02设置chronyd服务端2
[root@localhost ~]# vim /etc/chrony.conf
[root@localhost ~]# cat /etc/chrony.conf| egrep "^server|^allow|^local"
server ntp1.aliyum.com iburst
server ntp2.aliyum.com iburst
server ntp3.aliyum.com iburst
allow 192.168.20.0/24
local stratum 11
[root@localhost ~]# systemctl enable chronyd --now
[root@localhost ~]# systemctl restart chronyd
#master03配置chronyd客户端
[root@localhost ~]# vim /etc/chrony.conf
[root@localhost ~]# cat /etc/chrony.conf | grep "^server"
server 192.168.20.201 iburst
server 192.168.20.202 iburst
[root@localhost ~]# systemctl enable chronyd --now
[root@localhost ~]# systemctl restart chronyd
#node1配置chronyd客户端
[root@localhost ~]# vim /etc/chrony.conf
[root@localhost ~]# cat /etc/chrony.conf | grep "^server"
server 192.168.20.201 iburst
server 192.168.20.202 iburst
[root@localhost ~]# systemctl enable chronyd --now
[root@localhost ~]# systemctl restart chronyd
#node2配置chronyd客户端
[root@localhost ~]# vim /etc/chrony.conf
[root@localhost ~]# cat /etc/chrony.conf | grep "^server"
server 192.168.20.201 iburst
server 192.168.20.202 iburst
[root@localhost ~]# systemctl enable chronyd --now
[root@localhost ~]# systemctl restart chronyd
3、设置定时任务,确保chronyd时刻同步
(由于虚拟机中没有 bios 硬件,让时间一直运行)
[root@localhost ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@localhost ~]# crontab -l
*/5 * * * * systemctl restart chronyd
[root@localhost ~]# systemctl enable crond --now
[root@localhost ~]# systemctl restart crond
7、关闭系统不需要服务
8、设置 rsyslogd 和 systemd journald
mkdir /var/log/journal # 持久化保存日志的目录
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald
9、升级内核为4.4,设置默认启动启动
升级系统内核为 4.44
CentOS 7.x 系统自带的 3.10.x 内核存在一些 Bugs,导致运行的 Docker、Kubernetes 不稳定,例如: rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
# 安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置,如果没有,再安装一次!
yum --enablerepo=elrepo-kernel install -y kernel-lt
# 设置开机从新内核启动
grub2-set-default 'CentOS Linux (4.4.189-1.el7.elrepo.x86_64) 7 (Core)'
也可以向每一个节点中上传 kernel-lt 的rpm包:
#安装
$ yum -y install kernel-lt-4.4*
#设置4.4内核默认启动
[root@localhost ~]# cat /boot/grub2/grub.cfg |grep 4.4
[root@localhost ~]# grub2-set-default 'CentOS Linux (4.4.222-1.el7.elrepo.x86_64) 7 (Core)'
10、重启,关机做快照
3)sealos 安装
# 下载并安装 sealos, sealos 是个 golang 的二进制工具,直接下载拷贝到 bin 目录即可, release 页面也可下载
$ wget -c https://sealyun.oss-cn-beijing.aliyuncs.com/latest/sealos && \
chmod +x sealos && mv sealos /usr/bin
# 下载离线资源包
$ wget -c https://sealyun.oss-cn-beijing.aliyuncs.com/2fb10b1396f8c6674355fcc14a8cda7c-v1.20.0/kube1.20.0.tar.gz
# 安装一个三 master 的 kubernetes 集群
$ sealos init --passwd '123456' \
> --master 192.168.20.201 --master 192.168.20.202 --master 192.168.20.203 \
> --node 192.168.20.204-192.168.20.205 \
> --pkg-url /root/kube1.16.0.tar.gz \
> --version v1.16.0
其他命令
增加 Master 节点
$ sealos join --master 192.168.0.6 --master 192.168.0.7
# 或者多个连续 IP
$ sealos join --master 192.168.0.6-192.168.0.9
增加 node
$ sealos join --node 192.168.0.6 --node 192.168.0.7
# 或者多个连续 IP
$ sealos join --node 192.168.0.6-192.168.0.9
删除指定 Master 节点
$ sealos clean --master 192.168.0.6 --master 192.168.0.7
# 或者多个连续 IP
$ sealos clean --master 192.168.0.6-192.168.0.9
删除指定 node 节点
$ sealos clean --node 192.168.0.6 --node 192.168.0.7
# 或者多个连续 IP
$ sealos clean --node 192.168.0.6-192.168.0.9
清理集群
备份集群
4)节点状态
kube-scheduler 状态查看
$ kubectl get endpoints kube-scheduler -n kube-system -o yaml
NAME ENDPOINTS AGE
kube-scheduler <none> 12m
[root@k8s-master01 ~]# kubectl get endpoints kube-scheduler -n kube-system -o yaml
apiVersion: v1
kind: Endpoints
metadata:
annotations:
control-plane.alpha.kubernetes.io/leader: '{"holderIdentity":"k8s-master03_83054470-8074-4200-9523-6ba7d99a23b3","leaseDurationSeconds":15,"acquireTime":"2023-02-11T00:41:01Z","renewTime":"2023-02-11T00:41:51Z","leaderTransitions":1}'
creationTimestamp: "2023-02-11T00:40:05Z"
name: kube-scheduler
namespace: kube-system
resourceVersion: "871"
selfLink: /api/v1/namespaces/kube-system/endpoints/kube-scheduler
uid: d43ca787-7095-47db-bdfa-1e12fcc85e19
kube-controller-manager 状态查看
[root@k8s-master01 ~]# kubectl get endpoints kube-controller-manager -n kube-system -o yaml
apiVersion: v1
kind: Endpoints
metadata:
annotations:
control-plane.alpha.kubernetes.io/leader: '{"holderIdentity":"k8s-master03_db536083-f166-4145-952b-fd966fa227dc","leaseDurationSeconds":15,"acquireTime":"2023-02-11T00:40:59Z","renewTime":"2023-02-11T00:42:00Z","leaderTransitions":1}'
creationTimestamp: "2023-02-11T00:40:04Z"
name: kube-controller-manager
namespace: kube-system
resourceVersion: "885"
selfLink: /api/v1/namespaces/kube-system/endpoints/kube-controller-manager
uid: 18c26b9e-54ea-4c90-8a05-b159451ea4ae
所有子版本的发型包
https://pan.baidu.com/s/1fu_l8yL_K6BLpSIugKhvAg?pwd=47f5
5)保存初始化配置文件
[root@k8s-master01 ~]# mkdir -p /usr/local/kubernetes/install
[root@k8s-master01 ~]# cp -a kubeadm-config.yaml /usr/local/kubernetes/install
三、测试高可用
通过查看节点状态,发现 Schedule 、Controller Manager 都在 master03 节点运行
1)将master03强制关机
2)测试运行
创建控制器、service
$ kubectl create deployment myapp --image=wangyanglinux/myapp:v1
$ kubectl scale deployment myapp --replicas=10
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-5f6676bbd6-22xbq 1/1 Running 0 63s 100.97.125.4 k8s-node01 <none> <none>
myapp-5f6676bbd6-2k7gs 1/1 Running 0 63s 100.125.152.2 k8s-node02 <none> <none>
myapp-5f6676bbd6-5hqfm 1/1 Running 0 88s 100.125.152.1 k8s-node02 <none> <none>
myapp-5f6676bbd6-j2tkd 1/1 Running 0 63s 100.125.152.3 k8s-node02 <none> <none>
myapp-5f6676bbd6-jxrfj 1/1 Running 0 63s 100.125.152.5 k8s-node02 <none> <none>
myapp-5f6676bbd6-l2pzt 1/1 Running 0 63s 100.125.152.4 k8s-node02 <none> <none>
myapp-5f6676bbd6-pcfxv 1/1 Running 0 63s 100.97.125.1 k8s-node01 <none> <none>
myapp-5f6676bbd6-r9dlw 1/1 Running 0 63s 100.97.125.5 k8s-node01 <none> <none>
myapp-5f6676bbd6-w7lzk 1/1 Running 0 63s 100.97.125.3 k8s-node01 <none> <none>
myapp-5f6676bbd6-xj5xd 1/1 Running 0 63s 100.97.125.2 k8s-node01 <none> <none>
$ kubectl create svc nodeport myapp --tcp=80:80
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24m
myapp NodePort 10.96.247.207 <none> 80:32466/TCP 4s
访问master01,master02
3)修复
将master03开机,集群中会自动修复







