|
|
Как добавить master-узел в статическом или гибридном кластере?
| How do I add a master node to a static or hybrid cluster?
|
Важно иметь нечетное количество master-узлов для обеспечения кворума.
|
It is important to have an odd number of masters to ensure a quorum.
|
Добавление master-узла в статический или гибридный кластер ничем не отличается от добавления обычного узла в кластер. Воспользуйтесь для этого соответствующими примерами. Все необходимые действия по настройке компонентов control plane кластера на новом узле будут выполнены автоматически, дождитесь их завершения — появления master-узлов в статусе Ready .
| Adding a master node to a static or hybrid cluster has no difference from adding a regular node to a cluster. To do this, use the corresponding examples. All the necessary actions to configure a cluster control plane components on the new master nodes are performed automatically. Wait until the master nodes appear in Ready status.
|
Как добавить master-узлы в облачном кластере (single-master в multi-master)?
| How do I add a master nodes to a cloud cluster (single-master to a multi-master)?
|
Перед добавлением узлов убедитесь в наличии необходимых квот.
Важно иметь нечетное количество master-узлов для обеспечения кворума.
|
Before adding nodes, ensure you have the required quotas in the cloud provider.
It is important to have an odd number of masters to ensure a quorum.
|
- Сделайте резервную копию
etcd и папки /etc/kubernetes .
- Скопируйте полученный архив за пределы кластера (например, на локальную машину).
- Убедитесь, что в кластере нет алертов, которые могут помешать созданию новых master-узлов.
- Убедитесь, что очередь Deckhouse пуста.
- На локальной машине запустите контейнер установщика Deckhouse соответствующей редакции и версии (измените адрес container registry при необходимости):
|
- Make a backup of
etcd and the /etc/kubernetes directory.
- Transfer the archive to a server outside the cluster (e.g., on a local machine).
- Ensure there are no alerts in the cluster that can prevent the creation of new master nodes.
- Make sure that Deckhouse queue is empty.
- Run the appropriate edition and version of the Deckhouse installer container on the local machine (change the container registry address if necessary):
|
bash
DH_VERSION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/version}’)
DH_EDITION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/edition}’ | tr ‘[:upper:]’ ‘[:lower:]’ )
docker run –pull=always -it -v “$HOME/.ssh/:/tmp/.ssh/”
registry.deckhouse.io/deckhouse/${DH_EDITION}/install:${DH_VERSION} bash
| bash
DH_VERSION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/version}’)
DH_EDITION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/edition}’ | tr ‘[:upper:]’ ‘[:lower:]’ )
docker run –pull=always -it -v “$HOME/.ssh/:/tmp/.ssh/”
registry.deckhouse.io/deckhouse/${DH_EDITION}/install:${DH_VERSION} bash
|
- В контейнере с инсталлятором выполните следующую команду, чтобы проверить состояние перед началом работы:
|
- In the installer container, run the following command to check the state before working:
|
bash
dhctl terraform check –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= --ssh-host
| bash
dhctl terraform check –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= --ssh-host
|
Ответ должен сообщить, что Terraform не нашел расхождений и изменений не требуется.
| The command output should indicate that Terraform found no inconsistencies and no changes are required.
|
- В контейнере с инсталлятором выполните следующую команду и укажите требуемое количество мастер-узлов в параметре
masterNodeGroup.replicas :
|
- In the installer container, run the following command and specify the required number of replicas using the
masterNodeGroup.replicas parameter:
|
bash
dhctl config edit provider-cluster-configuration –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host
| bash
dhctl config edit provider-cluster-configuration –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host
|
Для Yandex Cloud, при использовании внешних адресов на мастер-узлах, количество элементов массива в параметре masterNodeGroup.instanceClass.externalIPAddresses должно равняться количеству мастер-узлов. При использовании значения Auto (автоматический заказ публичных IP-адресов), количество элементов в массиве все равно должно соответствовать количеству мастер-узлов.
Например, при трех мастер-узлах (masterNodeGroup.replicas: 3 ) и автоматическом заказе адресов, параметр masterNodeGroup.instanceClass.externalIPAddresses будет выглядеть следующим образом:
bash
externalIPAddresses:
|
For Yandex Cloud, when using external addresses on master nodes, the number of array elements in the masterNodeGroup.instanceClass.externalIPAddresses parameter must equal the number of master nodes. If Auto is used (public IP addresses are provisioned automatically), the number of array elements must still equal the number of master nodes.
To illustrate, with three master nodes (masterNodeGroup.replicas: 3 ) and automatic address reservation, the masterNodeGroup.instanceClass.externalIPAddresses parameter would look as follows:
bash
externalIPAddresses:
|
- В контейнере с инсталлятором выполните следующую команду для запуска масштабирования:
|
- In the installer container, run the following command to start scaling:
|
bash
dhctl converge –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= --ssh-host
| bash
dhctl converge –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= --ssh-host
|
- Дождитесь появления необходимого количества master-узлов в статусе
Ready и готовности всех экземпляров control-plane-manager :
|
- Wait until the required number of master nodes are
Ready and all control-plane-manager instances are up and running:
|
bash
kubectl -n kube-system wait pod –timeout=10m –for=condition=ContainersReady -l app=d8-control-plane-manager
| bash
kubectl -n kube-system wait pod –timeout=10m –for=condition=ContainersReady -l app=d8-control-plane-manager
|
|
|
Как уменьшить число master-узлов в облачном кластере (multi-master в single-master)?
| How do I reduce the number of master nodes in a cloud cluster (multi-master to single-master)?
|
- Сделайте резервную копию
etcd и папки /etc/kubernetes .
- Скопируйте полученный архив за пределы кластера (например, на локальную машину).
- Убедитесь, что в кластере нет алертов, которые могут помешать обновлению master-узлов.
- Убедитесь, что очередь Deckhouse пуста.
- На локальной машине запустите контейнер установщика Deckhouse соответствующей редакции и версии (измените адрес container registry при необходимости):
|
- Make a backup of
etcd and the /etc/kubernetes directory.
- Transfer the archive to a server outside the cluster (e.g., on a local machine).
- Ensure there are no alerts in the cluster that can prevent the update of the master nodes.
- Make sure that Deckhouse queue is empty.
- Run the appropriate edition and version of the Deckhouse installer container on the local machine (change the container registry address if necessary):
|
bash
DH_VERSION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/version}’)
DH_EDITION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/edition}’ | tr ‘[:upper:]’ ‘[:lower:]’ )
docker run –pull=always -it -v “$HOME/.ssh/:/tmp/.ssh/”
registry.deckhouse.io/deckhouse/${DH_EDITION}/install:${DH_VERSION} bash
| bash
DH_VERSION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/version}’)
DH_EDITION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/edition}’ | tr ‘[:upper:]’ ‘[:lower:]’ )
docker run –pull=always -it -v “$HOME/.ssh/:/tmp/.ssh/”
registry.deckhouse.io/deckhouse/${DH_EDITION}/install:${DH_VERSION} bash
|
- В контейнере с инсталлятором выполните следующую команду и укажите
1 в параметре masterNodeGroup.replicas :
|
- In the installer container, run the following command to check the state before working:
|
bash
dhctl config edit provider-cluster-configuration –ssh-agent-private-keys=/tmp/.ssh/ \
--ssh-user= --ssh-host
| bash
dhctl terraform check –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= --ssh-host
|
- Снимите следующие лейблы с удаляемых master-узлов:
node-role.kubernetes.io/control-plane
node-role.kubernetes.io/master
node.deckhouse.io/group
| The response should tell you that Terraform does not want to change anything.
|
Команда для снятия лейблов:
|
- Run the following command in the installer container and set
masterNodeGroup.replicas to 1 :
|
bash
kubectl label node node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master- node.deckhouse.io/group-
| bash
dhctl config edit provider-cluster-configuration –ssh-agent-private-keys=/tmp/.ssh/ \
--ssh-user= --ssh-host
|
- Убедитесь, что удаляемые master-узлы пропали из списка членов кластера etcd:
|
- Remove the following labels from the master nodes to be deleted:
node-role.kubernetes.io/control-plane
node-role.kubernetes.io/master
node.deckhouse.io/group
|
bash
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
| Use the following command to remove labels:
|
- Выполните
drain для удаляемых узлов:
| bash
kubectl label node node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master- node.deckhouse.io/group-
|
bash
kubectl drain --ignore-daemonsets --delete-emptydir-data
|
- Make sure that the master nodes to be deleted are no longer listed as etcd cluster members:
|
- Выключите виртуальные машины, соответствующие удаляемым узлам, удалите инстансы соответствующих узлов из облака и подключенные к ним диски (
kubernetes-data-master-<N> ).
| bash
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
|
- Удалите в кластере поды, оставшиеся на удаленных узлах:
|
drain the nodes being deleted:
|
bash
kubectl delete pods –all-namespaces –field-selector spec.nodeName= --force
| bash
kubectl drain --ignore-daemonsets --delete-emptydir-data
|
- Удалите в кластере объекты
Node удаленных узлов:
|
- Shut down the virtual machines corresponding to the nodes to be deleted, remove the instances of those nodes from the cloud and the disks connected to them (
kubernetes-data-master-<N> ).
|
bash
kubectl delete node
|
- In the cluster, delete the Pods running on the nodes being deleted:
|
- В контейнере с инсталлятором выполните следующую команду для запуска масштабирования:
| bash
kubectl delete pods –all-namespaces –field-selector spec.nodeName= --force
|
bash
dhctl converge –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= --ssh-host
|
- In the cluster, delete the Node objects associated with the nodes being deleted:
|
Как убрать роль master-узла, сохранив узел?
| bash
kubectl delete node
|
- Сделайте резервную копию
etcd и папки /etc/kubernetes .
- Скопируйте полученный архив за пределы кластера (например, на локальную машину).
- Убедитесь, что в кластере нет алертов, которые могут помешать обновлению master-узлов.
- Убедитесь, что очередь Deckhouse пуста.
- Снимите лейблы
node.deckhouse.io/group: master и node-role.kubernetes.io/control-plane: "" .
- Убедитесь, что удаляемый master-узел пропал из списка членов кластера etcd:
|
- In the installer container, run the following command to start scaling:
|
bash
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
| bash
dhctl converge –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= --ssh-host
|
- Зайдите на узел и выполните следующие команды:
| How do I dismiss the master role while keeping the node?
|
shell
rm -f /etc/kubernetes/manifests/{etcd,kube-apiserver,kube-scheduler,kube-controller-manager}.yaml
rm -f /etc/kubernetes/{scheduler,controller-manager}.conf
rm -f /etc/kubernetes/authorization-webhook-config.yaml
rm -f /etc/kubernetes/admin.conf /root/.kube/config
rm -rf /etc/kubernetes/deckhouse
rm -rf /etc/kubernetes/pki/{ca.key,apiserver,etcd/,front-proxy,sa.*}
rm -rf /var/lib/etcd/member/
|
- Make a backup of
etcd and the /etc/kubernetes directory.
- Transfer the archive to a server outside the cluster (e.g., on a local machine).
- Ensure there are no alerts in the cluster that can prevent the update of the master nodes.
- Make sure that Deckhouse queue is empty.
- Remove the
node.deckhouse.io/group: master and node-role.kubernetes.io/control-plane: "" labels.
- Make sure that the master node to be deleted is no longer listed as a member of the etcd cluster:
|
Как изменить образ ОС в multi-master-кластере?
| bash
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
|
- Сделайте резервную копию
etcd и папки /etc/kubernetes .
- Скопируйте полученный архив за пределы кластера (например, на локальную машину).
- Убедитесь, что в кластере нет алертов, которые могут помешать обновлению master-узлов.
- Убедитесь, что очередь Deckhouse пуста.
- На локальной машине запустите контейнер установщика Deckhouse соответствующей редакции и версии (измените адрес container registry при необходимости):
|
- Exec to the node and run the following commands:
|
bash
DH_VERSION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/version}’)
DH_EDITION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/edition}’ | tr ‘[:upper:]’ ‘[:lower:]’ )
docker run –pull=always -it -v “$HOME/.ssh/:/tmp/.ssh/”
registry.deckhouse.io/deckhouse/${DH_EDITION}/install:${DH_VERSION} bash
| shell
rm -f /etc/kubernetes/manifests/{etcd,kube-apiserver,kube-scheduler,kube-controller-manager}.yaml
rm -f /etc/kubernetes/{scheduler,controller-manager}.conf
rm -f /etc/kubernetes/authorization-webhook-config.yaml
rm -f /etc/kubernetes/admin.conf /root/.kube/config
rm -rf /etc/kubernetes/deckhouse
rm -rf /etc/kubernetes/pki/{ca.key,apiserver,etcd/,front-proxy,sa.*}
rm -rf /var/lib/etcd/member/
|
- В контейнере с инсталлятором выполните следующую команду, чтобы проверить состояние перед началом работы:
| How do I switch to a different OS image in a multi-master cluster?
|
bash
dhctl terraform check –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
|
- Make a backup of
etcd and the /etc/kubernetes directory.
- Transfer the archive to a server outside the cluster (e.g., on a local machine).
- Ensure there are no alerts in the cluster that can prevent the update of the master nodes.
- Make sure that Deckhouse queue is empty.
- Run the appropriate edition and version of the Deckhouse installer container on the local machine (change the container registry address if necessary):
|
Ответ должен сообщить вам, что Terraform не хочет ничего менять.
| bash
DH_VERSION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/version}’)
DH_EDITION=$(kubectl -n d8-system get deployment deckhouse -o jsonpath=’{.metadata.annotations.core.deckhouse.io\/edition}’ | tr ‘[:upper:]’ ‘[:lower:]’ )
docker run –pull=always -it -v “$HOME/.ssh/:/tmp/.ssh/”
registry.deckhouse.io/deckhouse/${DH_EDITION}/install:${DH_VERSION} bash
|
- В контейнере с инсталлятором выполните следующую команду и укажите необходимый образ ОС в параметре
masterNodeGroup.instanceClass (укажите адреса всех master-узлов в параметре --ssh-host ):
|
- In the installer container, run the following command to check the state before working:
|
bash
dhctl config edit provider-cluster-configuration –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
| bash
dhctl terraform check –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
|
Следующие действия выполняйте поочередно на каждом master-узле, начиная с узла с наивысшим номером (с суффиксом 2) и заканчивая узлом с наименьшим номером (с суффиксом 0).
| The response should tell you that Terraform does not want to change anything.
|
- Выберите master-узел для обновления (укажите его название):
|
- In the installer container, run the following command and specify the required OS image using the
masterNodeGroup.instanceClass parameter (specify the addresses of all master nodes using the -ssh-host parameter):
|
bash
NODE=”"
| bash
dhctl config edit provider-cluster-configuration –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
|
- Выполните следующую команду для снятия лейблов
node-role.kubernetes.io/control-plane , node-role.kubernetes.io/master , node.deckhouse.io/group с узла:
| Repeat the steps below for each master node one by one, starting with the node with the highest number (suffix 2) and ending with the node with the lowest number (suffix 0).
|
bash
kubectl label node ${NODE}
node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master- node.deckhouse.io/group-
|
- Select the master node to update (enter its name):
|
- Убедитесь, что узел пропал из списка членов кластера etcd:
| bash
NODE=”"
|
bash
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
|
- Run the following command to remove the
node-role.kubernetes.io/control-plane , node-role.kubernetes.io/master , and node.deckhouse.io/group labels from the node:
|
- Выполните
drain для узла:
| bash
kubectl label node ${NODE}
node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master- node.deckhouse.io/group-
|
bash
kubectl drain ${NODE} –ignore-daemonsets –delete-emptydir-data
|
- Make sure that the node is no longer listed as an etcd cluster member:
|
- Выключите виртуальную машину, соответствующую узлу, удалите инстанс узла из облака и подключенные к нему диски (kubernetes-data).
| bash
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
|
- Удалите в кластере поды, оставшиеся на удаляемом узле:
|
- Drain the node:
|
bash
kubectl delete pods –all-namespaces –field-selector spec.nodeName=${NODE} –force
| bash
kubectl drain ${NODE} –ignore-daemonsets –delete-emptydir-data
|
- Удалите в кластере объект
Node удаленного узла:
|
- Shut down the virtual machine associated with the node, remove the node instance from the cloud and the disks connected to it (
kubernetes-data ).
|
bash
kubectl delete node ${NODE}
|
- In the cluster, delete the Pods remaining on the node being deleted:
|
- В контейнере с инсталлятором выполните следующую команду для создания обновленного узла:
| bash
kubectl delete pods –all-namespaces –field-selector spec.nodeName=${NODE} –force
|
Вам нужно внимательно прочитать, что converge собирается делать, когда запрашивает одобрение.
|
- In the cluster, delete the Node object for the node being deleted:
|
Если converge запрашивает одобрение для другого мастер-узла, его следует пропустить, выбрав no .
| bash
kubectl delete node ${NODE}
|
bash
dhctl converge –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
|
- In the installer container, run the following command to create the updated node:
|
- На созданном узле посмотрите журнал systemd-unit’а
bashible.service . Дождитесь окончания настройки узла — в журнале появится сообщение nothing to do :
| You should read carefully what converge is going to do when it asks for approval.
|
bash
journalctl -fu bashible.service
| If converge requests approval for another master node, it should be skipped by saying no .
|
- Убедитесь, что узел появился в списке членов кластера etcd:
| bash
dhctl converge –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
|
bash
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
|
- On the newly created node, check the systemd-unit log for the
bashible.service . Wait until the node configuration is complete (you will see a message nothing to do in the log):
|
- Убедитесь, что
control-plane-manager функционирует на узле.
| bash
journalctl -fu bashible.service
|
bash
kubectl -n kube-system wait pod –timeout=10m –for=condition=ContainersReady
-l app=d8-control-plane-manager –field-selector spec.nodeName=${NODE}
|
- Make sure the node is listed as an etcd cluster member:
|
- Перейдите к обновлению следующего узла.
| bash
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
|
Как изменить образ ОС в single-master-кластере?
|
- Make sure
control-plane-manager is running on the node:
|
- Преобразуйте single-master-кластер в multi-master в соответствии с инструкцией.
- Обновите master-узлы в соответствии с инструкцией.
- Преобразуйте multi-master-кластер в single-master в соответствии с инструкцией
| bash
kubectl -n kube-system wait pod –timeout=10m –for=condition=ContainersReady
-l app=d8-control-plane-manager –field-selector spec.nodeName=${NODE}
|
Как посмотреть список member’ов в etcd?
|
- Proceed to update the next node (repeat the steps above).
|
Вариант 1
| How do I switch to a different OS image in a single-master cluster?
|
Используйте команду etcdctl member list
|
- Convert your single-master cluster to a multi-master one, as described in the guide on adding master nodes to a cluster.
- Update the master nodes following the instructions.
- Convert your multi-master cluster to a single-master one according to the guide on excluding master nodes from the cluster.
|
Пример:
| How do I view the list of etcd members?
|
shell
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
| Option 1
|
Внимание! Последний параметр в таблице вывода показывает, что член etcd находится в состоянии learner, а не в состоянии leader.
| Use the etcdctl member list command.
|
Вариант 2
| Example:
|
Используйте команду etcdctl endpoint status . Пятый параметр в таблице вывода будет true у лидера.
| shell
kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) –
etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt
–cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key
–endpoints https://127.0.0.1:2379/ member list -w table
|
Пример:
| Warning! The last parameter in the output table shows etcd member is in learner state, is not in leader state.
|
shell
$ kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) – etcdctl \
–cacert /etc/kubernetes/pki/etcd/ca.crt –cert /etc/kubernetes/pki/etcd/ca.crt \
–key /etc/kubernetes/pki/etcd/ca.key –endpoints https://127.0.0.1:2379/ endpoint status -w table
| Option 2
|
https://10.2.1.101:2379, ade526d28b1f92f7, 3.5.3, 177 MB, false, false, 42007, 406566258, 406566258,
https://10.2.1.102:2379, d282ac2ce600c1ce, 3.5.3, 182 MB, true, false, 42007, 406566258, 406566258,
| Use the etcdctl endpoint status command. The fifth parameter in the output table will be true for the leader.
|
Что делать, если что-то пошло не так?
| Example:
|
В процессе работы control-plane-manager оставляет резервные копии в /etc/kubernetes/deckhouse/backup , они могут помочь.
| shell
$ kubectl -n kube-system exec -ti $(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) – etcdctl \
–cacert /etc/kubernetes/pki/etcd/ca.crt –cert /etc/kubernetes/pki/etcd/ca.crt \
–key /etc/kubernetes/pki/etcd/ca.key –endpoints https://127.0.0.1:2379/ endpoint status -w table
|
Что делать, если кластер etcd развалился?
| https://10.2.1.101:2379, ade526d28b1f92f7, 3.5.3, 177 MB, false, false, 42007, 406566258, 406566258,
https://10.2.1.102:2379, d282ac2ce600c1ce, 3.5.3, 182 MB, true, false, 42007, 406566258, 406566258,
|
- Остановите (удалите
/etc/kubernetes/manifests/etcd.yaml ) etcd на всех узлах, кроме одного. С него начнется восстановление multi-master’а.
- На оставшемся узле в манифесте
/etc/kubernetes/manifests/etcd.yaml укажите параметр --force-new-cluster в spec.containers.command .
- После успешного подъема кластера удалите параметр
--force-new-cluster .
| What if something went wrong?
|
Внимание! Операция деструктивна, она полностью уничтожает консенсус и запускает etcd-кластер с состояния, которое сохранилось на узле. Любые pending-записи пропадут.
| The control-plane-manager saves backups to /etc/kubernetes/deckhouse/backup . They can be useful in diagnosing the issue.
|
Что делать, если etcd постоянно перезапускается с ошибкой?
| What if the etcd cluster fails?
|
Данный вариант может понадобиться, если --force-new-cluster не восстанавливает работу etcd. Такое может случиться при неудачном converge master-узлов, когда новый master-узел был создан со старым диском etcd, поменял свой адрес из локальной сети, и другие master-узлы отсутствуют. Симптомы, при которых стоит использовать данный способ: контейнер etcd в бесконечном рестарте, в его логе ошибка: panic: unexpected removal of unknown remote peer .
|
- Stop (delete the
/etc/kubernetes/manifests/etcd.yaml file) etcd on all nodes except one. This last node will serve as a starting point for the new multi-master cluster.
- On the last node, edit etcd manifest
/etc/kubernetes/manifests/etcd.yaml and add the parameter --force-new-cluster to spec.containers.command .
- After the new cluster is ready, remove the
--force-new-cluster parameter.
|
- Установите утилиту etcdutl.
- С текущего локального снапшота базы etcd (
/var/lib/etcd/member/snap/db ) выполните создание нового снапшота:
|
Caution! This operation is unsafe and breaks the guarantees given by the consensus protocol. Note that it brings the cluster to the state that was saved on the node. Any pending entries will be lost.
|
shell
./etcdutl snapshot restore /var/lib/etcd/member/snap/db –name \
--initial-cluster=HOSTNAME=https://<ADDRESS>:2380 --initial-advertise-peer-urls=https://ADDRESS:2380 \
--skip-hash-check=true --data-dir /var/lib/etcdtest
| What if etcd restarts with an error?
|
, где:
<HOSTNAME> — название master-узла;
<ADDRESS> — адрес master-узла.
| This method may be necessary if the --force-new-cluster option doesn’t restore etcd work. Such a scenario can occur during an unsuccessful converge of master nodes, where a new master node was created with an old etcd disk, changed its internal address, and other master nodes are absent. Symptoms indicating the need for this method include: the etcd container being stuck in an endless restart with the log showing the error: panic: unexpected removal of unknown remote peer .
|
- Выполните команды, для использования нового снапшота:
|
- Install the etcdutl utility.
- Create a new etcd database snapshot from the current local snapshot (
/var/lib/etcd/member/snap/db ):
|
shell
cp -r /var/lib/etcd /tmp/etcd-backup
rm -rf /var/lib/etcd
mv /var/lib/etcdtest /var/lib/etcd
| shell
./etcdutl snapshot restore /var/lib/etcd/member/snap/db –name \
--initial-cluster=HOSTNAME=https://<ADDRESS>:2380 --initial-advertise-peer-urls=https://ADDRESS:2380 \
--skip-hash-check=true --data-dir /var/lib/etcdtest
|
- Найдите контейнеры
etcd и api-server :
| where:
<HOSTNAME> — the name of the master node,
<ADDRESS> — the address of the master node.
|
shell
crictl ps -a | egrep “etcd|apiserver”
|
- Execute the following commands to use the new snapshot:
|
- Удалите найденные контейнеры
etcd и api-server :
| shell
cp -r /var/lib/etcd /tmp/etcd-backup
rm -rf /var/lib/etcd
mv /var/lib/etcdtest /var/lib/etcd
|
shell
crictl rm
|
- Locate the
etcd and api-server containers:
|
- Перезапустите master-узел.
| shell
crictl ps -a | egrep “etcd|apiserver”
|
Как настроить дополнительные политики аудита?
|
- Remove the
etcd and api-server containers:
|
- Включите параметр auditPolicyEnabled в настройках модуля:
| shell
crictl rm
|
yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
|
- Restart the master node.
|
- Создайте Secret
kube-system/audit-policy с YAML-файлом политик, закодированным в Base64:
|
|
yaml
apiVersion: v1
kind: Secret
metadata:
name: audit-policy
namespace: kube-system
data:
audit-policy.yaml:
|
- Enable the auditPolicyEnabled flag in the module configuration:
|
Минимальный рабочий пример audit-policy.yaml выглядит так:
| yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
|
yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
omitStages:
- RequestReceived
|
- Create the
kube-system/audit-policy Secret containing a Base64 encoded YAML file:
|
Подробную информацию по настройке содержимого audit-policy.yaml можно получить по следующим ссылкам:
| yaml
apiVersion: v1
kind: Secret
metadata:
name: audit-policy
namespace: kube-system
data:
audit-policy.yaml:
|
Как исключить встроенные политики аудита?
| The minimum viable example of the audit-policy.yaml file looks as follows:
|
Установите параметр apiserver.basicAuditPolicyEnabled модуля в false .
| yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
omitStages:
- RequestReceived
|
Пример:
| You can find the detailed information about configuring the audit-policy.yaml file at the following links:
|
yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
basicAuditPolicyEnabled: false
| How to omit Deckhouse built-in policy rules?
|
Как вывести аудит-лог в стандартный вывод вместо файлов?
| Set the apiserver.basicAuditPolicyEnabled module parameter to false .
|
Установите параметр apiserver.auditLog.output модуля в значение Stdout .
| An example:
|
Пример:
| yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
basicAuditPolicyEnabled: false
|
yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
auditLog:
output: Stdout
| How stream audit log to stdout instead of files?
|
Как работать с журналом аудита?
| Set the apiserver.auditLog.output parameter to Stdout .
|
Предполагается наличие на master-узлах «скрейпера логов» (log-shipper, promtail, filebeat), который будет следить за файлом с логами:
| An example:
|
bash
/var/log/kube-audit/audit.log
| yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
auditLog:
output: Stdout
|
Параметры ротации файла журнала предустановлены и их изменение не предусмотрено:
- Максимальное занимаемое место на диске
1000 МБ .
- Максимальная глубина записи
7 дней .
| How to deal with the audit log?
|
В зависимости от настроек политики (Policy ) и количества запросов к apiserver логов может быть очень много, соответственно глубина хранения может быть менее 30 минут.
| There must be some log scraper on master nodes (log-shipper, promtail, filebeat) that will monitor the log file:
|
Предостережение
| bash
/var/log/kube-audit/audit.log
|
Внимание! Текущая реализация функционала не является безопасной с точки зрения возможности временно сломать control plane.
Если в Secret’е с конфигурационным файлом окажутся неподдерживаемые опции или опечатка, apiserver не сможет запуститься.
| The following fixed parameters of log rotation are in use:
- The maximum disk space is limited to
1000 Mb .
- Logs older than
7 days will be deleted.
|
В случае возникновения проблем с запуском apiserver потребуется вручную отключить параметры --audit-log-* в манифесте /etc/kubernetes/manifests/kube-apiserver.yaml и перезапустить apiserver следующей командой:
| Depending on the Policy settings and the number of requests to the apiserver, the amount of logs collected may be high. Thus, in some cases, logs can only be kept for less than 30 minutes.
|
bash
docker stop $(docker ps | grep kube-apiserver- | awk ‘{print $1}’)
| Cautionary note
|
Или (в зависимости используемого вами CRI).
crictl stopp $(crictl pods –name=kube-apiserver -q)
|
*Note! The current implementation of this feature isn’t safe and may lead to a temporary failure of the control plane.
The apiserver will not be able to start if there are unsupported options or a typo in the Secret.
|
После перезапуска будет достаточно времени исправить Secret или удалить его:
| If apiserver is unable to start, you have to manually disable the --audit-log-* parameters in the /etc/kubernetes/manifests/kube-apiserver.yaml manifest and restart apiserver using the following command:
|
bash
kubectl -n kube-system delete secret audit-policy
| bash
docker stop $(docker ps | grep kube-apiserver- | awk ‘{print $1}’)
|
Как ускорить перезапуск подов при потере связи с узлом?
| Or (depending on your CRI).
crictl stopp $(crictl pods –name=kube-apiserver -q)
|
По умолчанию, если узел за 40 секунд не сообщает свое состояние, он помечается как недоступный. И еще через 5 минут поды узла начнут перезапускаться на других узлах. Итоговое время недоступности приложений около 6 минут.
| After the restart, you will be able to fix the Secret or delete it:
|
В специфических случаях, когда приложение не может быть запущено в нескольких экземплярах, есть способ сократить период их недоступности:
| bash
kubectl -n kube-system delete secret audit-policy
|
- Уменьшить время перехода узла в состояние
Unreachable при потере с ним связи настройкой параметра nodeMonitorGracePeriodSeconds .
- Установить меньший таймаут удаления подов с недоступного узла в параметре
failedNodePodEvictionTimeoutSeconds .
| How do I speed up the restart of Pods if the connection to the node has been lost?
|
Пример
| By default, a node is marked as unavailable if it does not report its state for 40 seconds. After another 5 minutes, its Pods will be rescheduled to other nodes. Thus, the overall application unavailability lasts approximately 6 minutes.
|
yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
nodeMonitorGracePeriodSeconds: 10
failedNodePodEvictionTimeoutSeconds: 50
| In specific cases, if an application cannot run in multiple instances, there is a way to lower its unavailability time:
|
В этом случае при потере связи с узлом приложения будут перезапущены через ~ 1 минуту.
|
- Reduce the period required for the node to become
Unreachable if the connection to it is lost by setting the nodeMonitorGracePeriodSeconds parameter.
- Set a lower timeout for evicting Pods on a failed node using the
failedNodePodEvictionTimeoutSeconds parameter.
|
Предостережение
| An example
|
Оба описанных параметра оказывают непосредственное влияние на потребляемые control-plane'ом ресурсы процессора и памяти. Уменьшая таймауты, мы заставляем системные компоненты чаще производить отправку статусов и сверку состояний ресурсов.
| yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
nodeMonitorGracePeriodSeconds: 10
failedNodePodEvictionTimeoutSeconds: 50
|
В процессе подбора подходящих вам значений обращайте внимание на графики потребления ресурсов управляющих узлов. Будьте готовы к тому, что чем меньшие значения параметров вы выбираете, тем больше ресурсов может потребоваться для выделения на эти узлы.
| In this case, if the connection to the node is lost, the applications will be restarted in about 1 minute.
|
Резервное копирование etcd и восстановление
| Cautionary note
|
Как сделать бэкап etcd?
| Both these parameters directly impact the CPU and memory resources consumed by the control plane. By lowering timeouts, we force system components to send statuses more frequently and check the resource state more often.
|
Войдите на любой control-plane-узел под пользователем root и используйте следующий bash-скрипт:
| When deciding on the appropriate threshold values, consider resources consumed by the control nodes (graphs can help you with this). Note that the lower parameters are, the more resources you may need to allocate to these nodes.
|
bash
| etc backup and restore
|
!/usr/bin/env bash
| How do make etcd backup?
|
pod=etcd-hostname
kubectl -n kube-system exec “$pod” – /usr/bin/etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt –cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key –endpoints https://127.0.0.1:2379/ snapshot save /var/lib/etcd/${pod##/}.snapshot &&
mv /var/lib/etcd/”${pod##/}.snapshot” etcd-backup.snapshot &&
cp -r /etc/kubernetes/ ./ &&
tar -cvzf kube-backup.tar.gz ./etcd-backup.snapshot ./kubernetes/
rm -r ./kubernetes ./etcd-backup.snapshot
| Login into any control-plane node with root user and use next script:
|
В текущей директории будет создан файл etcd-backup.snapshot со снимком базы etcd одного из членов etcd-кластера.
Из полученного снимка можно будет восстановить состояние кластера etcd.
| bash
|
Также рекомендуем сделать бэкап директории /etc/kubernetes , в которой находятся:
- манифесты и конфигурация компонентов control-plane;
- PKI кластера Kubernetes.
Данная директория поможет быстро восстановить кластер при полной потере control-plane-узлов без создания нового кластера
и без повторного присоединения узлов в новый кластер.
| !/usr/bin/env bash
|
Мы рекомендуем хранить резервные копии снимков состояния кластера etcd, а также бэкап директории /etc/kubernetes/ в зашифрованном виде вне кластера Deckhouse.
Для этого вы можете использовать сторонние инструменты резервного копирования файлов, например Restic, Borg, Duplicity и т. д.
| pod=etcd-hostname
kubectl -n kube-system exec “$pod” – /usr/bin/etcdctl –cacert /etc/kubernetes/pki/etcd/ca.crt –cert /etc/kubernetes/pki/etcd/ca.crt –key /etc/kubernetes/pki/etcd/ca.key –endpoints https://127.0.0.1:2379/ snapshot save /var/lib/etcd/${pod##/}.snapshot &&
mv /var/lib/etcd/”${pod##/}.snapshot” etcd-backup.snapshot &&
cp -r /etc/kubernetes/ ./ &&
tar -cvzf kube-backup.tar.gz ./etcd-backup.snapshot ./kubernetes/
rm -r ./kubernetes ./etcd-backup.snapshot
|
О возможных вариантах восстановления состояния кластера из снимка etcd вы можете узнать здесь.
| In the current directory etcd snapshot file etcd-backup.snapshot will be created from one of an etcd cluster members.
From this file, you can restore the previous etcd cluster state in the future.
|
Как выполнить полное восстановление состояния кластера из резервной копии etcd?
| Also, we recommend making a backup of the /etc/kubernetes directory, which contains:
- manifests and configurations of control-plane components;
- Kubernetes cluster PKI.
This directory will help to quickly restore a cluster in case of complete loss of control-plane nodes without creating a new cluster
and without rejoin the remaining nodes into the new cluster.
|
Далее будут описаны шаги по восстановлению кластера до предыдущего состояния из резервной копии при полной потере данных.
| We recommend encrypting etcd snapshot backups as well as backup of the directory /etc/kubernetes/ and saving them outside the Deckhouse cluster.
You can use one of third-party files backup tools, for example: Restic, Borg, Duplicity, etc.
|
Восстановление кластера single-master
| You can see here for learn about etcd disaster recovery procedures from snapshots.
|
Для корректного восстановления кластера single-master выполните следующие шаги:
|
|
- Загрузите утилиту etcdctl на сервер (желательно чтобы её версия была такая же, как и версия etcd в кластере).
| The following steps will be described to restore to the previous state of the cluster from a backup in case of complete data loss.
|
shell
wget “https://github.com/etcd-io/etcd/releases/download/v3.5.4/etcd-v3.5.4-linux-amd64.tar.gz”
tar -xzvf etcd-v3.5.4-linux-amd64.tar.gz && mv etcd-v3.5.4-linux-amd64/etcdctl /usr/local/bin/etcdctl
| Restoring a single-master cluster
|
Посмотреть версию etcd в кластере можно выполнив следующую команду:
| Follow these steps to restore a single-master cluster:
|
shell
kubectl -n kube-system exec -ti etcd-$(hostname) – etcdctl version
|
- Download the etcdctl utility to the server (preferably its version is the same as the etcd version in the cluster).
|
- Остановите etcd.
| shell
wget “https://github.com/etcd-io/etcd/releases/download/v3.5.4/etcd-v3.5.4-linux-amd64.tar.gz”
tar -xzvf etcd-v3.5.4-linux-amd64.tar.gz && mv etcd-v3.5.4-linux-amd64/etcdctl /usr/local/bin/etcdctl
|
shell
mv /etc/kubernetes/manifests/etcd.yaml ~/etcd.yaml
| Use the following command to view the etcd version in the cluster:
|
- Сохраните текущие данные etcd.
| shell
kubectl -n kube-system exec -ti etcd-$(hostname) – etcdctl version
|
shell
cp -r /var/lib/etcd/member/ /var/lib/deckhouse-etcd-backup
|
- Stop the etcd.
|
- Очистите директорию etcd.
| shell
mv /etc/kubernetes/manifests/etcd.yaml ~/etcd.yaml
|
shell
rm -rf /var/lib/etcd/member/
|
- Save the current etcd data.
|
- Перенесите и переименуйте резервную копию в
~/etcd-backup.snapshot .
| shell
cp -r /var/lib/etcd/member/ /var/lib/deckhouse-etcd-backup
|
- Восстановите базу данных etcd.
|
- Clean the etcd directory.
|
shell
ETCDCTL_API=3 etcdctl snapshot restore ~/etcd-backup.snapshot –cacert /etc/kubernetes/pki/etcd/ca.crt –cert /etc/kubernetes/pki/etcd/ca.crt
–key /etc/kubernetes/pki/etcd/ca.key –endpoints https://127.0.0.1:2379/ –data-dir=/var/lib/etcd
| shell
rm -rf /var/lib/etcd/member/
|
- Запустите etcd.
|
- Transfer and rename the backup to
~/etcd-backup.snapshot .
|
shell
mv ~/etcd.yaml /etc/kubernetes/manifests/etcd.yaml
|
- Restore the etcd database.
|
Восстановление кластерa multi-master
| shell
ETCDCTL_API=3 etcdctl snapshot restore ~/etcd-backup.snapshot –cacert /etc/kubernetes/pki/etcd/ca.crt –cert /etc/kubernetes/pki/etcd/ca.crt
–key /etc/kubernetes/pki/etcd/ca.key –endpoints https://127.0.0.1:2379/ –data-dir=/var/lib/etcd
|
Для корректного восстановления кластера multi-master выполните следующие шаги:
|
- Run etcd.
|
- Явно включите режим High Availability (HA) с помощью глобального параметра highAvailability. Это нужно, например, чтобы не потерять одну реплику Prometheus и её PVC, поскольку в режиме single-master HA отключен по умолчанию.
| shell
mv ~/etcd.yaml /etc/kubernetes/manifests/etcd.yaml
|
- Переведите кластер в режим single-master, в соответствии с инструкцией для облачных кластеров или самостоятельно выведите статические master-узлы из кластера.
| Restorige a multi-master cluster
|
- На оставшемся единственном master-узле выполните шаги по восстановлению etcd из резервной копии в соответствии с инструкцией для single-master.
| Follow these steps to restore a multi-master cluster:
|
- Когда работа etcd будет восстановлена, удалите из кластера информацию об уже удаленных в п.1 master-узлах, воспользовавшись следующей командой (укажите название узла):
|
- Explicitly set the High Availability (HA) mode by specifying the highAvailability parameter. This is necessary, for example, in order not to lose one Prometheus replica and its PVC, since HA is disabled by default in single-master mode.
|
shell
kubectl delete node
|
- Switch the cluster to single-master mode according to instruction for cloud clusters or independently remove static master-node from the cluster.
|
- Перезапустите все узлы кластера.
|
- On a single master-node, perform the steps to restore etcd from backup in accordance with the instructions for a single-master cluster.
|
- Дождитесь выполнения заданий из очереди Deckhouse:
|
- When etcd operation is restored, delete the information about the master nodes already deleted in step 1 from the cluster:
|
shell
kubectl -n d8-system exec svc/deckhouse-leader -c deckhouse – deckhouse-controller queue main
| shell
kubectl delete node MASTER_NODE_I
|
- Переведите кластер обратно в режим multi-master в соответствии с инструкцией для облачных кластеров или инструкцией для статических или гибридных кластеров.
|
- Restart all nodes of the cluster.
|
Как восстановить объект Kubernetes из резервной копии etcd?
|
- Wait for the deckhouse queue to complete:
|
Чтобы получить данные определенных объектов кластера из резервной копии etcd:
- Запустите временный экземпляр etcd.
- Наполните его данными из резервной копии.
- Получите описания нужных объектов с помощью
etcdhelper .
| shell
kubectl -n d8-system exec svc/deckhouse-leader -c deckhouse – deckhouse-controller queue main
|
Пример шагов по восстановлению объектов из резервной копии etcd
|
- Switch the cluster back to multi-master mode according to instructions for cloud clusters or instructions for static or hybrid clusters.
|
В примере далее etcd-snapshot.bin — резервная копия etcd (snapshot), infra-production — namespace, в котором нужно восстановить объекты.
| How do I restore a Kubernetes object from an etcd backup?
|
- Запустите под с временным экземпляром etcd.
- Подготовьте файл
etcd.pod.yaml шаблона пода, выполнив следующие команды:
| To get cluster objects data from an etcd backup, you need:
- Start an temporary instance of etcd.
- Fill it with data from the backup.
- Get desired objects using
etcdhelper .
|
shell
cat «EOF >etcd.pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: etcdrestore
namespace: default
spec:
containers:
- command:
- /bin/sh
- -c
- “sleep 96h”
image: IMAGE
imagePullPolicy: IfNotPresent
name: etcd
volumeMounts:
- name: etcddir
mountPath: /default.etcd
volumes:
- name: etcddir
emptyDir: {}
EOF
IMG=
kubectl -n kube-system get pod -l component=etcd -o jsonpath="{.items[*].spec.containers[*].image}" | cut -f 1 -d ' '
sed -i -e “s#IMAGE#$IMG#” etcd.pod.yaml
| Example of steps to restore objects from an etcd backup
|
| In the example below, etcd-snapshot.bin is a etcd shapshot, infra-production is the namespace in which objects need to be restored.
|
shell
kubectl create -f etcd.pod.yaml
|
- Start the Pod, with a temporary instance of etcd.
- Prepare the file
etcd.pod.yaml of the Pod template by executing the following commands:
|
- Скопируйте
etcdhelper и снимок etcd в контейнер пода.
| shell
cat «EOF >etcd.pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: etcdrestore
namespace: default
spec:
containers:
- command:
- /bin/sh
- -c
- “sleep 96h”
image: IMAGE
imagePullPolicy: IfNotPresent
name: etcd
volumeMounts:
- name: etcddir
mountPath: /default.etcd
volumes:
- name: etcddir
emptyDir: {}
EOF
IMG=
kubectl -n kube-system get pod -l component=etcd -o jsonpath="{.items[*].spec.containers[*].image}" | cut -f 1 -d ' '
sed -i -e “s#IMAGE#$IMG#” etcd.pod.yaml
|
etcdhelper можно собрать из исходного кода или скопировать из готового образа (например, из образа etcdhelper на Docker Hub).
|
|
Пример:
| shell
kubectl create -f etcd.pod.yaml
|
shell
kubectl cp etcd-snapshot.bin default/etcdrestore:/tmp/etcd-snapshot.bin
kubectl cp etcdhelper default/etcdrestore:/usr/bin/etcdhelper
|
- Copy the
etcdhelper and the etc snapshot into the Pod container.
|
- В контейнере установите права на запуск
etcdhelper , восстановите данные из резервной копии и запустите etcd.
| You can build etcdhelper from the source code or copy from another image (for example, from the image of etcdhelper on Docker Hub).
|
Пример:
| Example:
|
console
~ # kubectl -n default exec -it etcdrestore – sh
/ # chmod +x /usr/bin/etcdhelper
/ # etcdctl snapshot restore /tmp/etcd-snapshot.bin
/ # etcd &
| shell
kubectl cp etcd-snapshot.bin default/etcdrestore:/tmp/etcd-snapshot.bin
kubectl cp etcdhelper default/etcdrestore:/usr/bin/etcdhelper
|
- Получите описания нужных объектов кластера, отфильтровав их с помощью
grep .
|
- Set the rights to run
etcdhelper in the container, restore the data from the backup and run etcd.
|
Пример:
| Example:
|
console
~ # kubectl -n default exec -it etcdrestore – sh
/ # mkdir /tmp/restored_yaml
/ # cd /tmp/restored_yaml
/tmp/restored_yaml # for o in etcdhelper -endpoint 127.0.0.1:2379 ls /registry/ | grep infra-production ; do etcdhelper -endpoint 127.0.0.1:2379 get $o > echo $o | sed -e "s#/registry/##g;s#/#_#g" .yaml ; done
| console
~ # kubectl -n default exec -it etcdrestore – sh
/ # chmod +x /usr/bin/etcdhelper
/ # etcdctl snapshot restore /tmp/etcd-snapshot.bin
/ # etcd &
|
Замена символов с помощью sed в примере позволяет сохранить описания объектов в файлы, именованные подобно структуре реестра etcd. Например: /registry/deployments/infra-production/supercronic.yaml → deployments_infra-production_supercronic.yaml .
|
- Get necessary cluster objects by filtering them using `grep’.
|
- Скопируйте полученные описания объектов на master-узел:
| Example:
|
shell
kubectl cp default/etcdrestore:/tmp/restored_yaml restored_yaml
| console
~ # kubectl -n default exec -it etcdrestore – sh
/ # mkdir /tmp/restored_yaml
/ # cd /tmp/restored_yaml
/tmp/restored_yaml # for o in etcdhelper -endpoint 127.0.0.1:2379 ls /registry/ | grep infra-production ; do etcdhelper -endpoint 127.0.0.1:2379 get $o > echo $o | sed -e "s#/registry/##g;s#/#_#g" .yaml ; done
|
- Удалите из полученных описаний объектов информацию о времени создания, UID, status и прочие оперативные данные, после чего восстановите объекты:
| Replacing characters with sed in the example allows you to save descriptions of objects in files named similar to the etcd registry structure. For example: /registry/deployments/infra-production/supercronic.yaml → deployments_infra-production_supercronic.yaml .
|
shell
kubectl create -f restored_yaml/deployments_infra-production_supercronic.yaml
|
- Copy the received object descriptions to the master node:
|
- Удалите под с временным экземпляром etcd:
| shell
kubectl cp default/etcdrestore:/tmp/restored_yaml restored_yaml
|
shell
kubectl -n default delete pod etcdrestore
|
- Delete information about the creation time, UID, status, and other operational data from the received object descriptions, and then restore the objects:
|
Как выбирается узел, на котором будет запущен под?
| shell
kubectl create -f restored_yaml/deployments_infra-production_supercronic.yaml
|
За распределение подов по узлам отвечает планировщик Kubernetes (компонент scheduler ).
У него есть 2 фазы — Filtering и Scoring (на самом деле их больше, есть еще pre-filtering / post-filtering, но глобально можно свести к двум фазам).
|
- Delete the Pod with a temporary instance of etcd:
|
Общее устройство планировщика Kubernetes
| shell
kubectl -n default delete pod etcdrestore
|
Планировщик состоит из плагинов, которые работают в рамках какой-либо фазы (фаз).
| How the node to run the Pod on is selected
|
Примеры плагинов:
- ImageLocality — отдает предпочтение узлам, на которых уже есть образы контейнеров, которые используются в запускаемом поде. Фаза: Scoring.
- TaintToleration — реализует механизм taints and tolerations. Фазы: Filtering, Scoring.
- NodePorts — проверяет, есть ли у узла свободные порты, необходимые для запуска пода. Фаза: Filtering.
| The Kubernetes scheduler component selects the node to run the Pod on.
The selection process involves two phases, namely Filtering and Scoring. They are supposed to efficiently distribute the Pods between the nodes.
Although there are some additional phases, such as pre-filtering, post-filtering, and so on, you can safely narrow them down to the global phases mentioned above, as they merely increase flexibility and help to optimize things.
|
Полный список плагинов можно посмотреть в документации Kubernetes.
| The structure of the Kubernetes scheduler
|
Логика работы
| The Scheduler comprises plugins that function in either or both phases.
|
Сначала идет фаза фильтрации (Filtering). В этот момент работают filter -плагины, которые из всего списка узлов выбирают те, которые попадают под условия фильтров (taints , nodePorts , nodeName , unschedulable и т. д.). Если узлы лежат в разных зонах, при выборе зоны чередуются, чтобы не размещать все поды в одной зоне.
| Example of plugins:
- ImageLocality — favors nodes that already have the container images that the Pod runs. Phase: Scoring.
- TaintToleration — implements taints and tolerations. Phases: Filtering, Scoring.
- NodePorts - checks whether the ports required for the Pod to run are available on the node. Phase: Filtering.
|
Предположим, что узлы распределяются по зонам следующим образом:
| The full list of plugins is available in the Kubernetes documentation.
|
text
Zone 1: Node 1, Node 2, Node 3, Node 4
Zone 2: Node 5, Node 6
| Working logic
|
В этом случае они будут выбираться в следующем порядке:
| The selection process starts with the Filtering phase. During it, filter plugins select nodes that satisfy filter conditions such as taints , nodePorts , nodeName , unschedulable , etc.
If the nodes are in different zones, the scheduler alternates zones when selecting to ensure that all Pods will not end up in the same zone.
|
text
Node 1, Node 5, Node 2, Node 6, Node 3, Node 4
| Suppose there are two zones with the following nodes:
|
Обратите внимание, что с целью оптимизации выбираются не все попадающие под условия узлы, а только их часть. По умолчанию функция выбора количества узлов линейная. Для кластера из ≤50 узлов будут выбраны 100% узлов, для кластера из 100 узлов — 50%, а для кластера из 5000 узлов — 10%. Минимальное значение — 5% при количестве узлов более 5000. Таким образом, при настройках по умолчанию узел может не попасть в список возможных узлов для запуска. Эту логику можно изменить (см. подробнее про параметр percentageOfNodesToScore в документации Kubernetes), но Deckhouse не дает такой возможности.
| text
Zone 1: Node 1, Node 2, Node 3, Node 4
Zone 2: Node 5, Node 6
|
После того как выбраны узлы, подходящие под условия, запускается фаза Scoring. Каждый плагин анализирует список отфильтрованных узлов и назначает оценку (score) каждому узлу. Оценки от разных плагинов суммируются. На этой фазе оцениваются доступные ресурсы на узлах, pod capacity, affinity, volume provisioning и так далее. По итогам этой фазы выбирается узел с наибольшей оценкой. Если сразу несколько узлов получили максимальную оценку, узел выбирается случайным образом.
| In this case, the nodes will be selected in the following order:
|
В итоге под запускается на выбранном узле.
| text
Node 1, Node 5, Node 2, Node 6, Node 3, Node 4.
|
Документация
| Note that Kubernetes limits the number of nodes to calculate their scores during scheduling. This optimizes the selection process and prevents unnecessary scoring.
By default, the threshold is linear. For clusters with less than or equal to 50 nodes, 100% of nodes are considered for scheduling; for clusters with 100 nodes, a 50%-threshold is used; and for clusters with 5000 nodes, a 10%-threshold is used. The minimum threshold value is 5% for clusters with more than 5000 nodes. Therefore, even if all the conditions are met, a node may not be included in the list of candidates for scheduling if the default settings are used. This logic can be changed (read more about the parameter percentage Of Nodes To Score in the Kubernetes documentation), but Deckhouse does not provide such an option.
|
| The Scoring phase follows once the nodes that meet the conditions are selected. Each plugin evaluates the filtered node list and assigns a score to each node based on available resources, Pod capacity, affinity, volume provisioning, and other factors. The scores from the different plugins are then summed up and the node with the highest score is selected. If several nodes have the same score, the node is selected at random.
|
| Finally, the scheduler assigns the Pod to the node with the highest ranking.
|
| Documentation
|
|
|