Pod 密度是每个节点的 Pod 数量,Karpenter 还提供 pod density control
(Pod 密度控制),允许设置在节点上调度的 Pod 数量。 Kubernetes 默认限制每个节点 110 个 pod,在EKS上Pod 数量还受实例类型的限制。
Static Pod Density
- 在Provisioner配置 .spec.kubeletConfiguration
,指定 maxPods 。 此Provisioner生成的所有节点都将在其 kubelet 上设置此 maxPods 值,并将在调度期间考虑此值。Dynamic Pod Densisty
- 设置应在节点的每个 CPU 核心上调度的 pod 数量。 这是通过使用 podsPerCore
参数来完成的,该参数指定每个 CPU 核心的 pod 目标数量。默认情况下,EKS根据实例大小决定了节点能创建的最大pod数量。如果想调整这个值,可以调整spec.kubeletConfiguration
的maxPods
值,这个参数会由Karpenter传给kubelet,在kubelet上设置--max-pods
参数。通过提高小机型的pod密度,可以达到成本优化的效果,每个节点上能跑更多的pod。
在下面的例子中,我们将为c6a.2xlarge
设置Pod密度,让它最多跑6个Pod(它有8个CPU,如果pod需要1个cpu的话能跑8个)
注意设置Static Pod Density的时候很容易遇到一个坑——忽略Daemenset的数量。比如我们node上有六个DaemonSet在跑,那么应用直接启动不起来,因为一启动就会超出maxPods的值
我们将这样设置:
kubeletConfiguration:
maxPods: 6
先删除之前创建的资源:
部署Provisioner和Node Template,注意在spec.kubeletConfiguration
部分指定了最大Pod数量:
mkdir ~/environment/karpenter
cd ~/environment/karpenter
cat <<EoF> static.yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
disruption:
consolidateAfter: 30s
consolidationPolicy: WhenEmpty
expireAfter: Never
template:
metadata:
labels:
eks-immersion-team: my-team
spec:
kubelet:
maxPods: 6
nodeClassRef:
name: default
requirements:
- key: node.kubernetes.io/instance-type
operator: In
values: ["c6a.2xlarge"]
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand"]
- key: kubernetes.io/os
operator: In
values: ["linux"]
---
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
role: "KarpenterNodeRole-${CLUSTER_NAME}"
securityGroupSelectorTerms:
- tags:
alpha.eksctl.io/cluster-name: $CLUSTER_NAME
subnetSelectorTerms:
- tags:
alpha.eksctl.io/cluster-name: $CLUSTER_NAME
tags:
intent: apps
managed-by: karpenter
EoF
kubectl apply -f static.yaml
创建应用:
cd ~/environment/karpenter
cat <<EoF> static-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: inflate
spec:
replicas: 12 # 这里是因为我们Pod上跑了4个DaemonSet,可以继续将这个值调大
selector:
matchLabels:
app: inflate
template:
metadata:
labels:
app: inflate
spec:
terminationGracePeriodSeconds: 0
containers:
- name: inflate
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
resources:
requests:
cpu: 1
nodeSelector:
eks-immersion-team: my-team
EoF
kubectl apply -f static-deploy.yaml
由于我们每个节点上要跑3个DaemonSet,maxPods设置的为6,所以要创建12个replica, 也需要四台机器:
可以设置每个CPU核上运行Pod的数量,从而更好的利用CPU资源。Karpenter把这个值传给kubelet的--pods-per-core
参数来完成设置。例如如果将其设置为5,Karpenter会尝试每个CPU核上运行5个pod,所以如果你有8核CPU,Karpenter将在上面部署40个Pod:
kubelet:
podsPerCore: 5
首先清理之前创建的资源:
kubectl delete deployment inflate
kubectl delete nodepool.karpenter.sh default
kubectl delete ec2nodeclass.karpenter.k8s.aws default
部署NodePool和NodeClass,为了设置每个CPU核上最大Pod数量,在spec.kubelet
中指定了podsPerCore
:
mkdir -p ~/environment/karpenter
cd ~/environment/karpenter
cat <<EoF> dynamic.yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
disruption:
consolidateAfter: 30s
consolidationPolicy: WhenEmpty
expireAfter: Never
template:
metadata:
labels:
eks-immersion-team: my-team
spec:
kubelet:
podsPerCore: 5
nodeClassRef:
name: default
requirements:
- key: node.kubernetes.io/instance-type
operator: In
values: ["c6a.2xlarge"]
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand"]
- key: kubernetes.io/os
operator: In
values: ["linux"]
---
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
role: "KarpenterNodeRole-${CLUSTER_NAME}"
securityGroupSelectorTerms:
- tags:
alpha.eksctl.io/cluster-name: $CLUSTER_NAME
subnetSelectorTerms:
- tags:
alpha.eksctl.io/cluster-name: $CLUSTER_NAME
tags:
intent: apps
managed-by: karpenter
EoF
kubectl apply -f dynamic.yaml
我们创建inflate应用,并让它有45个replica:
cd ~/environment/karpenter
cat <<EoF> dynamic-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: inflate
spec:
replicas: 45
selector:
matchLabels:
app: inflate
template:
metadata:
labels:
app: inflate
spec:
terminationGracePeriodSeconds: 0
containers:
- name: inflate
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
resources:
requests:
cpu: 0.1
nodeSelector:
eks-immersion-team: my-team
EoF
kubectl apply -f dynamic-deploy.yaml
c6a.2xlarge
具有8个CPU,我们将cpu request设置为0.1,理想情况它上面应该能跑80个pod。但是因为设置了podsPerCore = 5
,所以它实际最多只能跑40个pod: