GKE Kubernetes 节点池升级非常慢



我正在 6 个节点(在两个节点池中)测试集群中试验 GKE 集群升级,然后再在我们的暂存或生产集群上尝试。当我只有 12 个副本 nginx 部署时,安装的 nginx 入口控制器和证书管理器(如掌舵图)每个节点池(3 个节点)需要 10 分钟。我非常满意。我决定再试一次看起来更像我们设置的东西。我删除了nginx部署并添加了2个节点.js部署,以下helm图表:mongodb-0.4.27,mcrouter-0.1.0(作为有状态集),redis-ha-2.0.0和我自己的www-redirect-0.0.1图表(简单的nginx,可以重定向)。问题似乎出在麦克路由器上。一旦节点开始耗尽,该节点的状态将更改为Ready,SchedulingDisabled(这似乎正常),但以下 Pod 仍然存在:

  • 麦克路由器-内存缓存-0
  • 流利的GCP-v2.0.9-4F87T
  • kube-proxy-gke-test-upgrade-cluster-default-pool-74f8edac-wblf

我不知道为什么那两个 kube 系统 pod 仍然存在,但那个 mcrouter 是我的,它不会足够快。如果我等待足够长的时间(1 小时+),那么它最终会起作用,我不确定为什么。 当前节点池(3 个节点)在 2h46 分钟前开始升级,2 个节点已升级,第 3 个仍在升级但没有任何移动......我想它会在接下来的 1-2 小时内完成...... 我尝试用--ignore-daemonsets --force运行 drain 命令,但它告诉我它已经被耗尽了。 我试图删除 pod,但它们只是回来了,升级没有移动得更快。 有什么想法吗?

更新 #1

麦克路由器掌舵图是这样安装的:

helm install stable/mcrouter --name mcrouter --set controller=statefulset

它为 mcrouter 部分创建的有状态集是:

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
labels:
app: mcrouter-mcrouter
chart: mcrouter-0.1.0
heritage: Tiller
release: mcrouter
name: mcrouter-mcrouter
spec:
podManagementPolicy: OrderedReady
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: mcrouter-mcrouter
chart: mcrouter-0.1.0
heritage: Tiller
release: mcrouter
serviceName: mcrouter-mcrouter
template:
metadata:
labels:
app: mcrouter-mcrouter
chart: mcrouter-0.1.0
heritage: Tiller
release: mcrouter
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: mcrouter-mcrouter
release: mcrouter
topologyKey: kubernetes.io/hostname
containers:
- args:
- -p 5000
- --config-file=/etc/mcrouter/config.json
command:
- mcrouter
image: jphalip/mcrouter:0.36.0
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: mcrouter-port
timeoutSeconds: 5
name: mcrouter-mcrouter
ports:
- containerPort: 5000
name: mcrouter-port
protocol: TCP
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: mcrouter-port
timeoutSeconds: 1
resources:
limits:
cpu: 256m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/mcrouter
name: config
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- configMap:
defaultMode: 420
name: mcrouter-mcrouter
name: config
updateStrategy:
type: OnDelete

这是 memcached Statefulset:

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
labels:
app: mcrouter-memcached
chart: memcached-1.2.1
heritage: Tiller
release: mcrouter
name: mcrouter-memcached
spec:
podManagementPolicy: OrderedReady
replicas: 5
revisionHistoryLimit: 10
selector:
matchLabels:
app: mcrouter-memcached
chart: memcached-1.2.1
heritage: Tiller
release: mcrouter
serviceName: mcrouter-memcached
template:
metadata:
labels:
app: mcrouter-memcached
chart: memcached-1.2.1
heritage: Tiller
release: mcrouter
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: mcrouter-memcached
release: mcrouter
topologyKey: kubernetes.io/hostname
containers:
- command:
- memcached
- -m 64
- -o
- modern
- -v
image: memcached:1.4.36-alpine
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: memcache
timeoutSeconds: 5
name: mcrouter-memcached
ports:
- containerPort: 11211
name: memcache
protocol: TCP
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: memcache
timeoutSeconds: 1
resources:
requests:
cpu: 50m
memory: 64Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
updateStrategy:
type: OnDelete
status:
replicas: 0

这是一个有点复杂的问题,我绝对不确定它是否像我的想法,但是......让我们试着了解正在发生的事情。

您有一个升级过程,并且群集中有 6 个节点。系统将使用 Drain 逐个升级它,以从 Pod 中删除所有工作负载。

清空进程本身尊重您的设置和副本数以及所需的工作负载状态,其优先级高于节点本身的清空。

在耗尽过程中,Kubernetes 将尝试将所有工作负载安排在调度可用的资源上。在系统要排出的节点上的调度被禁用,您可以看到它的状态 -Ready,SchedulingDisabled

因此,Kubernetes 调度程序试图在所有可用节点上为您的工作负载找到合适的位置。只要它需要将您描述的所有内容放在群集配置中,它就会等待。

现在最重要的事情。您设置需要replicas: 5为您的mcrouter-memcached。由于podAntiAffinity,它不能在每个节点上运行多个副本,并且运行它的节点应该有足够的资源,这是使用resources:ReplicaSet块计算的。

因此,我认为,您的集群没有足够的资源在其余 5 个节点上运行mcrouter-memcached的新副本。例如,在副本仍未运行的最后一个节点上,由于其他工作负载,您没有足够的内存。

我认为如果您将mcrouter-memcachedreplicaset设置为 4,它将解决问题。或者,您可以尝试为该工作负载使用更强大的实例,或者向集群再添加一个节点,这也应该会有所帮助。

希望我对我的逻辑给出了足够的解释,问我是否有什么不清楚的地方。但首先请尝试通过提供的解决方案解决问题:)

问题是来自 PodDisruptBudget 的 minAvailable 值(这是 memcached helm chart的一部分,它是 mcrouter helm chart的依赖项)和 memcached 副本集的副本值的组合。两者都设置为 5,因此在耗尽期间无法删除它们。我尝试将 minAvailable 更改为 4,但 PDB 目前是不可变的。我所做的是删除舵图并替换它。

helm delete --purge myproxy
helm install ./charts/mcrouter-0.1.0-croy.1.tgz --name myproxy --set controller=statefulset --set memcached.replicaCount=5 --set memcached.pdbMinAvailable=4

完成此操作后,我能够使群集正常升级。

我应该做的(但只是在之后才考虑)是将副本值更改为 6,这样我就不需要删除和替换整个图表。

感谢您@AntonKostenko试图帮助我找到这个问题。 这个问题也帮助了我。 感谢Slack@Kubernetes的人们,特别是巴黎,他们试图让我的问题更加可见,以及 Kubernetes 办公时间的志愿者(碰巧是昨天,幸运的是我!)也看了一眼。 最后,感谢来自加拿大 Kubernetes 的 psycotica0 也给了我一些指示。

最新更新