我有一个5节点集群(1-master/4-worker)。有没有可能配置一个StatefulSet,我可以让一个pod在给定的节点上运行,知道它有足够的容量,而不是Kubernetes Scheduler来做这个决定?
假设我的StatefulSet创建了4个pod(副本: 4)作为myapp-0、myapp-1、myapp-2和myapp-3。现在我要找的是:
myapp-0 pod--获取调度时间-> worker-1
myapp-1 pod--获取调度时间-> worker-2
myapp-2 pod--获取调度时间-> worker-3
myapp-3 pod--获取调度时间-> worker-4
请让我知道它是否能以某种方式实现?因为如果我给StatefulSet的pod添加一个容差,那么所有的pod都是一样的,并且所有的pod都会被调度到一个与污点匹配的节点上。
谢谢,J
发布于 2020-02-17 21:46:30
您可以将调度任意pod子集的责任委托给您自己的自定义调度器,这些调度器与默认的Kubernetes调度器一起运行,或者代替默认的Kubernetes调度器运行。
您可以编写自己的自定义调度程序。自定义调度程序可以用任何语言编写,可以根据您的需要而简单或复杂。下面是一个用Bash编写的自定义调度器的非常简单的示例,它随机分配一个节点。请注意,您需要将其与kubectl代理一起运行,才能使其工作。
SERVER='localhost:8001'
while true;
do
for PODNAME in $(kubectl --server $SERVER get pods -o json | jq '.items[] | select(.spec.schedulerName == "my-scheduler") | select(.spec.nodeName == null) | .metadata.name' | tr -d '"')
;
do
NODES=($(kubectl --server $SERVER get nodes -o json | jq '.items[].metadata.name' | tr -d '"'))
NUMNODES=${#NODES[@]}
CHOSEN=${NODES[$[$RANDOM % $NUMNODES]]}
curl --header "Content-Type:application/json" --request POST --data '{"apiVersion":"v1", "kind": "Binding", "metadata": {"name": "'$PODNAME'"}, "target": {"apiVersion": "v1", "kind"
: "Node", "name": "'$CHOSEN'"}}' http://$SERVER/api/v1/namespaces/default/pods/$PODNAME/binding/
echo "Assigned $PODNAME to $CHOSEN"
done
sleep 1
done然后,只需在规范部分下的StatefulSet配置文件中添加schedulerName: your-scheduler行。
您也可以使用pod affinity:。
示例:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-cache
spec:
selector:
matchLabels:
app: store
replicas: 3
template:
metadata:
labels:
app: store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis-server
image: redis:3.2-alpine下面的The服务器statefuset的yaml片段配置了podAntiAffinity和podAffinity。这会通知调度程序,它的所有副本都将与具有选择器标签app=store的pod放在同一位置。这还将确保每个web服务器副本不会共存于单个节点上。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-server
spec:
selector:
matchLabels:
app: web-store
replicas: 3
template:
metadata:
labels:
app: web-store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-store
topologyKey: "kubernetes.io/hostname"
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: web-app
image: nginx:1.12-alpine如果我们创建上述两个部署,我们的三节点集群应该如下所示。
node-1 node-2 node-3
webserver-1 webserver-2 webserver-3
cache-1 cache-2 cache-3上面的示例使用带有topologyKey:"kubernetes.io/hostname"的PodAntiAffinity规则来部署redis集群,这样就不会有两个实例位于同一主机上
您可以简单地定义特定pod的三个副本,并定义特定pod配置文件egg。注意:有label:nodeName,这是节点选择约束的最简单形式,但由于其限制,通常不使用它。nodeName是PodSpec的一个字段。如果它不为空,则调度程序将忽略pod,并且在指定节点上运行的kubelet将尝试运行pod。因此,如果PodSpec中提供了nodeName,则它优先于上面的节点选择方法。
以下是使用nodeName字段的pod配置文件的示例:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeName: kube-worker-1有关调度程序的更多信息:custom-scheduler。
看看这篇文章:assigining-pods-kubernetes。
发布于 2020-02-16 10:10:43
你可以使用nodeSelector和node affinity来做这件事(看看这个指南https://kubernetes.io/docs/concepts/configuration/assign-pod-node/),任何人都可以用来在特定的节点上运行pod。但是如果节点有污染(限制),那么您需要为这些节点添加容差(更多信息可以在https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/中找到)。使用这种方法,您可以指定用于pod调度的节点列表,问题是如果您指定for ex。3个节点,你有5个pod,那么你无法控制在每个节点上运行多少pod。它们按照kube-schedular进行分发。另一个相关用例:如果您想在每个指定节点上运行一个pod,您可以创建一个守护进程并使用nodeSelector选择节点。
发布于 2020-02-16 16:19:30
您可以使用podAntiAffinity将副本分发到不同的节点。
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: "kubernetes.io/hostname"这将在worker1中部署web-0,在worker2中部署web-1,在worker3中部署web-2,在worker4中部署web-3。
https://stackoverflow.com/questions/60242339
复制相似问题