|
|
Как добавить 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-узлы в облачном кластере?
| How do I add master nodes to a cloud cluster?
|
Далее описана конвертация кластера с одним master-узлом в мультимастерный кластер.
| The following describes the conversion of a single-master cluster into 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.
|
- В контейнере с инсталлятором выполните следующую команду и укажите требуемое количество master-узлов в параметре
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, при использовании внешних адресов на master-узлах, количество элементов массива в параметре masterNodeGroup.instanceClass.externalIPAddresses должно равняться количеству master-узлов. При использовании значения Auto (автоматический заказ публичных IP-адресов), количество элементов в массиве все равно должно соответствовать количеству master-узлов.
Например, при трех master-узлах (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-узлов в облачном кластере?
| How do I reduce the number of master nodes in a cloud cluster?
|
Далее описана конвертация мультимастерного кластера в кластер с одним master-узлом.
| The following describes the conversion of a multi-master cluster into a single-master.
|
Описанные ниже шаги необходимо выполнять с первого по порядку master-узла кластера (master-0). Это связано с тем, что кластер всегда масштабируется по порядку: например, невозможно удалить узлы master-0 и master-1, оставив master-2.
| The steps described below must be performed from the first in order of the master node of the cluster (master-0). This is because the cluster is always scaled in order: for example, it is impossible to delete nodes master-0 and master-1, leaving master-2.
|
- Сделайте резервную копию
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
|
Для Yandex Cloud при использовании внешних адресов на master-узлах количество элементов массива в параметре masterNodeGroup.instanceClass.externalIPAddresses должно равняться количеству master-узлов. При использовании значения Auto (автоматический заказ публичных IP-адресов) количество элементов в массиве все равно должно соответствовать количеству master-узлов.
Например, при одном master-узле (masterNodeGroup.replicas: 1 ) и автоматическом заказе адресов параметр masterNodeGroup.instanceClass.externalIPAddresses будет выглядеть следующим образом:
yaml
externalIPAddresses:
| The command output should indicate that Terraform found no inconsistencies and no changes are required.
|
- Снимите следующие лейблы с удаляемых master-узлов:
node-role.kubernetes.io/control-plane
node-role.kubernetes.io/master
node.deckhouse.io/group
|
- Run the following command in the installer container and set
masterNodeGroup.replicas to 1 :
|
Команда для снятия лейблов:
| bash
dhctl config edit provider-cluster-configuration –ssh-agent-private-keys=/tmp/.ssh/ \
--ssh-user= --ssh-host
|
bash
kubectl label node node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master- node.deckhouse.io/group-
|
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: 1 ) and automatic address reservation, the masterNodeGroup.instanceClass.externalIPAddresses parameter would look as follows:
yaml
externalIPAddresses:
|
- Убедитесь, что удаляемые 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 json | jq -r ‘.items[] | select( .status.conditions[] | select(.type == “ContainersReady” and .status == “True”)) | .metadata.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-role.kubernetes.io/control-plane
node-role.kubernetes.io/master
node.deckhouse.io/group
|
- 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
kubectl label node node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master- node.deckhouse.io/group-
| How do I dismiss the master role while keeping the node?
|
- Убедитесь, что удаляемый master-узел пропал из списка узлов кластера:
|
- 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 following labels:
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 json | jq -r ‘.items[] | select( .status.conditions[] | select(.type == “ContainersReady” and .status == “True”)) | .metadata.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:
|
- Зайдите на узел и выполните следующие команды:
| bash
kubectl label node node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master- node.deckhouse.io/group-
|
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 sure that the master node to be deleted is no longer listed as a member of the etcd cluster:
|
| 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
|
Как изменить образ ОС в мультимастерном кластере?
|
- Exec to the node and run the following commands:
|
- Сделайте резервную копию
etcd и папки /etc/kubernetes .
- Скопируйте полученный архив за пределы кластера (например, на локальную машину).
- Убедитесь, что в кластере нет алертов, которые могут помешать обновлению master-узлов.
- Убедитесь, что очередь Deckhouse пуста.
- На локальной машине запустите контейнер установщика Deckhouse соответствующей редакции и версии (измените адрес container registry при необходимости):
| 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/
|
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
| How do I switch to a different OS image in a multi-master cluster?
|
- В контейнере с инсталлятором выполните следующую команду, чтобы проверить состояние перед началом работы:
|
- 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
dhctl terraform check –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
| 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
|
Ответ должен сообщить, что Terraform не нашел расхождений и изменений не требуется.
|
- In the installer container, run the following command to check the state before working:
|
- В контейнере с инсталлятором выполните следующую команду и укажите необходимый образ ОС в параметре
masterNodeGroup.instanceClass (укажите адреса всех master-узлов в параметре --ssh-host ):
| bash
dhctl terraform check –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
|
bash
dhctl config edit provider-cluster-configuration –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
| The command output should indicate that Terraform found no inconsistencies and no changes are required.
|
- В контейнере с инсталлятором выполните следующую команду, чтобы провести обновление узлов:
|
- 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):
|
Внимательно изучите действия, которые планирует выполнить converge, когда запрашивает подтверждение.
| bash
dhctl config edit provider-cluster-configuration –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
|
При выполнении команды узлы будут замены на новые с подтверждением на каждом узле. Замена будет выполняться по очереди в обратном порядке (2,1,0).
|
- Select the master node to update (enter its name):
|
bash
dhctl converge –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
| bash
NODE=”"
|
Следующие действия (П. 9-12) выполняйте поочередно на каждом master-узле, начиная с узла с наивысшим номером (с суффиксом 2) и заканчивая узлом с наименьшим номером (с суффиксом 0).
|
- 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:
|
- На созданном узле откройте журнал systemd-юнита
bashible.service . Дождитесь окончания настройки узла — в журнале должно появиться сообщение nothing to do :
| bash
kubectl label node ${NODE}
node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master- node.deckhouse.io/group-
|
bash
journalctl -fu bashible.service
|
- Make sure that the node is no longer listed as an etcd cluster member:
|
- Проверьте, что узел etcd отобразился в списке узлов кластера:
| bash
kubectl -n kube-system exec -ti
$(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o json | jq -r ‘.items[] | select( .status.conditions[] | select(.type == “ContainersReady” and .status == “True”)) | .metadata.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
kubectl -n kube-system exec -ti
$(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o json | jq -r ‘.items[] | select( .status.conditions[] | select(.type == “ContainersReady” and .status == “True”)) | .metadata.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
|
- In the installer container, run the following command to perform nodes upgrade:
|
- Убедитесь, что
control-plane-manager функционирует на узле.
| You should read carefully what converge is going to do when it asks for approval.
|
bash
kubectl -n kube-system wait pod –timeout=10m –for=condition=ContainersReady
-l app=d8-control-plane-manager –field-selector spec.nodeName=
| When the command is executed, the nodes will be replaced by new nodes with confirmation on each node. The replacement will be performed one by one in reverse order (2,1,0).
|
- Перейдите к обновлению следующего узла.
| bash
dhctl converge –ssh-agent-private-keys=/tmp/.ssh/ --ssh-user= \
--ssh-host --ssh-host --ssh-host
|
| Repeat the steps below (Sec. 9-12) 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).
|
Как изменить образ ОС в кластере с одним master-узлом?
|
- 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):
|
- Преобразуйте кластер с одним master-узлом в мультимастерный в соответствии с инструкцией.
- Обновите master-узлы в соответствии с инструкцией.
- Преобразуйте мультимастерный кластер в кластер с одним master-узлом в соответствии с инструкцией
| bash
journalctl -fu bashible.service
|
|
- Make sure the node is listed as an etcd cluster member:
|
Как посмотреть список узлов кластера в etcd?
| bash
kubectl -n kube-system exec -ti
$(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o json | jq -r ‘.items[] | select( .status.conditions[] | select(.type == “ContainersReady” and .status == “True”)) | .metadata.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
|
Вариант 1
|
- Make sure
control-plane-manager is running on the node:
|
Используйте команду etcdctl member list .
| bash
kubectl -n kube-system wait pod –timeout=10m –for=condition=ContainersReady
-l app=d8-control-plane-manager –field-selector spec.nodeName=${NODE}
|
Пример:
|
- Proceed to update the next node (repeat the steps above).
|
shell
kubectl -n kube-system exec -ti
$(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o json | jq -r ‘.items[] | select( .status.conditions[] | select(.type == “ContainersReady” and .status == “True”)) | .metadata.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
| How do I switch to a different OS image in a single-master cluster?
|
Внимание. Последний параметр в таблице вывода показывает, что узел находится в состоянии learner , а не в состоянии leader .
|
- 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.
|
Вариант 2
| How do I view the list of etcd members?
|
Используйте команду etcdctl endpoint status . Для этой команды, после флага --endpoints нужно подставить адрес каждого узла control-plane. В пятом столбце таблицы вывода будет указано значение true для лидера.
| Option 1
|
Пример скрипта, который автоматически передает все адреса узлов control-plane:
| Use the etcdctl member list command.
|
shell
MASTER_NODE_IPS=($(kubectl get nodes -l
node-role.kubernetes.io/control-plane=””
-o ‘custom-columns=IP:.status.addresses[?(@.type==”InternalIP”)].address’
–no-headers))
unset ENDPOINTS_STRING
for master_node_ip in ${MASTER_NODE_IPS[@]}
do ENDPOINTS_STRING+=”–endpoints https://${master_node_ip}:2379 “
done
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
$(echo -n $ENDPOINTS_STRING) endpoint status -w table
| Example:
|
Что делать, если что-то пошло не так?
| shell
kubectl -n kube-system exec -ti
$(kubectl -n kube-system get pod -l component=etcd,tier=control-plane -o json | jq -r ‘.items[] | select( .status.conditions[] | select(.type == “ContainersReady” and .status == “True”)) | .metadata.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
|
В процессе работы control-plane-manager автоматически создает резервные копии конфигурации и данных, которые могут пригодиться в случае возникновения проблем. Эти резервные копии сохраняются в директории /etc/kubernetes/deckhouse/backup . Если в процессе работы возникли ошибки или непредвиденные ситуации, вы можете использовать эти резервные копии для восстановления до предыдущего исправного состояния.
| Warning. The last parameter in the output table shows etcd member is in learner state, is not in leader state.
|
| Option 2
|
Что делать, если кластер etcd не функционирует?
| Use the etcdctl endpoint status command. For this command, every control-plane address must be passed after --endpoints flag.
The fifth parameter in the output table will be true for the leader.
|
Если кластер etcd не функционирует и не удается восстановить его из резервной копии, вы можете попытаться восстановить его с нуля, следуя шагам ниже.
| Example of a script that automatically passes all control-plane nodes to the command:
|
- Сначала на всех узлах, которые являются частью вашего кластера etcd, кроме одного, удалите манифест
etcd.yaml , который находится в директории /etc/kubernetes/manifests/ . После этого только один узел останется активным, и с него будет происходить восстановление состояния мультимастерного кластера.
- На оставшемся узле откройте файл манифеста
etcd.yaml и укажите параметр --force-new-cluster в spec.containers.command .
- После успешного восстановления кластера, удалите параметр
--force-new-cluster .
| shell
MASTER_NODE_IPS=($(kubectl get nodes -l
node-role.kubernetes.io/control-plane=””
-o ‘custom-columns=IP:.status.addresses[?(@.type==”InternalIP”)].address’
–no-headers))
unset ENDPOINTS_STRING
for master_node_ip in ${MASTER_NODE_IPS[@]}
do ENDPOINTS_STRING+=”–endpoints https://${master_node_ip}:2379 “
done
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
$(echo -n $ENDPOINTS_STRING) endpoint status -w table
|
Эта операция является деструктивной, так как она полностью уничтожает текущие данные и инициализирует кластер с состоянием, которое сохранено на узле. Все pending-записи будут утеряны.
| What if something went wrong?
|
Что делать, если etcd постоянно перезапускается с ошибкой?
| During its operation, control-plane-manager automatically creates backups of configurations and data that may be useful in case of issues. These backups are stored in the /etc/kubernetes/deckhouse/backup directory. If errors or unforeseen situations occur during operation, you can use these backups to restore to the previous stable state.
|
Этот способ может понадобиться, если использование параметра --force-new-cluster не восстанавливает работу etcd. Это может произойти, если converge master-узлов прошел неудачно, в результате чего новый master-узел был создан на старом диске etcd, изменил свой адрес в локальной сети, а другие master-узлы отсутствуют. Этот метод стоит использовать если контейнер etcd находится в бесконечном цикле перезапуска, а в его логах появляется ошибка: panic: unexpected removal of unknown remote peer .
| What if the etcd cluster fails?
|
- Установите утилиту etcdutl.
- С текущего локального снапшота базы etcd (
/var/lib/etcd/member/snap/db ) выполните создание нового снапшота:
| If the etcd cluster is not functioning and it cannot be restored from a backup, you can attempt to rebuild it from scratch by following the steps below.
|
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
|
- First, on all nodes that are part of your etcd cluster, except for one, remove the
etcd.yaml manifest located in the /etc/kubernetes/manifests/ directory. 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.
|
<HOSTNAME> — название master-узла;
<ADDRESS> — адрес master-узла.
| 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.
|
- Выполните следующие команды для использования нового снапшота:
| What if etcd restarts with an error?
|
shell
cp -r /var/lib/etcd /tmp/etcd-backup
rm -rf /var/lib/etcd
mv /var/lib/etcdtest /var/lib/etcd
| 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 .
|
- Найдите контейнеры
etcd и api-server :
|
- Install the etcdutl utility.
- Create a new etcd database snapshot from the current local snapshot (
/var/lib/etcd/member/snap/db ):
|
shell
crictl ps -a | egrep “etcd|apiserver”
| 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 :
|
<HOSTNAME> — the name of the master node;
<ADDRESS> — the address of the master node.
|
shell
crictl rm
|
- Execute the following commands to use the new snapshot:
|
- Перезапустите master-узел.
| shell
cp -r /var/lib/etcd /tmp/etcd-backup
rm -rf /var/lib/etcd
mv /var/lib/etcdtest /var/lib/etcd
|
Как настроить дополнительные политики аудита?
|
- Locate the
etcd and api-server containers:
|
- Включите параметр auditPolicyEnabled в настройках модуля:
| shell
crictl ps -a | egrep “etcd|apiserver”
|
yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
|
- Remove the
etcd and api-server containers:
|
- Создайте Secret
kube-system/audit-policy с YAML-файлом политик, закодированным в Base64:
| shell
crictl rm
|
yaml
apiVersion: v1
kind: Secret
metadata:
name: audit-policy
namespace: kube-system
data:
audit-policy.yaml:
|
- Restart the master node.
|
Минимальный рабочий пример audit-policy.yaml выглядит так:
|
|
yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
omitStages:
- RequestReceived
|
- 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
|
Как исключить встроенные политики аудита?
|
- Create the
kube-system/audit-policy Secret containing a Base64 encoded YAML file:
|
Установите параметр apiserver.basicAuditPolicyEnabled модуля в false .
| 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:
|
yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
basicAuditPolicyEnabled: false
| yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
omitStages:
- RequestReceived
|
Как вывести аудит-лог в стандартный вывод вместо файлов?
| You can find detailed information on how to configure audit-policy.yaml file here:
|
Установите параметр apiserver.auditLog.output модуля в значение Stdout .
| How to omit Deckhouse built-in policy rules?
|
Пример:
| Set the apiserver.basicAuditPolicyEnabled module parameter to false .
|
yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
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
|
Предполагается, что на master-узлах установлен «скрейпер логов»: log-shipper, promtail , filebeat , который будет мониторить файл с логами:
| How to stream audit log to stdout instead of files?
|
bash
/var/log/kube-audit/audit.log
| Set the apiserver.auditLog.output parameter to Stdout .
|
Параметры ротации логов в файле журнала предустановлены и их изменение не предусмотрено:
| An example:
|
- Максимальное занимаемое место на диске
1000 МБ .
- Максимальная глубина записи
7 дней .
| yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
apiserver:
auditPolicyEnabled: true
auditLog:
output: Stdout
|
В зависимости от настроек политики (Policy ) и количества запросов к apiserver логов может быть очень много, соответственно глубина хранения может быть менее 30 минут.
| How to deal with the audit log?
|
Текущая реализация функционала не гарантирует безопасность, так как существует риск временного нарушения работы control plane.
| There must be some log scraper on master nodes (log-shipper, promtail, filebeat) that will monitor the log file:
|
Если в Secret’е с конфигурационным файлом окажутся неподдерживаемые опции или опечатка, apiserver не сможет запуститься.
| bash
/var/log/kube-audit/audit.log
|
В случае возникновения проблем с запуском apiserver , потребуется вручную отключить параметры --audit-log-* в манифесте /etc/kubernetes/manifests/kube-apiserver.yaml и перезапустить apiserver следующей командой:
| The following fixed parameters of log rotation are in use:
|
bash
docker stop $(docker ps | grep kube-apiserver- | awk ‘{print $1}’)
|
- The maximum disk space is limited to
1000 Mb .
- Logs older than
7 days will be deleted.
|
Или (в зависимости используемого вами CRI).
crictl stopp $(crictl pods –name=kube-apiserver -q)
| 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.
|
После перезапуска будет достаточно времени исправить Secret или удалить его:
| The current implementation of this feature isn’t safe and may lead to a temporary failure of the control plane.
|
bash
kubectl -n kube-system delete secret audit-policy
| The apiserver will not be able to start if there are unsupported options or a typo in the 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:
|
По умолчанию, если узел в течении 40 секунд не сообщает свое состояние, он помечается как недоступный. И еще через 5 минут поды узла начнут перезапускаться на других узлах. В итоге общее время недоступности приложений составляет около 6 минут.
| bash
docker stop $(docker ps | grep kube-apiserver- | awk ‘{print $1}’)
|
В специфических случаях, когда приложение не может быть запущено в нескольких экземплярах, есть способ сократить период их недоступности:
| Or (depending on your CRI).
crictl stopp $(crictl pods –name=kube-apiserver -q)
|
- Уменьшить время перехода узла в состояние
Unreachable при потере с ним связи настройкой параметра nodeMonitorGracePeriodSeconds .
- Установить меньший таймаут удаления подов с недоступного узла в параметре
failedNodePodEvictionTimeoutSeconds .
| After the restart, you will be able to fix the Secret or delete it:
|
Пример:
| bash
kubectl -n kube-system delete secret audit-policy
|
yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
nodeMonitorGracePeriodSeconds: 10
failedNodePodEvictionTimeoutSeconds: 50
| How do I speed up the restart of Pods if the connection to the node has been lost?
|
В этом случае при потере связи с узлом приложения будут перезапущены примерно через 1 минуту.
| 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.
|
Оба упомянутых параметра напрямую влияют на использование процессора и памяти control-plane’ом. Снижая таймауты, системные компоненты чаще отправляют статусы и проверяют состояние ресурсов.
| In specific cases, if an application cannot run in multiple instances, there is a way to lower its unavailability time:
|
При выборе оптимальных значений учитывайте графики использования ресурсов управляющих узлов. Чем меньше значения параметров, тем больше ресурсов может понадобиться для их обработки на этих узлах.
|
- 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.
|
Резервное копирование и восстановление etcd
| Example:
|
Что выполняется автоматически
| yaml
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: control-plane-manager
spec:
version: 1
settings:
nodeMonitorGracePeriodSeconds: 10
failedNodePodEvictionTimeoutSeconds: 50
|
Автоматически запускаются CronJob kube-system/d8-etcd-backup-* в 00:00 по UTC+0. Результат сохраняется в /var/lib/etcd/etcd-backup.tar.gz на всех узлах с control-plane в кластере (master-узлы).
| In this case, if the connection to the node is lost, the applications will be restarted in about 1 minute.
|
| 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.
|
Как сделать резервную копию etcd вручную
| 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.
|
| etcd backup and restore
|
Начиная с релиза Deckhouse Kubernetes Platform v1.65, стала доступна утилита d8 backup etcd , которая предназначена для быстрого создания снимков состояния etcd.
| What is done automatically
|
bash
d8 backup etcd –kubeconfig $KUBECONFIG ./etcd-backup.snapshot
| CronJob kube-system/d8-etcd-backup-* is automatically started at 00:00 UTC+0. The result is saved in /var/lib/etcd/etcd-backup.tar.gz on all nodes with control-plane in the cluster (master nodes).
|
| How to manually backup etcd
|
Войдите на любой control-plane узел под пользователем root и используйте следующий bash-скрипт:
|
|
bash
| Starting with Deckhouse Kubernetes Platform v1.65, a new d8 backup etcd tool is available for taking snapshots of etcd state.
|
!/usr/bin/env bash
set -e
| bash
d8 backup etcd –kubeconfig $KUBECONFIG ./etcd-backup.snapshot
|
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
|
|
В текущей директории будет создан файл kube-backup.tar.gz со снимком базы etcd одного из узлов кластера.
Из полученного снимка можно будет восстановить состояние кластера.
| Login into any control-plane node with root user and use next script:
|
Рекомендуем сделать резервную копию директории /etc/kubernetes , в которой находятся:
| bash
|
| !/usr/bin/env bash
set -e
|
Данная директория поможет быстро восстановить кластер при полной потере control-plane узлов без создания нового кластера и без повторного присоединения узлов в новый кластер.
| 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, а также резервную копию директории /etc/kubernetes/ в зашифрованном виде вне кластера Deckhouse.
Для этого вы можете использовать сторонние инструменты резервного копирования файлов, например Restic, Borg, Duplicity и т.д.
| In the current directory etcd snapshot file kube-backup.tar.gz 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:
|
Как выполнить полное восстановление состояния кластера из резервной копии etcd?
|
|
Далее описаны шаги по восстановлению кластера до предыдущего состояния из резервной копии при полной потере данных.
| 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.
|
Восстановление кластера с одним master-узлом
| You can see documentation for learn about etcd disaster recovery procedures from snapshots.
|
Для корректного восстановления выполните следующие шаги на master-узле:
|
|
- Найдите утилиту
etcdctl на master-узле и скопируйте исполняемый файл в /usr/local/bin/ :
| 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
cp $(find /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/
-name etcdctl -print | tail -n 1) /usr/local/bin/etcdctl
etcdctl version
| Restoring a single-master cluster
|
Должен отобразиться корректный вывод etcdctl version без ошибок.
| Follow these steps to restore a single-master cluster on master node:
|
Также вы можете загрузить исполняемый файл etcdctl на сервер (желательно, чтобы версия etcdctl была такая же, как и версия etcd в кластере):
|
- Find
etcdctl utility on the master-node and copy the executable to /usr/local/bin/ :
|
shell
wget “https://github.com/etcd-io/etcd/releases/download/v3.5.16/etcd-v3.5.16-linux-amd64.tar.gz”
tar -xzvf etcd-v3.5.16-linux-amd64.tar.gz && mv etcd-v3.5.16-linux-amd64/etcdctl /usr/local/bin/etcdctl
| shell
cp $(find /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/
-name etcdctl -print | tail -n 1) /usr/local/bin/etcdctl
etcdctl version
|
Проверить версию etcd в кластере можно выполнив следующую команду (команда может не сработать, если etcd и Kubernetes API недоступны):
| The result must be a correct output of etcdctl version command without errors.
|
shell
kubectl -n kube-system exec -ti etcd-$(hostname) – etcdctl version
| Alternatively, you can download etcdctl executable to the node (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.16/etcd-v3.5.16-linux-amd64.tar.gz”
tar -xzvf etcd-v3.5.16-linux-amd64.tar.gz && mv etcd-v3.5.16-linux-amd64/etcdctl /usr/local/bin/etcdctl
|
shell
mv /etc/kubernetes/manifests/etcd.yaml ~/etcd.yaml
| You can check current etcd version using following command (might not work, if etcd and Kubernetes API are already unavailable):
|
- Сохраните текущие данные 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 в файл
~/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. Запуск может занять некоторое время.
|
- Put the etcd backup to
~/etcd-backup.snapshot file.
|
shell
mv ~/etcd.yaml /etc/kubernetes/manifests/etcd.yaml
crictl ps –label io.kubernetes.pod.name=etcd-$HOSTNAME
|
- Restore the etcd database.
|
| 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
|
Восстановление мультимастерного кластера
|
- Run etcd. The process may take some time.
|
Для корректного восстановления выполните следующие шаги:
| shell
mv ~/etcd.yaml /etc/kubernetes/manifests/etcd.yaml
crictl ps –label io.kubernetes.pod.name=etcd-$HOSTNAME
|
- Включите режим High Availability (HA) с помощью глобального параметра highAvailability. Это необходимо для сохранения хотя бы одной реплики Prometheus и его PVC, поскольку в режиме кластера с одним master-узлом HA по умолчанию отключён.
| Restoring a multi-master cluster
|
- Переведите кластер в режим с одним master-узлом в соответствии с инструкцией для облачных кластеров, или самостоятельно выведите статические master-узлы из кластера.
| Follow these steps to restore a multi-master cluster:
|
- На оставшемся единственном master-узле выполните шаги по восстановлению etcd из резервной копии в соответствии с инструкцией для кластера с одним 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.
|
- Когда работа etcd будет восстановлена, удалите из кластера информацию об уже удаленных в первом пункте master-узлах, воспользовавшись следующей командой (укажите название узла):
|
- Switch the cluster to single-master mode according to instruction for cloud clusters or independently remove static master-node from the cluster.
|
shell
kubectl delete node
|
- On a single master-node, perform the steps to restore etcd from backup in accordance with the instructions for a single-master cluster.
|
- Перезапустите все узлы кластера.
|
- When etcd operation is restored, delete the information about the master nodes already deleted in step 1 from the cluster:
|
- Дождитесь выполнения заданий из очереди Deckhouse:
| shell
kubectl delete node MASTER_NODE_I
|
shell
kubectl -n d8-system exec svc/deckhouse-leader -c deckhouse – deckhouse-controller queue main
|
- Restart all nodes of the cluster.
|
- Переведите кластер обратно в режим мультимастерного в соответствии с инструкцией для облачных кластеров или инструкцией для статических или гибридных кластеров.
|
- Wait for the deckhouse queue to complete:
|
Как восстановить объект Kubernetes из резервной копии etcd?
| 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.
- Заполните его данными из резервной копии.
- Получите описания нужных объектов с помощью
auger .
| How do I restore a Kubernetes object from an etcd backup?
|
Пример шагов по восстановлению объектов из резервной копии etcd
| To get cluster objects data from an etcd backup, you need:
|
В следующем примере etcd-backup.snapshot — резервная копия etcd (snapshot), infra-production — пространство имен, в котором нужно восстановить объекты.
|
- Start an temporary instance of etcd.
- Fill it with data from the backup.
- Get desired objects using
auger .
|
- Для выгрузки бинарных данных из etcd потребуется утилита auger. Ее можно собрать из исходного кода на любой машине с Docker (на узлах кластера это сделать невозможно).
| Example of steps to restore objects from an etcd backup
|
shell
git clone -b v1.0.1 –depth 1 https://github.com/etcd-io/auger
cd auger
make release
build/auger -h
- Получившийся исполняемый файл
build/auger , а также snapshot из резервной копии etcd нужно загрузить на master-узел, с которого будет выполняться дальнейшие действия.
| In the example below, etcd-backup.snapshot is a etcd shapshot, infra-production is the namespace in which objects need to be restored.
|
Данные действия выполняются на master-узле в кластере, на который предварительно был загружен файл snapshot и утилита auger :
|
- To decode objects from
etcd you would need auger. It can be built from source on any machine that has Docker installed (it cannot be done on cluster nodes).
|
- Установите полный путь до
snapshot и до утилиты в переменных окружения:
| shell
git clone -b v1.0.1 –depth 1 https://github.com/etcd-io/auger
cd auger
make release
build/auger -h
- Resulting executable
build/auger , and also the snapshot from the backup copy of etcd must be uploaded on master-node, on which following actions would be performed.
|
shell
SNAPSHOT=/root/etcd-restore/etcd-backup.snapshot
AUGER_BIN=/root/auger
chmod +x $AUGER_BIN
| Following actions are performed on a master node, to which etcd snapshot file and auger tool were copied:
|
- Запустите под с временным экземпляром etcd:
|
- Set full path for snapshot file and for the tool into environmental variables:
|
- Создайте манифест пода. Он будет запускаться именно на текущем master-узле, выбрав его по переменной
$HOSTNAME , и смонтирует snapshot по пути $SNAPSHOT для загрузки во временный экземпляр etcd:
| shell
SNAPSHOT=/root/etcd-restore/etcd-backup.snapshot
AUGER_BIN=/root/auger
chmod +x $AUGER_BIN
|
shell
cat «EOF >etcd.pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: etcdrestore
namespace: default
spec:
nodeName: $HOSTNAME
tolerations:
- operator: Exists
initContainers:
- command:
- etcdctl
- snapshot
- restore
- “/tmp/etcd-snapshot”
image: $(kubectl -n kube-system get pod -l component=etcd -o jsonpath=”{.items[].spec.containers[].image}” | cut -f 1 -d ‘ ‘)
imagePullPolicy: IfNotPresent
name: etcd-snapshot-restore
volumeMounts:
- name: etcddir
mountPath: /default.etcd
- name: etcd-snapshot
mountPath: /tmp/etcd-snapshot
readOnly: true
containers:
- command:
- etcd
image: $(kubectl -n kube-system get pod -l component=etcd -o jsonpath=”{.items[].spec.containers[].image}” | cut -f 1 -d ‘ ‘)
imagePullPolicy: IfNotPresent
name: etcd-temp
volumeMounts:
- name: etcddir
mountPath: /default.etcd
volumes:
- name: etcddir
emptyDir: {}
- name: etcd-snapshot
hostPath:
path: $SNAPSHOT
type: File
EOF
|
- Run a Pod with temporary instance of
etcd .
- Create Pod manifest. It should schedule on current master node by
$HOSTNAME variable, and mounts snapshot file by $SNAPSHOT variable, which it then restores in temporary etcd instance:
|
| shell
cat «EOF >etcd.pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: etcdrestore
namespace: default
spec:
nodeName: $HOSTNAME
tolerations:
- operator: Exists
initContainers:
- command:
- etcdctl
- snapshot
- restore
- “/tmp/etcd-snapshot”
image: $(kubectl -n kube-system get pod -l component=etcd -o jsonpath=”{.items[].spec.containers[].image}” | cut -f 1 -d ‘ ‘)
imagePullPolicy: IfNotPresent
name: etcd-snapshot-restore
volumeMounts:
- name: etcddir
mountPath: /default.etcd
- name: etcd-snapshot
mountPath: /tmp/etcd-snapshot
readOnly: true
containers:
- command:
- etcd
image: $(kubectl -n kube-system get pod -l component=etcd -o jsonpath=”{.items[].spec.containers[].image}” | cut -f 1 -d ‘ ‘)
imagePullPolicy: IfNotPresent
name: etcd-temp
volumeMounts:
- name: etcddir
mountPath: /default.etcd
volumes:
- name: etcddir
emptyDir: {}
- name: etcd-snapshot
hostPath:
path: $SNAPSHOT
type: File
EOF
|
shell
kubectl create -f etcd.pod.yaml
|
- Create Pod from the resulting manifest:
|
- Установите нужные переменные. В текущем примере:
| shell
kubectl create -f etcd.pod.yaml
|
infra-production - пространство имен, в котором мы будем искать ресурсы.
|
- Set environment variables. In this example:
|
/root/etcd-restore/output - каталог для восстановленных манифестов.
|
infra-production - namespace which we will search resources in.
|
/root/auger - путь до исполняемого файла утилиты auger :
|
/root/etcd-restore/output - path for outputting recovered resource manifests.
|
shell
FILTER=infra-production
BACKUP_OUTPUT_DIR=/root/etcd-restore/output
mkdir -p $BACKUP_OUTPUT_DIR && cd $BACKUP_OUTPUT_DIR
|
/root/auger - path to auger executable.
|
- Следующие команды отфильтруют список нужных ресурсов по переменной
$FILTER и выгрузят их в каталог $BACKUP_OUTPUT_DIR :
| shell
FILTER=infra-production
BACKUP_OUTPUT_DIR=/root/etcd-restore/output
mkdir -p $BACKUP_OUTPUT_DIR && cd $BACKUP_OUTPUT_DIR
|
shell
files=($(kubectl -n default exec etcdrestore -c etcd-temp – etcdctl –endpoints=localhost:2379 get / –prefix –keys-only | grep “$FILTER”))
for file in “${files[@]}”
do
OBJECT=$(kubectl -n default exec etcdrestore -c etcd-temp – etcdctl –endpoints=localhost:2379 get “$file” –print-value-only | $AUGER_BIN decode)
FILENAME=$(echo $file | sed -e “s#/registry/##g;s#/#_#g”)
echo “$OBJECT” > “$BACKUP_OUTPUT_DIR/$FILENAME.yaml”
echo $BACKUP_OUTPUT_DIR/$FILENAME.yaml
done
|
- Commands below will filter needed resources by
$FILTER and output them into $BACKUP_OUTPUT_DIR directory:
|
- Удалите из полученных описаний объектов информацию о времени создания (
creationTimestamp ), UID , status и прочие оперативные данные, после чего восстановите объекты:
| shell
files=($(kubectl -n default exec etcdrestore -c etcd-temp – etcdctl –endpoints=localhost:2379 get / –prefix –keys-only | grep “$FILTER”))
for file in “${files[@]}”
do
OBJECT=$(kubectl -n default exec etcdrestore -c etcd-temp – etcdctl –endpoints=localhost:2379 get “$file” –print-value-only | $AUGER_BIN decode)
FILENAME=$(echo $file | sed -e “s#/registry/##g;s#/#_#g”)
echo “$OBJECT” > “$BACKUP_OUTPUT_DIR/$FILENAME.yaml”
echo $BACKUP_OUTPUT_DIR/$FILENAME.yaml
done
|
bash
kubectl create -f deployments_infra-production_supercronic.yaml
|
- From resulting
yaml files, delete creationTimestamp , UID , status and other operational fields, and then restore the objects:
|
- Удалите под с временным экземпляром etcd:
| bash
kubectl create -f deployments_infra-production_supercronic.yaml
|
bash
kubectl -n default delete pod etcdrestore
|
- Delete the Pod with a temporary instance of etcd:
|
Как выбирается узел, на котором будет запущен под?
| bash
kubectl -n default delete pod etcdrestore
|
За распределение подов по узлам отвечает планировщик Kubernetes (компонент scheduler ).
Он проходит через две основные фазы — Filtering и Scoring (на самом деле, фаз больше, например, pre-filtering и post-filtering , но в общем можно выделить две ключевые фазы).
| How the node to run the Pod on is selected
|
Общее устройство планировщика Kubernetes
| 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.
|
- ImageLocality — отдает предпочтение узлам, на которых уже есть образы контейнеров, которые используются в запускаемом поде. Фаза:
Scoring .
- TaintToleration — реализует механизм taints and tolerations. Фазы:
Filtering , Scoring .
- NodePorts — проверяет, есть ли у узла свободные порты, необходимые для запуска пода. Фаза:
Filtering .
| The structure of the Kubernetes scheduler
|
С полным списком плагинов можно ознакомиться в документации Kubernetes.
| The Scheduler comprises plugins that function in either or both phases.
|
Логика работы
| 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.
|
default-scheduler — профиль по умолчанию, который распределяет поды на узлы с наименьшей загрузкой;
high-node-utilization — профиль, при котором поды размещаются на узлах с наибольшей загрузкой.
| Working logic
|
Чтобы задать профиль планировщика, укажите его параметре spec.schedulerName манифеста пода.
| Scheduler profiles
|
Пример использования профиля:
| There are two predefined scheduler profiles:
|
yaml
apiVersion: v1
kind: Pod
metadata:
name: scheduler-example
labels:
name: scheduler-example
spec:
schedulerName: high-node-utilization
containers:
- name: example-pod
image: registry.k8s.io/pause:2.0
|
default-scheduler : The default profile that distributes pods to nodes with the lowest load;
high-node-utilization : A profile that places pods on nodes with the highest load.
|
Этапы планирования подов
| To specify a scheduler profile, use the spec.schedulerName parameter in the pod manifest.
|
На первой фазе — Filtering — активируются плагины фильтрации (filter-плагины), которые из всех доступных узлов выбирают те, которые удовлетворяют определенным условиям фильтрации (например, taints , nodePorts , nodeName , unschedulable и другие). Если узлы расположены в разных зонах, планировщик чередует выбор зон, чтобы избежать размещения всех подов в одной зоне.
| Example of using a profile:
|
Предположим, что узлы распределяются по зонам следующим образом:
| yaml
apiVersion: v1
kind: Pod
metadata:
name: scheduler-example
labels:
name: scheduler-example
spec:
schedulerName: high-node-utilization
containers:
- name: example-pod
image: registry.k8s.io/pause:2.0
|
text
Zone 1: Node 1, Node 2, Node 3, Node 4
Zone 2: Node 5, Node 6
| Pod scheduling stages
|
В этом случае они будут выбираться в следующем порядке:
| 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. Таким образом, при настройках по умолчанию узел может не попасть в список возможных узлов для запуска.
| text
Zone 1: Node 1, Node 2, Node 3, Node 4
Zone 2: Node 5, Node 6
|
Эту логику можно изменить (см. подробнее про параметр percentageOfNodesToScore в документации Kubernetes), но Deckhouse не дает такой возможности.
| In this case, the nodes will be selected in the following order:
|
После того как были выбраны узлы, соответствующие условиям фильтрации, запускается фаза Scoring . Каждый плагин анализирует список отфильтрованных узлов и назначает оценку (score) каждому узлу. Оценки от разных плагинов суммируются. На этой фазе оцениваются доступные ресурсы на узлах: pod capacity , affinity , volume provisioning и другие. По итогам этой фазы выбирается узел с наибольшей оценкой. Если сразу несколько узлов получили максимальную оценку, узел выбирается случайным образом.
| 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
|
Для изменения логики работы планировщика можно использовать механизм плагинов расширения.
|
|
Каждый плагин представляет собой вебхук, отвечающий следующим требованиям:
| How to change or extend the scheduler logic
|
- Использование TLS.
- Доступность через сервис внутри кластера.
- Поддержка стандартных
Verbs (filterVerb = filter , prioritizeVerb = prioritize ).
- Также, предполагается что все подключаемые плагины могут кэшировать информацию об узле (
nodeCacheCapable: true ).
| To change the logic of the scheduler it is possible to use the extension mechanism Extenders.
|
Подключить extender можно при помощи ресурса KubeSchedulerWebhookConfiguration.
| Each plugin is a webhook that must satisfy the following requirements:
|
При использовании опции failurePolicy: Fail , в случае ошибки в работе вебхука планировщик Kubernetes прекратит свою работу, и новые поды не смогут быть запущены.
|
- Use of TLS.
- Accessibility through a service within the cluster.
- Support for standard
Verbs (filterVerb = filter , prioritizeVerb = prioritize ).
- It is also assumed that all plugins can cache node information (
nodeCacheCapable: true ).
|
Как происходит ротация сертификатов kubelet?
| You can connect an extender using KubeSchedulerWebhookConfiguration resource.
|
С настройкой и включением ротации сертификатов kubelet вы можете ознакомиться в официальной документации Kubernetes.
| When using the failurePolicy: Fail option, in case of an error in the webhook’s operation, the scheduler will stop working and new pods will not be able to start.
|
В файле /var/lib/kubelet/config.yaml хранится конфигурация kubelet и указывается путь к сертификату (tlsCertFile ) и закрытому ключу (tlsPrivateKeyFile ).
| How does kubelet certificate rotation work?
|
В kubelet реализована следующая логика работы с серверными сертификатами:
| You can read about configuring and enabling kubelet certificate rotation in the official Kubernetes documentation.
|
- Если
tlsCertFile и tlsPrivateKeyFile не пустые, то kubelet будет использовать их как сертификат и ключ по умолчанию.
- При запросе клиента в kubelet API с указанием IP-адреса (например https://10.1.1.2:10250/), для установления соединения по TLS-протоколу будет использован закрытый ключ по умолчанию (
tlsPrivateKeyFile ). В данном случае ротация сертификатов не будет работать.
- При запросе клиента в kubelet API с указанием названия хоста (например https://k8s-node:10250/), для установления соединения по TLS-протоколу будет использован динамически сгенерированный закрытый ключ из директории
/var/lib/kubelet/pki/ . В данном случае ротация сертификатов будет работать.
- Если
tlsCertFile и tlsPrivateKeyFile пустые, то для установления соединения по TLS-протоколу будет использован динамически сгенерированный закрытый ключ из директории /var/lib/kubelet/pki/ . В данном случае ротация сертификатов будет работать.
| The /var/lib/kubelet/config.yaml file contains the kubelet configuration and specifies the path to the certificate (tlsCertFile ) and private key (tlsPrivateKeyFile ).
|
Поскольку в Deckhouse Kubernetes Platform для запросов в kubelet API используются IP-адреса, то в конфигурации kubelet поля tlsCertFile и tlsPrivateKeyFile не используются, а используется динамический сертификат, который kubelet генерирует самостоятельно. Также в модуле operator-trivy отключены проверки CIS benchmark AVD-KCV-0088 и AVD-KCV-0089 , которые отслеживают, были ли переданы аргументы --tls-cert-file и --tls-private-key-file для kubelet.
| Kubelet handles server certificates using the following logic:
- If
tlsCertFile and tlsPrivateKeyFile are not empty, kubelet will use them as the default certificate and key.
- When a client requests the kubelet API by specifying an IP address (e.g. https://10.1.1.2:10250/), the default private key (
tlsPrivateKeyFile ) will be used to establish a TLS connection. In this case, certificate rotation will not work.
- When a client requests the kubelet API by specifying a host name (e.g. https://k8s-node:10250/), a dynamically generated private key from the
/var/lib/kubelet/pki/ directory will be used to establish a TLS connection. In this case, certificate rotation will work.
|
Kubelet использует клиентский TLS сертификат(/var/lib/kubelet/pki/kubelet-client-current.pem ), при помощи которого может запросить у kube-apiserver новый клиентский сертификат или новый серверный сертификат(/var/lib/kubelet/pki/kubelet-server-current.pem ).
|
- If
tlsCertFile and tlsPrivateKeyFile are empty, a dynamically generated private key from the /var/lib/kubelet/pki/ directory will be used to establish the TLS connection. In this case, certificate rotation will work.
|
Когда до истечения времени жизни сертификата остается 5-10% (случайное значение из диапазона) времени, kubelet запрашивает у kube-apiserver новый сертификат. С описанием алгоритма ознакомьтесь в официальной документации Kubernetes.
| Since Deckhouse Kubernetes Platform uses IP addresses to make requests to the kubelet API, the kubelet configuration does not use the tlsCertFile and tlsPrivateKeyFile fields, but uses a dynamic certificate that kubelet generates itself. Also, the CIS benchmark AVD-KCV-0088 and AVD-KCV-0089 checks, which track whether the --tls-cert-file and --tls-private-key-file arguments were passed to kubelet, are disabled in the operator-trivy module.
|
Чтобы kubelet успел установить сертификат до его истечения, рекомендуем устанавливать время жизни сертификатов более, чем 1 час. Время устанавливается с помощью аргумента --cluster-signing-duration в манифесте /etc/kubernetes/manifests/kube-controller-manager.yaml . По умолчанию это значение равно 1 году (8760 часов).
| The kubelet uses a client TLS certificate (/var/lib/kubelet/pki/kubelet-client-current.pem ) with which it can request a new client certificate or a new server certificate (/var/lib/kubelet/pki/kubelet-server-current.pem ) from kube-apiserver.
|
Если истекло время жизни клиентского сертификата, то kubelet не сможет делать запросы к kube-apiserver и не сможет обновить сертификаты. В данном случае узел (Node) будет помечен как NotReady и пересоздан.
| When there is 5-10% (random value from the range) of time left before the certificate expires, kubelet requests a new certificate from kube-apiserver. For a description of the algorithm, see the official Kubernetes documentation.
|
Как вручную обновить сертификаты компонентов управляющего слоя?
| To ensure that kubelet has time to install the certificate before it expires, we recommend setting the certificate lifetime to more than 1 hour. The time is set using the --cluster-signing-duration argument in the /etc/kubernetes/manifests/kube-controller-manager.yaml manifest. By default, this value is 1 year (8760 hours).
|
Может возникнуть ситуация, когда master-узлы кластера находятся в выключенном состоянии долгое время. За это время может истечь срок действия сертификатов компонентов управляющего слоя. После включения узлов сертификаты не обновятся автоматически, поэтому это необходимо сделать вручную.
| If the client certificate lifetime has expired, kubelet will not be able to make requests to kube-apiserver and will not be able to renew certificates. In this case, the node will be marked as NotReady and recreated.
|
Обновление сертификатов компонентов управляющего слоя происходит с помощью утилиты kubeadm .
Чтобы обновить сертификаты, выполните следующие действия на каждом master-узле:
| How to manually update control plane component certificates?
|
- Найдите утилиту
kubeadm на master-узле и создайте символьную ссылку c помощью следующей команды:
| There may be a situation when the cluster’s master nodes are powered off for an extended period. During this time, the control plane component certificates may expire. After the nodes are powered back on, the certificates will not update automatically and must be renewed manually.
|
shell
ln -s $(find /var/lib/containerd -name kubeadm -type f -executable -print) /usr/bin/kubeadm
| Control plane component certificates are updated using the kubeadm utility.
To update the certificates, do the following on each master node:
|
- Обновите сертификаты:
|
- Find the
kubeadm utility on the master node and create a symbolic link using the following command:
|
shell
kubeadm certs renew all
| shell
ln -s $(find /var/lib/containerd -name kubeadm -type f -executable -print) /usr/bin/kubeadm
|
|
- Update the certificates:
|
| shell
kubeadm certs renew all
|