Вы можете делегировать ответственность за планирование произвольных подмножеств подов своему собственному (ым) планировщику (ам), которые запускаются (ются) вместе с планировщиком 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
.
Вы также можете использовать привязка к пакету:.
Пример:
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
В приведенном ниже фрагменте yaml набора состояний веб-сервера настроены podAntiAffinity и podAffinity. Это сообщает планировщику, что все его реплики должны быть расположены вместе с модулями, имеющими метку селектора app = store. Это также гарантирует, что каждая реплика веб-сервера не будет размещена на одном узле.
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
В приведенном выше примере используется правило PodAntiAffinity с topologyKey: "kubernetes.io/hostname"
для развертывания кластера Redis, чтобы на одном хосте не было двух экземпляров.
Вы можете просто определить три реплики конкретного модуля и определить конкретный файл конфигурации модуля, egg .: Есть метка: nodeName, который является простейшей формой ограничения выбора узла, но из-за его ограничений обычно не используется. nodeName - это поле PodSpec. Если он не пустой, планировщик игнорирует модуль, и кубелет, запущенный на указанном узле, пытается запустить модуль. Таким образом, если nodeName предоставляется в PodSpec, он имеет приоритет над вышеуказанными методами выбора узла.
Вот пример файла конфигурации модуля с использованием поля nodeName:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeName: kube-worker-1
Дополнительная информация о планировщике: custom-scheduler.
Взгляните на эту статью: assigining-pods-kubernetes.
person
Malgorzata
schedule
17.02.2020