Kubernetes的最佳实践

Kubernetes 作为最流行的容器编排系统已经成为大部分运维需要掌握的一项基本技能。而很好的掌握它应该做什么和不应该做什么,将是一个很好的开局。

程序开发

使用命名空间

使用不同的命名空间,以限制组的访问控制以及可能发生任何错误的爆炸半径。
还可以针对命名空间配置limitRange对象,以定义命名空间中容器的标准大小。ResourceQuotas可以限制命名空间内所有容器的总资源消耗。

使用就绪和存活探针

就绪和存活两种探针本质上都是健康检查的类型。
当就绪探针确保当pod准备好为请求提供服务时,才会将Pod的请求定向到它。
存活探针将应用程序是否正在允许将其作为是否健康的标志。

使用自动伸缩

在适当的情况下,可以使用自动伸缩来动态调整Pod的数量(Pod水平伸缩,HPA)、(Pod垂直伸缩,VPA)或集群的节点数量(集群自动伸缩,CA),具体取决于对资源的需求。

使用伸缩时也会带来一些挑战,比如持久化数据。

使用资源请求和约束

设置资源请求和约束可以避免容器在未分配所需资源的情况下启动,或集群用尽可用资源。如没有限制,Pod可以使用比所需要的更多的资源,从而导致可用资源总量减少。

使用deployment、DaemonSet、RelicaSet或SattefulSet跨节点部署Pod

永远不应该直接运行Pod。为了提高容错性,Pod应该始终作为Deployment、DaemonSet、ReplicaSet或SatefulSet的一部分。然后可以部署中使用反亲和性规则跨节点部署Pod,避免所有Pod调度到同一个节点上运行。

集群治理

使用多节点

如果提升可靠性,在单个节点上运行k8s不是一个好主意。集群中应该使用多个节点,一遍可以在他们之间分散工作负载。

使用RBAC

RABC可以为用户、组合service account分配权限,以在特定命名空间或整个集群执行被运行的操作。
主意分配权限应仅授予所需的权限。

使用云服务

将k8s托管在云上会更轻松。

升级版本

新版本会更安全些,还会引入新功能。

监控集群资源和审计策略日志

针对APIServer的日志进行分析和监控。

使用版本控制

对编排文件进行版本控制,对更改进行审计跟踪,有助于提高集群的稳定性。

使用精简镜像

较小的镜像有助于加速构建和部署速度,减少容器在集群上消耗的资源量。

集群配置

用标签治理对象

在云环境中对资源使用标签,以跟踪与业务相关的事务。

使用网络策略

使用网络策略限制集群中对象之间的流量。

使用防火墙

限制外部对APIServer的请求。

弹性伸缩

在kubernetes中,常见的“自动伸缩”有:

  • HPA:Pod水平伸缩
  • VPA:Pod垂直伸缩
  • CA:集群自动伸缩

不同类型的自动伸缩器,应用的场景不同。

HPA,HPA 定期检查内存和CPU等指标,自动跳转Deployment中副本数量。
VPA,无法通过调整Pod数量来扩容是,可以通过VPA增加Pod资源的大小,比如调整CPU和内存。
CA。当集群资源不足时,CA会自动配置新的计算资源并添加到集群中。

HPA

HPA 可以基于CPU使用率来自动伸缩Pod的数量,还可以基于其他指标,比如:

  • Resource metrics CPU、内存使用率
  • Pod metrics 网络利用率和流量
  • Object metrics 特定对象的指标,比如Ingress,可以按每秒使用请求数来扩展容器
  • Custom metrics 自定义监控,比如定义服务响应时间

工作原理:定时检测每个Pod指标的平均值,并检测删除或添加副本,是否会使该值更接近目标

最佳实践

  • 为HPA提供每个pod的资源指标,metrics-server;
  • 为每个容器配置指标阈值,HPA根据指标的阈值来做出伸缩的决策;
  • 使用自定义指标,确保使用正确的目标类型

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: hpa
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
requests:
cpu: 200m
memory: 100Mi
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: hpa
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
app: nginx

创建一个HPA用来控制上述步骤中的Deployment,是Pod副本数量维持在1~10。HPA通过改变Pod副本的数量以保持所有Pod的平均CPU使用率在50%以内。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: nginx
namespace: hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50

VPA

VPA,即使垂直Pod自动伸缩,是根据容器资源使用率自动设置CPU和内存的requests,从而允许在节点上进行适当的调度。既可以缩小过度请求资源的容器,也可以根据使用情况提升资源不足的容量。

组件:

  • Recommender 监控资源利用率并计算目标值,并推荐一个理想的资源请求值
  • Updater 检查Pod资源限制是否需要更新
  • Admission Controller 在创建Pod时覆盖其资源请求

最佳实践

  1. 避免在Kubernetes的1.11版本之前使用
  2. 使用updateMode:OFF运行VPA,以及了解要自动伸缩的Pod的资源使用情况,为以后调整做基础
  3. 如果工作负载经常出现高使用率和低使用率的峰值,则VPA过于激进,使用HPA效果会更好

示例

注意使用VPA需要先部署 autoscaler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: vpa
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
requests:
cpu: 100m
memory: 250Mi
1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: vpa
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
app: nginx

创建VPA:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: autoscaling.k8s.io/v1beta2
kind: VerticalPodAutoscaler
metadata:
name: nginx-vpa
namespace: vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: nginx
updatePolicy:
updateMode: "Off"
resourcePolicy:
containerPolicies:
- containerName: "nginx"
minAllowed:
cpu: "250m"
memory: "100Mi"
maxAllowed:
cpu: "2000m"
memory: "2048Mi"

注意updateMode设置为Auto的时候才会自动调整。使用限制:

  • 不能和HPA共存
  • Pod使用副本控制器,比如Deployment或StatefulSet

优势:

  • Pod资源用其所需,所以集群节点使用效率高
  • Pod会被安排到具有适当资源的节点上
  • 不必运行基准测试任务来确定CPU和内存的请求和食指
  • VPA可以随时调整资源设置,无需手动操作

CA

CA是基于Pod来扩展集群节点,会定期检查是否有不可调度的的的Pod,如需更多资源,并且扩展的集群仍然在用户提供的约束范围内,则会调整集群的大小。

影响的因素:

  1. HPA的响应耗时
  2. CA的响应耗时
  3. 节点的初始化耗时
  4. Pod创建耗时

默认情况下,kubelet每10秒抓取一下Pod的CPU和内存使用情况;
每分钟,Metrices Server将聚合的指标开放给API Server及其他组件使用;
CA 每10秒排查不可调度的Pod。<100个节点,每个节点最大30个Pod,平均延迟在5s。100到1000个节点时,平均延迟在15s左右;
节点的配置时间,通常在3~5分钟;
容器创建Pod,在几秒到1分钟不等。

因此对于小的集群,最差的情况可能在6分钟左右,大的集群则可能在7分钟以上。因此,压缩时间的方式:

1
2
3
4
5
6
7
HPA 的刷新时间,默认 15 秒,通过 --horizontal-pod-autoscaler-sync-period 标志控制;

Metrics Server 的指标抓取时间,默认 60 秒,通过 metric-resolution 控

CA 的扫描间隔,默认 10 秒,通过 scan-interval 控制;

节点上缓存镜像,比如 kube-fledged等工具;

总之,尽量避免被动创建新节点,主动创建新节点。

最佳实践

  1. 选择和Kubernetes匹配的版本
  2. 检查集群节点是否有相同的CPU和内存,否则无法正常工作,因为它假设每个节点都有相同的资源
  3. 确保自动伸缩的Pod都有指定的资源请求
------ 本文结束 ------

版权声明

Medivh's Notes by Medivh is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Medivh创作并维护的Medivh's Notes博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
本文首发于Medivh 博客( http://www.mknight.cn ),版权所有,侵权必究。