本文介绍构建高可用Kubernetes集群的推荐配置。
类型 | 说明 | 高可靠配置建议 |
---|---|---|
集群控制节点 | 云容器引擎专有版有控制节点,可参考如下建议提升集群整体稳定性和可靠性。 | 集群Master节点多可用区 、集群网络选择服务转发模式、关注配额限制、监控控制节点指标 |
集群工作节点 | 一般业务应用容器运行在Kubernetes集群工作节点,可参考如下建议实现控制节点的可扩展性及可修复性,及时关注核心组件的运行状态。 | 运行npd 配置DNS缓存、合理部署CoreDNS |
应用层面 | 为确保业务应用在流量高峰期不间断正常提供服务,可参考如下建议部署和配置应用,使应用具备弹性,并及时关注应用运行状态提前发现潜在问题。 | 运行多个实例 设置资源配额、应用多可用区部署、自动弹性伸缩、日志监控告警 |
集群Master节点多可用区
天翼云每个区域(Region)下有不同的可用区(Availability Zone,AZ)。可用区由一个或多个数据中心组成,具备独立的风火水电。区域的多个AZ间通过高速光纤相连,用户可基于此构建跨AZ高可用系统。
创建集群时,部署模式选择多可用区部署,选择控制节点数为3或以上。多可用区部署模式下,控制节点会尽量分布在不同可用区以增强容灾能力 。
集群网络选择
云容器引擎支持calico IPIP隧道网络和cubecni VPC网络。不同网络插件存在性能和功能差异,请根据业务需求合理选择,详见集群网络概述。
- VPC选择:由于VPC间相互隔离,如果容器应用需访问RDS数据库等云服务实例,建议把这些云服务实例创建在同一VPC。对于已创建好处于不同VPC的云服务实例,可以通过对等连接配置两VPC互通。
- 容器网段选择:容器网络网段大小直接影响可创建的节点和Pod数,所以不能设置太小。使用calico IPIP隧道网络的集群,如果容器网段掩码是/16,这有256*256个地址,默认情况下每个节点从容器网段一次分配的IP网段为24,此时可创建节点数为256。使用cubecni VPC网络的集群,容器网段为VPC子网,容器网段被节点共享,每个节点会预申请10个子网IP。容器网段大小与节点数无直接关系,但影响可创建Pod数。若子网掩码是/19,则有8192个子网地址供Pod使用。
- 服务网段选择:服务网段决定集群中Service数上限,请根据实际需求配置Service网段。由于Service网段创建后无法修改,请勿设置过小的Service网段。
详见集群网络地址段规划实践。
服务转发模式
Kubernetes集群的kube-proxy组件,负责Service与后端Pod间的负载均衡转发,该组件有两种服务转发模式:
- iptables:适用于Service数量较少或客户端会出现大量并发短连接场景。当Service数超过1000时,iptables模式可能引入部分网络延迟;
- IPVS:相比iptables模式,其吞吐更高速度更快,适用于集群规模较大或Service数较多的场景。
关注配额限制
云服务和集群资源均有配额限制,以防止意外过度使用资源。
云服务配额:如弹性云服务器、云硬盘、虚拟私有云、弹性负载均衡、容器镜像服务等均有配额限制,当资源配额限制无法满足使用时,可以提交工单申请扩大配额;
集群配额:租户可创建集群数量、单集群管理节点数量、单节点最大Pod数有配额限制,详见使用限制。
监控控制节点指标
采集控制节点指标可以深入了解控制节点性能并提前识别问题,运行状况不佳的控制节点会影响应用可靠性。
云容器引擎通过ccse-monitor插件对接应用性能监控服务APM,以采集集群指标,默认会采集kube-apiserver、kube-controller、kube-scheduler、etcd等核心组件指标。
可在云容器引擎控制台的“运维管理-监控”侧查看这些系统组件的监控面板。
运行npd
工作节点故障可能影响容器应用的正常运行。npd(node problem detector)是Kubernetes社区提供的用于检测集群节点异常的插件,借助npd可及时获取节点可能存在的异常并处理。npd插件支持自定义配置,如目标节点、触发阈值、检查周期等。
配置DNS缓存
CoreDNS默认不缓存DNS,当集群内DNS请求量增加时,CoreDNS可能出现如下问题:
- 延迟增加:CoreDNS要处理更多请求,DNS查询可能变慢,从而影响业务性能;
- 资源占用率增加:CoreDNS需要占用更多CPU和内存,以满足激增的DNS请求。
可在集群中部署NodeLocal DNSCache插件以减少DNS请求延迟,提升服务发现的稳定性和性能。该插件在每个集群节点上运行DNS缓存代理,所有注入DNS配置的Pod优先使用该DNS缓存代理进行域名解析,以减少CoreDNS服务的压力,提高集群DNS性能。
合理部署CoreDNS
建议将集群的CoreDNS实例分布在不同可用区、不同节点上,避免单节点、单可用区故障。CoreDNS所在节点应避免CPU、内存高压力,否则会影响域名解析的QPS和响应延迟。
运行多个实例
若应用程序使用单个Pod承载,如果该Pod出现异常,则直接导致应用程序不可用。
建议使用Deployment等工作负载来部署应用,对于Deployment类型的工作负载,当Pod被删除时,deployment控制器会自动新建一个相同配置的Pod,以确保指定数量的Pod始终运行。
在创建Deployment类型工作负载时,建议指定实例数不小于2。如果一个实例发生故障,剩余的实例仍继续运行,若故障实例被删除,Kubernetes会自动创建另一个Pod。
可以使用容器水平伸缩(HPA)结合节点自动伸缩根据工作负载需求自动进行伸缩。
使用容器隔离进程
容器可提供一定程度的隔离,每个容器有单独的根文件系统、网络栈和CPU/内存等资源限制,可一定程度避免不同容器进程间相互干扰及恶意进程攻击和数据泄露,提高应用程序的可靠性、安全性和可移植性。
可在同一个Pod内创建多个容器,以便这些容器进程需协同工作。Pod内容器可以共享相同的网络栈、存储卷、IPC等资源。
Pod的init容器在非init容器启动前运行,常用于完成一些初始化任务,比如配置环境变量、准备数据存储等等。
Pod内多个容器共享同个Pod的生命周期,例如其中一个容器无法启动,则导致整个Pod无法进入Running状态。
设置资源配额
建议为所有工作负载配置资源请求/限制,资源请求影响Kubernetes调度,资源请求和限制则声明Pod的QoS。
若资源请求/限制没有配置或配置不合理,则可能导致某个节点上调度了过多Pod或调度了较多消耗资源过多的Pod,使得节点负载太高,甚至产生节点OOM等异常,无法对外提供服务。
为避免这类问题,建议为每个Pod均配置资源请求(Request)及限制(Limit)。Kubernetes在部署Pod时,会结合Pod的资源请求和限制找一个具有充足空闲资源的节点部署。
Kubernetes采用静态资源调度方式,对于节点剩余资源的计算方式如下:
节点剩余资源=节点总资源-已经分配出去的资源
- 节点剩余资源并不是实际可使用的资源,若手动运行一个很耗资源的程序,Kubernetes并不能感知到。
- 对于没有声明resources的Pod,当该Pod被调度到某个节点后,Kubernetes并不会在对应节点上扣掉该Pod使用的资源,这可能导致节点上调度太多Pod,所以建议为所有Pod配置resources。
应用多可用区部署
建议在多个不同可用区的节点上运行Pod,避免应用受到单可用区故障影响。
订购集群时,部署模式选择多可用区部署:
部署应用时,可为Pod设置反亲和性规则,实现跨多个可用区多个节点调度Pod,详情请参见应用高可用部署。
设置容器健康检查
Pod内容器若异常退出,Kubernetes会自动重启容器,能避免部分Pod容器异常导致的服务中断。但Pod处于Running状态并不代表Pod能正常提供服务,例如Pod内进程可能访问RDB实例失败且没退出,此时Pod状态依然是Running。建议为Pod配置存活探针(Liveness Probe),探测Pod是否存活。如果存活探针失败超过阈值,Kubernetes会重启Pod。
- 就绪探针(Readiness Probe)用于探测Pod是否可以正常对外提供服务。应用一般在启动过程中需要做一些初始化动作才能对外提供服务,为Pod添加过就绪探针后,当就绪探针检测成功时该Pod才会加入Service。当Pod的就绪探针失败时,Pod会从对应Service移除,避免Service流量继续转到异常Pod。
- 启动探针(Startup Probe)用于探测应用容器是否启动成功。若配置了启动探针,启动探针成功后,Kubernetes才会进行存活探针和就绪探针检查。建议对于启动慢的容器配置启动探针,避免这类Pod在启动运行之前因存活探针失败就被终止。
工作负载配置探针的YAML示例如下:
apiVersion: v1
kind: Pod
metadata:
labels:
app: probe-demo
name: probe-demo
spec:
containers:
- name: probe-demo
image: nginx:alpine
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: 80
failureThreshold: 3
periodSeconds: 10
自动弹性伸缩
云容器引擎的自动弹性伸缩功能提供自动调整工作负载实例数和集群节点数的能力,实现在业务高峰时快速扩容,在低谷时进行缩容,以节约资源与成本。
可配置如下两类弹性伸缩:
- 工作负载伸缩:调整容器的资源申请/限制值可实现工作负载纵向伸缩,但这种调整会使得关联Pod均重建,且存在瓶颈,例如节点剩余可用资源。对于无状态应用,可通过调整Deployment的实例数实现水平伸缩,分摊每个应用实例的压力,详见容器水平伸缩。
- 节点伸缩:随着Pod数不断增加,节点剩余资源会成为瓶颈,导致无法继续启动新建的Pod。为解决节点资源不足问题,可以基于节点资源使用率伸缩节点数,详见节点自动伸缩。