我正在尝试在 GKE Autopilot 上运行两个 1 副本部署。我希望将两个 Pod 安排在同一节点上。
我相信我应该能够在两个部署中使用 PodAffinity 来实现这一点:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: component
operator: In
values:
- app
topologyKey: kubernetes.io/hostname
Autopilot 启动一个节点并调度一个 Pod,但第二个 Pod 处于待处理状态,表示没有节点满足亲和性规则/资源。我本来希望 Autopilot 能够启动一个更大的节点来容纳两个 Pod。我是否遗漏了有关 PodAffinity 或 Autopilot 工作原理的信息?
Kubernetes 和 GKE 中没有机制可以重新创建节点以更好地适应 Pod。自动缩放(在 GKE 中以及在 OSS Cluster Autoscaler 中)通常只会为待处理的 pod 创建节点并删除空/未充分利用的节点。
工作负载分离
使用工作负载分离强制将 Pod 调度到一个(或多个,如果后续 Pod 不适合)专用节点上。请注意,如果两个 pod 的总和大于专用节点大小,仍然可能会出现此问题。 工作负载分离解决方案:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-app1
spec:
replicas: 1
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: cloud.google.com/compute-class
operator: In
values:
- Scale-Out
containers:
- name: hello-app
image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
resources:
requests:
memory: "1Gi"
tolerations:
- key: wskey
operator: Equal
value: wslabel
effect: NoSchedule
nodeSelector:
wskey: wslabel
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-app2
spec:
replicas: 1
selector:
matchLabels:
app: app2
template:
metadata:
labels:
app: app2
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- app1
topologyKey: "kubernetes.io/hostname"
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: cloud.google.com/compute-class
operator: In
values:
- Scale-Out
containers:
- name: hello-app
image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
resources:
requests:
memory: "1Gi"
tolerations:
- key: wskey
operator: Equal
value: wslabel
effect: NoSchedule
nodeSelector:
wskey: wslabel
具有工作负载分离的DaemonSet
在所有 Deployment 上应用工作负载分离配置,然后将除一个 Deployment(领导者)之外的所有 Deployment 转换为 DaemonSet (DS)。然后首先应用 DS,然后进行部署。这将确保节点足够大以捕获所有 DS 和领导者部署。
您可以在以下链接中阅读更多相关信息。