如何做k8s资源的规划 #
在K8s中进行资源规划是一个重要的任务,我来详细解释一下关键点:
1. CPU和内存资源规划 #
1.1 资源请求(requests)和限制(limits) #
spec:
containers:
- name: app
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
- requests: 容器需要的最小资源量
- limits: 容器能够使用的最大资源量
- CPU单位:1 CPU = 1000m(毫核)
- 内存单位:Mi(兆字节), Gi(吉字节)
2. 命名空间资源配额 #
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: your-namespace
spec:
hard:
requests.cpu: "4"
requests.memory: 4Gi
limits.cpu: "8"
limits.memory: 8Gi
pods: "10"
3. 资源规划的最佳实践 #
监控历史数据
- 使用Prometheus + Grafana监控应用实际资源使用情况
- 观察峰值和平均值
- 留出30-50%的buffer以应对突发流量
合理设置requests和limits
- requests设置为应用正常运行需要的资源量
- limits设置为预期峰值的1.5-2倍
- 避免limits设置过低导致OOM
Pod水平自动扩缩容(HPA)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: your-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
4. 节点资源规划 #
- 节点标签和污点
kubectl label nodes node1 workload-type=cpu-intensive
kubectl taint nodes node1 dedicated=cpu-intensive:NoSchedule
- 节点亲和性
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: workload-type
operator: In
values:
- cpu-intensive
5. 资源规划检查清单 #
- 应用层面
- 确定应用的基准资源需求
- 设置合适的requests和limits
- 配置HPA策略
- 集群层面
- 设置namespace资源配额
- 规划节点池和节点规格
- 配置节点亲和性策略
- 监控和优化
- 部署监控系统
- 定期检查资源使用情况
- 根据实际情况调整资源配置
6. 注意事项 #
避免资源过度分配
- 合理评估应用资源需求
- 定期清理未使用的资源
考虑成本优化
- 使用spot实例降低成本
- 配置集群自动扩缩容
- 优化资源利用率
确保高可用
- 合理设置Pod反亲和性
- 跨可用区部署
- 预留足够的资源buffer
通过以上方法进行资源规划,可以确保应用在K8s集群中稳定运行,同时实现资源的最优利用。记住要定期检查和调整资源配置,以适应业务的变化和增长。
k8s的组件有哪些 #
1、etcd 保存了整个集群的状态;
2、apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
3、controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
4、scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
5、kubelet 负责维护容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
6、Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI);
7、kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡。
让我详细介绍K8s的核心组件:
1. 控制平面组件(Master节点) #
- API Server
- 集群的统一入口
- 提供REST API接口
- 负责组件间的通信
- 认证和授权
# API Server配置示例
apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
spec:
containers:
- name: kube-apiserver
image: k8s.gcr.io/kube-apiserver:v1.24.0
command:
- kube-apiserver
- --advertise-address=192.168.1.10
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- etcd
- 分布式键值存储
- 保存集群所有数据
- 高可用配置
# etcd配置示例
spec:
containers:
- name: etcd
image: k8s.gcr.io/etcd:3.5.1
command:
- etcd
- --advertise-client-urls=https://192.168.1.10:2379
- --data-dir=/var/lib/etcd
- Controller Manager
- 维护集群状态
- 故障检测和自动恢复
- 包含多个控制器:
- Node Controller
- Replication Controller
- Endpoints Controller
- Service Account & Token Controller
- Scheduler
- 负责Pod调度
- 根据调度算法选择节点
- 考虑资源需求、亲和性等
2. 工作节点组件(Node节点) #
- Kubelet
- 节点代理
- 管理容器生命周期
- 执行Pod规范
# Kubelet配置示例
kubelet:
config:
kind: KubeletConfiguration
address: "0.0.0.0"
port: 10250
healthzPort: 10248
- Kube-proxy
- 网络代理
- 维护网络规则
- 实现Service概念
# Kube-proxy配置示例
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs" # 或者 "iptables"
- Container Runtime
- 容器运行时
- 如Docker、containerd
- 负责容器的实际运行
3. 附加组件 #
- CoreDNS
- 集群DNS服务
- 服务发现
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
spec:
selector:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
- Dashboard
- Web UI界面
- 集群管理和监控
- CNI网络插件
- 如Calico、Flannel
- 提供网络方案
# Calico配置示例
kind: DaemonSet
metadata:
name: calico-node
namespace: kube-system
4. 组件间通信 #
graph TD
A[API Server] --> B[etcd]
C[Controller Manager] --> A
D[Scheduler] --> A
E[Kubelet] --> A
F[Kube-proxy] --> A
5. 高可用配置建议 #
- 控制平面
- 至少3个master节点
- 使用负载均衡器
- etcd集群部署
- 工作节点
- 根据业务规模扩展
- 跨可用区部署
- 定期维护和更新
6. 监控要点 #
- 核心指标
- 组件健康状态
- API Server延迟
- etcd性能
- 调度器成功率
- 告警配置
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: k8s-components-alerts
spec:
groups:
- name: k8s-components
rules:
- alert: APIServerDown
expr: up{job="apiserver"} == 0
这些组件共同工作,确保了Kubernetes集群的正常运行。了解每个组件的功能和配置对于运维和故障排查非常重要。
scheduler和controller-manager的区别 #
让我详细解释Scheduler和Controller Manager的区别:
1. 基本职责 #
Scheduler:
- 负责Pod的调度决策
- 为Pod选择最合适的Node节点
- 不负责Pod的实际创建过程
Controller Manager:
- 负责维护集群状态
- 处理各类资源的控制循环
- 确保实际状态向期望状态迁移
2. 主要功能对比 #
- Scheduler功能:
# scheduler配置示例
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
score:
disabled:
- name: NodeResourcesLeastAllocated
enabled:
- name: NodeResourcesMostAllocated
- Controller Manager功能:
# 包含多个控制器
- Deployment Controller
- ReplicaSet Controller
- StatefulSet Controller
- Node Controller
- Service Controller
- Endpoints Controller
- Namespace Controller
3. 工作流程 #
Scheduler:
- 监听API Server中未被调度的Pod
- 根据调度算法为Pod选择节点
- 将调度结果更新到API Server
Controller Manager:
- 监听API Server中资源变化
- 对比实际状态和期望状态
- 执行必要的操作使集群达到期望状态
4. 实际应用示例 #
- Scheduler处理Pod调度:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
# Scheduler会根据以下条件选择节点
nodeSelector:
disk: ssd
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
- Controller Manager处理Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # Controller确保运行3个副本
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
5. 主要区别总结 #
职责范围:
- Scheduler: 仅负责Pod调度
- Controller Manager: 负责整个集群状态维护
工作方式:
- Scheduler: 一次性决策(为Pod选择节点)
- Controller Manager: 持续循环(reconcile循环)
关注点:
- Scheduler: 资源分配和约束条件
- Controller Manager: 状态维护和自动修复
操作对象:
- Scheduler: 主要处理Pod
- Controller Manager: 处理所有Kubernetes资源
6. 使用建议 #
Scheduler相关:
- 合理配置资源请求和限制
- 使用节点亲和性和反亲和性
- 配置合适的调度策略
Controller Manager相关:
- 正确设置资源的期望状态
- 监控控制器的运行状态
- 了解不同控制器的作用
通过理解这些区别,可以更好地:
规划应用部署策略
解决调度问题
处理集群状态异常
优化资源使用效率
ingress和service的区别 #
让我详细解释Ingress和Service的区别:
1. 基本定义 #
Service:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
type: ClusterIP # 或 NodePort, LoadBalancer
Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
2. 主要区别 #
功能定位
- Service: 提供集群内部的服务发现和负载均衡
- Ingress: 提供集群外部访问的HTTP/HTTPS路由规则
协议支持
- Service: 支持任何TCP/UDP协议
- Ingress: 主要支持HTTP/HTTPS协议
访问层级
- Service: 网络层(L4)
- Ingress: 应用层(L7)
3. 常见使用场景 #
- Service使用场景:
# 内部服务访问
apiVersion: v1
kind: Service
metadata:
name: db-service
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
type: ClusterIP
- Ingress使用场景:
# 外部访问路由
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: www.myapp.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
4. 高级特性对比 #
- Service特性:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
ports:
- port: 80
- Ingress特性:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts:
- myapp.com
secretName: tls-secret
5. 最佳实践 #
- 组合使用示例:
# Service配置
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
---
# Ingress配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
spec:
rules:
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
6. 使用建议 #
何时使用Service:
- 集群内部服务访问
- 需要TCP/UDP协议支持
- 简单的负载均衡需求
何时使用Ingress:
- 需要域名访问
- 需要路径匹配
- 需要SSL/TLS终止
- 需要URL重写
- 需要应用层负载均衡
通过合理组合使用Service和Ingress,可以构建完整的服务访问体系。
打污点的命令 #
让我介绍一下打污点(Taint)的相关命令:
1. 基本命令格式 #
# 添加污点
kubectl taint nodes <node-name> <key>=<value>:<effect>
# 删除污点
kubectl taint nodes <node-name> <key>-
2. 常用污点效果(effect) #
- NoSchedule: 不允许调度
- PreferNoSchedule: 尽量不调度
- NoExecute: 不允许调度,并驱逐已有Pod
3. 常用命令示例 #
# 添加不可调度污点
kubectl taint nodes node1 key1=value1:NoSchedule
# 添加优先不调度污点
kubectl taint nodes node2 key2=value2:PreferNoSchedule
# 添加驱逐污点
kubectl taint nodes node3 key3=value3:NoExecute
# 删除指定污点
kubectl taint nodes node1 key1-
# 删除所有污点
kubectl taint nodes node1 key1- key2- key3-
4. 实际应用场景 #
# 标记专用节点(如GPU节点)
kubectl taint nodes gpu-node-1 dedicated=gpu:NoSchedule
# 标记故障节点
kubectl taint nodes problem-node-1 node-problem=true:NoExecute
# 标记master节点
kubectl taint nodes master-node node-role.kubernetes.io/master=:NoSchedule
5. 查看节点污点 #
# 查看节点详情(包含污点信息)
kubectl describe node <node-name>
# 使用自定义输出格式查看污点
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
记住:
- 添加污点后需要配合容忍度(Toleration)使用
- 谨慎使用NoExecute效果
- 操作前先确认对现有Pod的影响
daemonset和deployment的区别 #
让我详细解释DaemonSet和Deployment的主要区别:
1. 基本定义和用途 #
Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
DaemonSet:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-ds
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
containers:
- name: fluentd
image: fluentd:v1.14
2. 主要区别 #
部署策略
- Deployment: 根据replicas数量部署指定数量的Pod
- DaemonSet: 在每个节点上运行一个Pod副本
使用场景
Deployment:
- 无状态应用
- 需要指定副本数的应用
- 支持滚动更新
DaemonSet:
- 日志收集(如fluentd)
- 节点监控(如node-exporter)
- 网络插件(如calico)
扩缩容
- Deployment: 可以手动或自动调整replicas数量
- DaemonSet: 随节点数量自动增减,不支持手动扩缩容
3. 典型应用场景 #
Deployment示例(应用服务):
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.14.2
ports:
- containerPort: 80
DaemonSet示例(监控代理):
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
containers:
- name: node-exporter
image: prom/node-exporter
ports:
- containerPort: 9100
4. 更新策略 #
- Deployment更新策略:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
- DaemonSet更新策略:
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
5. 使用建议 #
选择Deployment场景:
- 常规的Web应用
- 微服务应用
- 需要负载均衡的服务
选择DaemonSet场景:
- 系统级服务
- 监控采集服务
- 日志收集服务
- 存储插件
6. 注意事项 #
Deployment:
- 注意设置合适的资源请求和限制
- 配置合理的健康检查
- 考虑配置HPA实现自动扩缩容
DaemonSet:
- 注意资源占用,因为会在每个节点运行
- 合理配置污点容忍
- 避免运行太多DaemonSet影响业务Pod
通过合理选择Deployment和DaemonSet,可以更好地满足不同的应用部署需求。
我看到您已经理解了Deployment和DaemonSet的区别。让我结合您的项目文件,给出一些具体建议:
1. 订单服务应该使用Deployment #
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
namespace: core-business
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service
image: your-registry/order-service:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1000m"
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
2. 配套的监控采集使用DaemonSet #
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: metrics-collector
namespace: monitoring
spec:
selector:
matchLabels:
app: metrics-collector
template:
metadata:
labels:
app: metrics-collector
spec:
containers:
- name: collector
image: your-registry/metrics-collector:latest
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "200m"
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
hostPath:
path: /var/log
这样的组合可以确保:
- 订单服务能够灵活扩缩容
- 监控数据能够从每个节点收集
- 符合您在quota.yaml中设置的资源限制
k8s版本用的哪个版本 #
1.23.6
scheduler调度的方式有哪些 #
让我详细介绍K8s的调度机制:
1. 调度过程 #
调度过程分为两个主要阶段:
- Predicates(预选):过滤不符合条件的节点
- Priorities(优选):对符合条件的节点进行打分
2. 常用调度方式 #
- 节点选择器(NodeSelector)
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeSelector:
disk: ssd
gpu: "true"
- 节点亲和性(Node Affinity)
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
- Pod亲和性(Pod Affinity)
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname
- 污点和容忍(Taints and Tolerations)
# 给节点添加污点
kubectl taint nodes node1 key=value:NoSchedule
# Pod配置容忍
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
3. 高级调度特性 #
- Pod优先级和抢占
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
priorityClassName: high-priority
- DaemonSet调度
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
- 自定义调度器
apiVersion: v1
kind: Pod
metadata:
name: custom-scheduler-pod
spec:
schedulerName: my-custom-scheduler
4. 资源限制调度 #
- 资源请求和限制
spec:
containers:
- name: app
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- Pod拓扑分布约束
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web
5. 最佳实践 #
- 合理使用亲和性和反亲和性
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname
- 设置默认的调度策略
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
score:
disabled:
- name: NodeResourcesLeastAllocated
enabled:
- name: NodeResourcesMostAllocated
6. 注意事项 #
- 避免过度使用硬性调度约束
- 合理设置Pod优先级
- 注意节点资源均衡
- 考虑跨可用区调度
- 定期检查调度失败的原因
通过合理使用这些调度机制,可以:
- 确保应用高可用
- 优化资源使用
- 满足特定的部署需求
- 提高集群的稳定性
我看到您已经理解了K8s的调度机制。让我结合实际场景,给出一些具体的调度策略建议:
1. 针对订单服务(OrderService)的调度策略 #
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
template:
spec:
# 优先级设置
priorityClassName: high-priority
# 亲和性设置
affinity:
# 节点亲和性 - 选择高性能节点
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- high-performance
# Pod反亲和性 - 保证高可用
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: order-service
topologyKey: kubernetes.io/hostname
# 资源请求和限制
containers:
- name: order-service
resources:
requests:
cpu: "2"
memory: "4Gi"
limits:
cpu: "4"
memory: "8Gi"
2. 配合资源配额(quota.yaml)的调度策略 #
# 为订单服务创建专属命名空间配额
apiVersion: v1
kind: ResourceQuota
metadata:
name: order-service-quota
namespace: order-service
spec:
hard:
requests.cpu: "8"
requests.memory: 16Gi
limits.cpu: "16"
limits.memory: 32Gi
pods: "5"
3. 调度策略建议 #
高可用保证
- 跨节点部署
- 跨可用区部署
- 资源预留
性能保证
- 使用专用节点池
- 合理的资源限制
- 优先级设置
弹性伸缩
- 配置HPA
- 设置合理的扩缩容阈值
- 资源预留空间
这样的配置可以确保订单服务的稳定性和性能。
集群层面的规划 根据业务规模 预估多少台机器 #
让我为您详细说明集群规模的规划方法:
1. 业务规模评估 #
业务指标评估
- 日活用户数(DAU)
- 峰值QPS
- 数据存储需求
- 计算密集型/IO密集型
单个服务资源需求
典型服务资源配置示例:
- 小型服务:
CPU: 0.5-1核
内存: 1-2Gi
- 中型服务:
CPU: 2-4核
内存: 4-8Gi
- 大型服务:
CPU: 8核+
内存: 16Gi+
2. 节点规格选择 #
- 常用节点规格
- 通用型:
4核8G, 8核16G, 16核32G
- 计算密集型:
16核32G, 32核64G
- 内存密集型:
16核64G, 32核128G
- 节点数量计算公式
所需节点数 = (服务数量 × 单服务资源 × 副本数 × (1 + 冗余系数)) / 节点规格
3. 集群规模示例 #
- 小型集群(适合初创公司)
- 业务规模:
DAU: 1-10万
服务数量: 10-20个
- 节点配置:
管理节点: 3台 4核8G
工作节点: 3-5台 8核16G
- 总资源:
CPU: 40-60核
内存: 80-120G
- 中型集群(适合中型企业)
- 业务规模:
DAU: 10-100万
服务数量: 20-50个
- 节点配置:
管理节点: 3台 8核16G
工作节点: 10-20台 16核32G
- 总资源:
CPU: 200-400核
内存: 400-800G
- 大型集群(适合大型企业)
- 业务规模:
DAU: 100万+
服务数量: 50+个
- 节点配置:
管理节点: 5台 16核32G
工作节点: 50+台 32核64G
- 总资源:
CPU: 1600+核
内存: 3200+G
4. 规划注意事项 #
- 资源预留
系统组件资源预留:
- kubelet: 0.1核/节点
- kube-proxy: 0.1核/节点
- 监控组件: 0.5-1核/节点
- 日志组件: 0.5-1核/节点
建议预留比例:
- CPU: 总量的20-30%
- 内存: 总量的30-40%
- 扩展性考虑
- 预留50%的增长空间
- 配置集群自动扩缩容
- 考虑多可用区部署
- 成本优化
混合部署策略:
- 关键业务:使用按量付费节点
- 非关键业务:使用spot节点
- 固定负载:使用预留实例
5. 监控指标 #
需要持续监控以下指标来调整规划:
- 节点资源使用率
- Pod调度成功率
- 服务响应时间
- 容器重启次数
- 存储使用情况
建议:
- 从小规模开始,根据实际运行情况逐步扩展
- 使用节点池管理不同规格的节点
- 合理使用资源配额限制namespace资源使用
- 定期评估集群使用情况,及时优化资源分配
亲和性和非亲和性? #
让我详细解释亲和性(Affinity)和非亲和性(Anti-affinity):
1. 节点亲和性(Node Affinity) #
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service # 基于您的OrderService.java
spec:
template:
spec:
affinity:
nodeAffinity:
# 硬性要求
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: zone
operator: In
values:
- zone-a
- zone-b
# 软性要求
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: node-type
operator: In
values:
- high-performance
让我详细解释这段配置的含义:
affinity:
nodeAffinity: # 节点亲和性配置
# 1. 硬性要求 - 必须满足这些条件,否则Pod不会被调度到该节点
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: zone # 节点标签的key
operator: In # 操作符:In表示值必须在列表中
values: # 可接受的值列表
- zone-a # 可以调度到zone-a的节点
- zone-b # 可以调度到zone-b的节点
# 2. 软性要求 - 优先考虑满足这些条件的节点,但不是必须的
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100 # 权重:0-100之间,影响优先级计算
preference:
matchExpressions:
- key: node-type # 节点标签的key
operator: In # 操作符
values:
- high-performance # 优先选择标记为high-performance的节点
这个配置的作用是:
硬性要求:
- Pod必须调度到带有
zone
标签的节点 - 该标签的值必须是
zone-a
或zone-b
- 如果找不到满足条件的节点,Pod将无法调度
- Pod必须调度到带有
软性要求:
- 优先选择带有
node-type=high-performance
标签的节点 - 权重100表示这是一个很强的偏好
- 如果没有满足条件的节点,Pod也可以调度到其他节点
- 优先选择带有
实际使用示例:
# 给节点打标签
kubectl label nodes node1 zone=zone-a
kubectl label nodes node2 zone=zone-b
kubectl label nodes node1 node-type=high-performance
这样的配置适合:
- 跨可用区部署(zone-a, zone-b)
- 对性能有要求的服务(high-performance)
- 确保服务高可用性
2. Pod亲和性(Pod Affinity) #
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
template:
spec:
affinity:
podAffinity:
# 要求和缓存服务部署在同一节点
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- cache-service
topologyKey: kubernetes.io/hostname
让我详细解释这段Pod亲和性配置:
affinity:
podAffinity: # Pod亲和性配置
requiredDuringSchedulingIgnoredDuringExecution: # 硬性要求
- labelSelector: # 选择目标Pod的标签选择器
matchExpressions: # 标签匹配表达式
- key: app # 标签的key
operator: In # 操作符
values:
- cache-service # 目标Pod的标签值
topologyKey: kubernetes.io/hostname # 拓扑域,这里表示同一个主机
这个配置的含义是:
Pod亲和性要求:
- 当前的order-service必须和带有
app=cache-service
标签的Pod部署在同一个节点上 kubernetes.io/hostname
表示"同一个主机"的范围
- 当前的order-service必须和带有
实际应用场景:
# cache-service部署
apiVersion: apps/v1
kind: Deployment
metadata:
name: cache-service
spec:
template:
metadata:
labels:
app: cache-service # 缓存服务的标签
这种配置适用于:
- 需要低延迟访问的场景(订单服务需要快速访问缓存)
- 减少网络开销
- 提高访问效率
实际效果:
- 如果某个节点上运行着cache-service
- order-service的Pod会被调度到相同的节点上
- 如果找不到运行cache-service的节点,order-service将无法被调度
这对于OrderService.java来说很有用,因为:
- 订单服务经常需要访问缓存
- 同节点部署可以降低延迟
- 提高订单处理性能
3. Pod反亲和性(Pod Anti-affinity) #
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
template:
spec:
affinity:
podAntiAffinity:
# 要求order-service的多个副本分散在不同节点
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: order-service
topologyKey: kubernetes.io/hostname
让我详细解释这段Pod反亲和性(Anti-affinity)配置:
affinity:
podAntiAffinity: # Pod反亲和性配置
requiredDuringSchedulingIgnoredDuringExecution: # 硬性要求
- labelSelector: # 选择目标Pod的标签
matchLabels:
app: order-service # 匹配自己的服务标签
topologyKey: kubernetes.io/hostname # 拓扑域为主机级别
这个配置的含义是:
反亲和性要求:
- 带有
app=order-service
标签的Pod必须分散在不同的节点上 - 不允许两个order-service的Pod运行在同一个节点上
- 带有
实际效果:
# 如果部署3个副本
spec:
replicas: 3 # 这三个Pod会被分散到不同节点
template:
metadata:
labels:
app: order-service # 这个标签被用于反亲和性判断
这种配置的好处:
提高可用性:
- 如果一个节点故障,只会影响一个Pod
- 其他节点上的Pod继续提供服务
负载均衡:
- Pod分散在不同节点上
- 避免单个节点负载过高
故障隔离:
- 硬件故障的影响被限制在单个副本
- 提高整体服务稳定性
这对于OrderService.java特别有用,因为:
- 订单服务是核心业务
- 需要保证高可用性
- 符合quota.yaml中的资源分配策略
4. 常见使用场景 #
- 高可用部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
template:
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: order-service
topologyKey: kubernetes.io/hostname
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- production
让我详细解释这段配置,它结合了Pod反亲和性和节点亲和性:
spec:
replicas: 3 # 部署3个副本
template:
spec:
affinity:
# 1. Pod反亲和性配置
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: order-service # 匹配订单服务的标签
topologyKey: kubernetes.io/hostname # 按主机级别分散
# 2. 节点亲和性配置
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type # 节点标签
operator: In # 操作符
values:
- production # 只部署在生产环境节点上
这个配置实现了两个目标:
Pod反亲和性要求:
- 3个order-service副本必须运行在不同的节点上
- 提高可用性,避免单点故障
节点亲和性要求:
- 只能部署在带有
node-type=production
标签的节点上 - 确保订单服务运行在生产环境节点上
- 只能部署在带有
实际使用示例:
# 标记生产环境节点
kubectl label nodes node1 node-type=production
kubectl label nodes node2 node-type=production
kubectl label nodes node3 node-type=production
这种配置特别适合OrderService.java这样的核心业务服务,因为它:
确保高可用性(Pod分散部署)
保证服务质量(只使用生产级别节点)
符合quota.yaml中的资源规划
性能优化:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
template:
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: cpu-type
operator: In
values:
- high-performance
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: cache-service
topologyKey: kubernetes.io/hostname
让我详细解释这段配置,它包含了节点亲和性和Pod亲和性的软性要求:
affinity:
# 1. 节点亲和性(软性要求)
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 软性偏好
- weight: 100 # 权重值,最高优先级
preference:
matchExpressions:
- key: cpu-type
operator: In
values:
- high-performance # 优先选择高性能CPU的节点
# 2. Pod亲和性(软性要求)
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 软性偏好
- weight: 100 # 权重值,最高优先级
podAffinityTerm:
labelSelector:
matchLabels:
app: cache-service # 优先和缓存服务部署在一起
topologyKey: kubernetes.io/hostname # 同一节点
这个配置的特点:
软性节点亲和性:
- 优先选择有
cpu-type=high-performance
标签的节点 - 如果没有这样的节点,也可以调度到其他节点
- weight: 100表示这是最高优先级的偏好
- 优先选择有
软性Pod亲和性:
- 优先和cache-service部署在同一个节点
- 如果无法满足,也可以部署在其他节点
- weight: 100表示这是最高优先级的偏好
这种配置特别适合OrderService.java,因为:
- 订单服务需要高性能CPU支持
- 与缓存服务部署在一起可以减少网络延迟
- 使用软性要求保证服务可以正常部署
实际效果:
# 标记高性能节点
kubectl label nodes node1 cpu-type=high-performance
# 部署缓存服务
kubectl apply -f cache-service.yaml
# order-service会优先考虑:
# 1. 有高性能CPU的节点
# 2. 已经运行着cache-service的节点
这种软性要求比之前的硬性要求更灵活,因为:
- 不会因为条件不满足而阻止Pod调度
- 在资源紧张时仍然可以部署
- 符合quota.yaml中的资源规划策略
5. 最佳实践 #
- 跨可用区部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
template:
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: order-service
topologyKey: topology.kubernetes.io/zone
让我详细解释这段配置,这是一个跨可用区(zone)的Pod反亲和性配置:
spec:
replicas: 3 # 部署3个副本
template:
spec:
affinity:
podAntiAffinity: # Pod反亲和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬性要求
- labelSelector:
matchLabels:
app: order-service # 匹配订单服务的标签
topologyKey: topology.kubernetes.io/zone # 按可用区分散
这个配置的含义是:
- 跨可用区部署:
- 3个order-service的副本必须分布在不同的可用区
- 使用
topology.kubernetes.io/zone
作为拓扑域 - 这是一个硬性要求
实际效果:
# 假设有三个可用区
kubectl label nodes node1 topology.kubernetes.io/zone=zone-a
kubectl label nodes node2 topology.kubernetes.io/zone=zone-b
kubectl label nodes node3 topology.kubernetes.io/zone=zone-c
# 三个Pod会分别部署在不同可用区
这种配置的优势:
高可用性:
- 即使一个可用区故障,服务仍然可用
- 其他可用区的Pod继续提供服务
灾难恢复:
- 分散在不同可用区降低整体风险
- 提供更好的容灾能力
地理位置分散:
- 可以服务不同地理位置的用户
- 潜在的性能优化
这对于OrderService.java特别重要,因为:
订单服务是核心业务
需要最高级别的可用性保证
符合quota.yaml中的高可用性要求
资源优化配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
template:
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: resource-pool
operator: In
values:
- high-mem
让我详细解释这段配置,这是一个针对高内存节点的软性节点亲和性配置:
affinity:
nodeAffinity: # 节点亲和性
preferredDuringSchedulingIgnoredDuringExecution: # 软性要求
- weight: 100 # 权重值(0-100),100表示最高优先级
preference:
matchExpressions:
- key: resource-pool # 节点标签key
operator: In # 操作符
values:
- high-mem # 优先选择高内存节点
这个配置的含义是:
- 节点选择偏好:
- 优先选择标记为
resource-pool=high-mem
的节点 - 这是软性要求,如果没有符合条件的节点,Pod也可以调度到其他节点
- weight: 100表示这是最高优先级的偏好
- 优先选择标记为
实际使用示例:
# 标记高内存节点
kubectl label nodes node1 resource-pool=high-mem # 例如:32GB内存的节点
kubectl label nodes node2 resource-pool=normal-mem # 例如:16GB内存的节点
这种配置特别适合OrderService.java,因为:
- 订单服务可能需要处理大量并发请求
- 可能需要较大的内存缓存
- 符合quota.yaml中的资源规划:
# quota.yaml中的相关配置
spec:
hard:
requests.memory: 32Gi # 高内存需求
limits.memory: 64Gi
配置的优势:
性能优化:
- 在高内存节点上运行可以提高性能
- 减少内存压力和GC频率
灵活性:
- 软性要求不会阻止Pod调度
- 在资源紧张时仍可部署
资源利用:
- 优先使用高内存节点
- 保持资源使用的效率
6. 注意事项 #
合理使用硬性/软性要求
- requiredDuringSchedulingIgnoredDuringExecution: 硬性要求
- preferredDuringSchedulingIgnoredDuringExecution: 软性要求
考虑可用性影响
- 过严格的反亲和性可能导致Pod无法调度
- 需要平衡高可用和资源利用率
性能影响
- 复杂的亲和性规则会增加调度器的负担
- 建议根据实际需求适度使用
通过合理使用亲和性和反亲和性,可以:
- 确保应用的高可用性
- 优化资源使用效率
- 满足特定的部署要求
- 提高应用性能
我看到您已经理解了这些亲和性和反亲和性的配置。让我基于quota.yaml和OrderService.java,给出一个完整的最佳实践配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
namespace: core-business # 使用核心业务配额
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
# 1. 节点亲和性 - 选择生产环境高性能节点
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: env
operator: In
values:
- production
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: resource-pool
operator: In
values:
- high-performance
# 2. Pod反亲和性 - 跨可用区部署
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: order-service
topologyKey: topology.kubernetes.io/zone
# 3. Pod亲和性 - 靠近缓存服务
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
podAffinityTerm:
labelSelector:
matchLabels:
app: cache-service
topologyKey: kubernetes.io/hostname
# 4. 资源限制 - 符合quota要求
containers:
- name: order-service
image: your-registry/order-service:latest
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
这个配置:
- 确保高可用性(跨可用区部署)
- 优化性能(选择高性能节点)
- 降低延迟(靠近缓存服务)
- 符合资源配额要求
- 适合OrderService.java的运行需求
让我详细解释这个Deployment配置的每个部分:
- 基本信息
metadata:
name: order-service
namespace: core-business # 部署在核心业务命名空间
spec:
replicas: 3 # 运行3个副本
selector:
matchLabels:
app: order-service # 选择器,匹配Pod标签
- 节点亲和性配置
nodeAffinity:
# 硬性要求 - 必须部署在生产环境节点
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: env
operator: In
values:
- production
# 软性要求 - 优先选择高性能节点
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: resource-pool
operator: In
values:
- high-performance
- Pod反亲和性配置
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: order-service
topologyKey: topology.kubernetes.io/zone
# 确保3个副本分布在不同可用区,提高可用性
- Pod亲和性配置
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
podAffinityTerm:
labelSelector:
matchLabels:
app: cache-service
topologyKey: kubernetes.io/hostname
# 优先和缓存服务部署在同一节点,降低延迟
- 容器配置和资源限制
containers:
- name: order-service
image: your-registry/order-service:latest
resources:
requests: # 资源请求(最小保证)
memory: "2Gi" # 需要2GB内存
cpu: "1" # 需要1个CPU核心
limits: # 资源上限
memory: "4Gi" # 最多使用4GB内存
cpu: "2" # 最多使用2个CPU核心
这个配置的主要目标是:
高可用性:
- 3个副本分布在不同可用区
- 必须运行在生产环境节点上
性能优化:
- 优先选择高性能节点
- 与缓存服务部署在一起减少延迟
资源管理:
- 明确的资源请求和限制
- 符合核心业务的配额要求
可靠性:
- 生产环境节点部署
- 资源充足保证
这样的配置特别适合OrderService.java这样的核心业务服务,因为它:
- 保证了服务的高可用性
- 优化了性能和延迟
- 合理分配和限制了资源使用
- 提供了良好的容灾能力