行业知识
云原生学习
1. 高可用架构
1.1 架构图
Kubernetes是属于主从设备模型(Master-Slave架构),即有Master节点负责核心的调度、管理和运维,Slave节点则执行用户的程序。在Kubernetes中,主节点一般被称为Master Node 或者 Head Node,而从节点则被称为Worker Node 或者 Node。
Tips:Master节点通常包括API Server、Scheduler、Controller Manager等组件,Node节点通常包括Kubelet、Kube-Proxy等组件!
看到蓝色框内的Control Plane,这个是整个集群的控制平面,相当于是master进程的加强版。k8s中的Control Plane一般都会运行在Master节点上面。在默认情况下,Master节点并不会运行应用工作负载,所有的应用工作负载都交由Node节点负责。
控制平面中的Master节点主要运行控制平面的各种组件,它们主要的作用就是维持整个k8s集群的正常工作、存储集群的相关信息,同时为集群提供故障转移、负载均衡、任务调度和高可用等功能。对于Master节点一般有多个用于保证高可用,而控制平面中的各个组件均以容器的Pod形式运行在Master节点中,大部分的组件需要在每个Master节点上都运行,少数如DNS服务等组件则只需要保证足够数量的高可用即可。
1.1.1 etcd
ETCD:它是兼具一致性和高可用性的键值key-value数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库,负责保存Kubernetes Cluster的配置信息和各种资源的状态信息,当数据发生变化时,etcd 会快速地通知Kubernetes相关组件。
Kubernetes 集群的 etcd 数据库通常需要有个备份计划。此外还有一种k8s集群部署的高可用方案是将etcd数据库从容器中抽离出来,单独作为一个高可用数据库部署,从而为k8s提供稳定可靠的高可用数据库存储。
Tips:生成环境如果机器配置够高,安装etcd与master安装在一起也OK,也可以单独分离。
1.1.2 kube-apiserver
k8s集群的控制平面的核心是API服务器,而API服务器主要就是由kube-apiserver组件实现的,它被设计为可水平扩展,即通过部署不同数量的实例来进行缩放从而适应不同的流量。API服务器作为整个k8s控制平面的前端,负责提供 HTTP API,以供用户、集群中的不同部分组件和集群外部组件相互通信。(可以通过kubeadm或者kubectl这类的CLI工具来操控API从而控制整个k8s集群,也可以通过其他的Web UI来进行操控)
Tips:工具在背后也是调用 API,包括Web操作。
1.1.3 kube-scheduler
主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。
1.1.4 kube-controller-manager
K8S所有Worker Node的监控器。Controller Manager作为集群内部的管理控制中心,运行在Master节点上,是一个永不休止的循环。它实质上是群内的Node、Pod、服务(Server)、端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的监视与守护进程的合集,每个资源的Controller通过API Server提供的接口实时监控每个资源对象的当前状态,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。
其中控制器包括:
- 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应。
- 副本控制器(Replication Controller): 负责为系统中的每个副本控制器对象维护正确数量的 Pod。
- 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)。
- 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌。
1.1.5 kubelet
K8S中Master节点在每个Worker Node节点上运行的主要“节点代理”,也可以说是Master 的“眼线”。它会定期向Master Node汇报自己Node上运行服务的状态,并接受来自Master Node的指示采取调整措施。负责控制由 K8S 创建的容器的启动停止,保证节点工作正常。
1.1.6 kube-proxy
kube-proxy是集群中每个节点上运行的网络代理,负责Node在K8S的网络通讯、以及对外网络流量的负载均衡。 kube-proxy通过维护主机上的网络规则并执行连接转发,实现了Kubernetes服务抽象。
service在逻辑上代表了后端的多个Pod,外界通过service访问Pod。service接收到的请求就是通过kube-proxy转发到Pod上的,kube-proxy服务负责将访问service的TCP/UDP数据流转发到后端的容器。如果有多个副本,kube-proxy会实现负载均衡。
由于性能问题,目前大部分企业用K8S进行实际生产时,都不会直接使用Kube-proxy作为服务代理,而是通过Ingress Controller来集成HAProxy, Nginx来代替Kube-proxy。
1.2 高可用分析
所有从集群(或所运行的 Pods)发出的 API 调用都终止于 API server,而API Server直接与ETCD数据库通讯。若仅部署单一的API server ,当API server所在的 VM 关机或者 API 服务器崩溃将导致不能停止、更新或者启动新的 Pod、服务或副本控制器;而ETCD存储若发生丢失,API 服务器将不能启动。
所以如下几个方面需要做到:
- 集群状态维持:K8S集群状态信息存储在ETCD集群中,该集群非常可靠,且可以分布在多个节点上。需要注意的是,在ETCD群集中至少应该有3个节点,且为了防止2网络分裂,节点的数量必须为奇数。
- API服务器冗余灾备:K8S的API server服务器是无状态的,从ETCD集群中能获取所有必要的数据。这意味着K8S集群中可以轻松地运行多个API服务器,而无需要进行协调,因此我们可以把负载均衡器(LB)放在这些服务器之前,使其对用户、Worker Node均透明。
- Master选举:一些主组件(Scheduler和Controller Manager)不能同时具有多个实例,可以想象多个Scheduler同时进行节点调度会导致多大的混乱。由于Controller Manager等组件通常扮演着一个守护进程的角色,当它自己失败时,K8S将没有更多的手段重新启动它自己,因此必须准备已经启动的组件随时准备取代它。高度可扩展的Kubernetes集群可以让这些组件在领导者选举模式下运行。这意味着虽然多个实例在运行,但是每次只有一个实例是活动的,如果它失败,则另一个实例被选为领导者并代替它。
- K8S高可用:只要K8S集群关键结点均高可用,则部署在K8S集群中的Pod、Service的高可用性就可以由K8S自行保证。
负载均衡节点设计
负载均衡节点承担着Worker Node集群和Master集群通讯的职责,同时Load Balance没有部署在K8S集群中,不受Controller Manager的监控,倘若Load Balance发生故障,将导致Node与Master的通讯全部中断,因此需要对负载均衡做高可用配置。Load Balance同样不能同时有多个实例在服务,因此使用Keepalived对部署了Load Balance的服务器进行监控,当发生失败时将虚拟IP(VIP)飘移至备份节点,确保集群继续可用。
2. 前期规划及准备
2.1 高可用Kubernetes集群规划
主机规划
主机名
IP地址
说明
k8s-master01 ~ 03
10.0.0.104 ~ 106
master节点 * 3
k8s-master-lb
10.0.0.236
keepalived虚拟IP(不占用机器)
k8s-node01 ~ 02
10.0.0.107 ~ 108
worker节点 * 2
网络规划及版本说明
配置信息
备注
系统版本
CentOS 7.9
Docker版本 (containerd)
20.10.x
Pod网段
172.16.0.0/16
Service网段
192.168.0.0/16
Tips:宿主机网段、K8s Service网段、Pod网段不能重复!
本方案负载均衡(VIP)在Master上,没有单独做负载均衡双机热备。
IP
角色
Hostname
说明
10.0.0.104
Master
k8s-master01
keepalived、haproxy、kube-apiserver、kube-scheduler、kube-controller-manager
10.0.0.105
Master
k8s-master02
keepalived、haproxy、kube-apiserver、kube-scheduler、kube-controller-manager
10.0.0.106
Master
k8s-master03
keepalived、haproxy、kube-apiserver、kube-scheduler、kube-controller-manager
10.0.0.107
Node
k8s-node01
kubelet、kube-proxy
10.0.0.108
Node
k8s-node02
kubelet、kube-proxy
10.0.0.236
Virtual IP(VIP)
k8s-master-lb
各主机hosts解析需要对应加上这一条10.0.0.36 k8s-master-lb
2.2 基本环境配置
centos通过单独安装,非克隆。安装完后进行基本环境的配置,配置一下几个方面:
- 设置主机名
- 关闭NetworkManager、firewalld、dnsmasq、selinux
- 设置eth0
- 优化ssh
- 设置时区为Asia/Shanghai
- 备份并新增清华yum源、epel源、docker-ce源、k8s源
- 更新yum源软件包缓存
- 修改history格式及记录数
- 添加hosts解析
- 关闭swap分区
- 安装ntpdate服务,并同步时间
- 配置limits.conf
- 安装必备工具
- 升级系统并重启
在/root目录下创建k8s_system_init.sh,复制以下内容。然后sh /root/k8s_system_init.sh进行基本环境的配置。
此步骤Master及Node节点都需进行!
#!/bin/bashif [ $# -eq 2 ];then echo "设置主机名为:" echo "eth0设置IP地址为:10.0.0."else echo "使用方法:sh 主机名 主机位" exit 2fiecho "--------------------------------------"echo "1.正在设置主机名:"hostnamectl set-hostname echo "2.正在关闭NetworkManager、firewalld、dnsmasq、selinux"systemctl disable firewalld &> /dev/nullsystemctl disable NetworkManager &> /dev/nullsystemctl disable dnsmasq &> /dev/nullsystemctl stop firewalldsystemctl stop NetworkManagersystemctl stop dnsmasqsed -i "s#SELINUX=enforcing#SELINUX=disabled#g" /etc/selinux/configsetenforce 0echo "3.正在设置eth0:10.0.0."cat > /etc/sysconfig/network-scripts/ifcfg-eth0 /dev/nullsystemctl start ntpdateecho "*/10 * * * * root /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1" > /etc/cron.d/ntp_syncecho "12.配置limits.conf"ulimit -SHn 65535cat >> /etc/security/limits.conf /dev/nullecho "6.配置ipvs模块"modprobe -- ip_vsmodprobe -- ip_vs_rrmodprobe -- ip_vs_wrrmodprobe -- ip_vs_shmodprobe -- nf_conntrackcat >> /etc/modules-load.d/ipvs.conf