K8s kubectl Глубокое погружение
В моей предыдущей статье kubectl я показал вам, как использовать его для получения информации о кластере, apiVersion, а также информации о API-ресурсах. В этой статье давайте продолжим работу с узлами.
Для данного узла K8s обычно работают три компонента:
- kubelet: агент, который регистрирует/отменяет регистрацию узла с помощью API Kubernetes.
- Среда выполнения контейнера: механизм выполнения контейнера.
- kube-proxy: процесс сетевого прокси K8s.
Как администратор K8s, вам много раз нужно устранять неполадки, почему определенный узел не может запускать модули, получать информацию об узле в кластере, добавлять новый узел, заменять существующий узел и т. д. В этой статье позвольте мне показать вам все операции узла с помощью инструмента kubectl.
Список узлов
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-62-238.ec2.internal Ready <none> 85m v1.24.7-eks-fb459a0
Описать узел
$ kubectl describe node ip-192-168-62-238.ec2.internal Name: ip-192-168-62-238.ec2.internal Roles: <none> Labels: alpha.eksctl.io/cluster-name=dev-cluster alpha.eksctl.io/nodegroup-name=standard-workers beta.kubernetes.io/arch=amd64 beta.kubernetes.io/instance-type=t3.medium beta.kubernetes.io/os=linux eks.amazonaws.com/capacityType=ON_DEMAND eks.amazonaws.com/nodegroup=standard-workers eks.amazonaws.com/nodegroup-image=ami-0c84934009677b6d5 eks.amazonaws.com/sourceLaunchTemplateId=lt-0768d4e5bac8456db eks.amazonaws.com/sourceLaunchTemplateVersion=1 failure-domain.beta.kubernetes.io/region=us-east-1 failure-domain.beta.kubernetes.io/zone=us-east-1c k8s.io/cloud-provider-aws=494fdbb3e67643238cbc864a5ef9986c kubernetes.io/arch=amd64 kubernetes.io/hostname=ip-192-168-62-238.ec2.internal kubernetes.io/os=linux node.kubernetes.io/instance-type=t3.medium topology.kubernetes.io/region=us-east-1 topology.kubernetes.io/zone=us-east-1c Annotations: alpha.kubernetes.io/provided-node-ip: 192.168.62.238 node.alpha.kubernetes.io/ttl: 0 volumes.kubernetes.io/controller-managed-attach-detach: true CreationTimestamp: Mon, 19 Dec 2022 00:36:51 +0000 Taints: <none> Unschedulable: false Lease: HolderIdentity: ip-192-168-62-238.ec2.internal ... Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 325m (16%) 0 (0%) memory 140Mi (4%) 340Mi (10%) ephemeral-storage 0 (0%) 0 (0%) hugepages-1Gi 0 (0%) 0 (0%) hugepages-2Mi 0 (0%) 0 (0%) attachable-volumes-aws-ebs 0 0 Events: <none>
Показать использование узла
Иногда полезно знать, какие ресурсы потребляются узлами. Чтобы отобразить ресурсы, используемые узлами, выполните следующую команду:
$ kubectl top node NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% ip-192-168-23-112.ec2.internal 39m 2% 484Mi 14% ip-192-168-40-6.ec2.internal 39m 2% 503Mi 15%
Команда kubectl top
показывает метрики узла по использованию ЦП и памяти. Вы также можете использовать команду watch
для просмотра и мониторинга узлов в режиме реального времени, если вам нужно:
$ watch kubectl top nodes Every 2.0s: kubectl top nodes Sat Dec 24 19:35:53 2022 NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% ip-192-168-23-112.ec2.internal 39m 2% 486Mi 14% ip-192-168-40-6.ec2.internal 37m 1% 503Mi 15%
Отключить планирование узлов
Иногда мы хотим временно предотвратить назначение новых модулей на определенный узел, вы можете использовать параметр cordon
. Параметр cordon
позволяет пометить узел K8s как незапланированный.
$ kubectl cordon -h Mark node as unschedulable. Examples: # Mark node "foo" as unschedulable kubectl cordon foo Options: --dry-run='none': Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. -l, --selector='': Selector (label query) to filter on Usage: kubectl cordon NODE [options] Use "kubectl options" for a list of global command-line options (applies to all commands).
Давайте попробуем, мы видим, что кластер K8s в настоящее время имеет два доступных узла:
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-23-112.ec2.internal Ready <none> 10m v1.23.13-eks-fb459a0 ip-192-168-40-6.ec2.internal Ready <none> 10m v1.23.13-eks-fb459a0
Давайте отметим узел ip-192–168–40–6.ec2.internal
с помощью cordon
:
$ $ kubectl cordon ip-192-168-40-6.ec2.internal node/ip-192-168-40-6.ec2.internal cordoned
Теперь, если мы снова проверим доступность узлов:
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-23-112.ec2.internal Ready <none> 12m v1.23.13-eks-fb459a0 ip-192-168-40-6.ec2.internal Ready,SchedulingDisabled <none> 12m v1.23.13-eks-fb459a0
Обратите внимание, что теперь статус узла ip-192–168–40–6.ec2.internal
показывает «Готово, расписание отключено». Этот переключатель cordon
удобен, когда вы хотите быстро запустить некоторые тесты в своем кластере K8s, но не хотите влиять на критические узлы.
Примечание. Если заблокированный узел будет перезагружен, все запланированные на нем модули будут перенесены на другие узлы.
Чтобы возобновить его, вы можете использовать команду kubectl uncordon
:
$ kubectl uncordon ip-192-168-40-6.ec2.internal node/ip-192-168-40-6.ec2.internal uncordoned $ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-23-112.ec2.internal Ready <none> 14m v1.23.13-eks-fb459a0 ip-192-168-40-6.ec2.internal Ready <none> 14m v1.23.13-eks-fb459a0
Сливные узлы
Если вы хотите переместить все запущенные поды с узла для обслуживания узла, вы можете использовать команду drain
. kubectl drain
истощит заданный узел в рамках подготовки к обслуживанию.
drain
ожидает корректного завершения. Вы не должны работать на машине, пока команда не завершится. Когда вы будете готовы вернуть узел в эксплуатацию, используйте kubectl uncordon
, что снова сделает узел планируемым.
Давайте создадим несколько Nginx
подов в нашем кластере:
$ kubectl get po -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-74d589986c-2h98c 1/1 Running 0 7s 192.168.62.163 ip-192-168-40-6.ec2.internal <none> <none> nginx-74d589986c-2tnfc 1/1 Running 0 7s 192.168.22.109 ip-192-168-23-112.ec2.internal <none> <none> nginx-74d589986c-5bs67 1/1 Running 0 7s 192.168.53.226 ip-192-168-40-6.ec2.internal <none> <none> nginx-74d589986c-65cxz 1/1 Running 0 7s 192.168.11.223 ip-192-168-23-112.ec2.internal <none> <none> nginx-74d589986c-bjd2d 1/1 Running 0 7s 192.168.58.226 ip-192-168-40-6.ec2.internal <none> <none> nginx-74d589986c-q8kn4 1/1 Running 0 7s 192.168.25.25 ip-192-168-23-112.ec2.internal <none> <none>
У нас есть 6 Nginx
подов, работающих на двух разных узлах, давайте возьмем один из узлов:
$ kubectl drain ip-192-168-40-6.ec2.internal --dry-run='client' node/ip-192-168-40-6.ec2.internal cordoned (dry run) error: unable to drain node "ip-192-168-40-6.ec2.internal" due to error:[cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/aws-node-hh78n, kube-system/kube-proxy-xq4kl, cannot delete Pods with local storage (use --delete-emptydir-data to override): kube-system/coredns-d5b9bfc4-bcb97, kube-system/coredns-d5b9bfc4-f4w9w], continuing command... There are pending nodes to be drained: ip-192-168-40-6.ec2.internal cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/aws-node-hh78n, kube-system/kube-proxy-xq4kl cannot delete Pods with local storage (use --delete-emptydir-data to override): kube-system/coredns-d5b9bfc4-bcb97, kube-system/coredns-d5b9bfc4-f4w9w
Как видите, поскольку на узле работает DaemonSet
, мы не можем его слить.
$ kubectl get po kube-proxy-xq4kl -n kube-system -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-proxy-xq4kl 1/1 Running 0 24m 192.168.40.6 ip-192-168-40-6.ec2.internal <none> <none>
В этом случае мы должны использовать флаг --ignore-daemonsets
:
$ kubectl drain ip-192-168-40-6.ec2.internal --dry-run='client' --ignore-daemonsets node/ip-192-168-40-6.ec2.internal already cordoned (dry run) WARNING: ignoring DaemonSet-managed Pods: kube-system/aws-node-hh78n, kube-system/kube-proxy-xq4kl evicting pod default/nginx-74d589986c-2h98c (dry run) evicting pod default/nginx-74d589986c-5bs67 (dry run) evicting pod default/nginx-74d589986c-bjd2d (dry run) evicting pod kube-system/coredns-d5b9bfc4-bcb97 (dry run) evicting pod kube-system/coredns-d5b9bfc4-f4w9w (dry run) node/ip-192-168-40-6.ec2.internal drained (dry run)
Теперь давайте удалим флаг --dry-run
и фактически истощим его:
$ $ kubectl drain ip-192-168-40-6.ec2.internal --ignore-daemonsets node/ip-192-168-40-6.ec2.internal already cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/aws-node-hh78n, kube-system/kube-proxy-xq4kl evicting pod kube-system/coredns-d5b9bfc4-f4w9w evicting pod default/nginx-74d589986c-5bs67 evicting pod default/nginx-74d589986c-bjd2d evicting pod kube-system/coredns-d5b9bfc4-bcb97 evicting pod default/nginx-74d589986c-2h98c pod/nginx-74d589986c-bjd2d evicted pod/nginx-74d589986c-5bs67 evicted pod/coredns-d5b9bfc4-bcb97 evicted pod/nginx-74d589986c-2h98c evicted pod/coredns-d5b9bfc4-f4w9w evicted node/ip-192-168-40-6.ec2.internal drained $ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-23-112.ec2.internal Ready <none> 27m v1.23.13-eks-fb459a0 ip-192-168-40-6.ec2.internal Ready,SchedulingDisabled <none> 27m v1.23.13-eks-fb459a0
Теперь вы можете начать обслуживание этого узла.
Удалить узлы
Вы можете использовать команду kubectl delete
для удаления узла из кластера K8s.
$ kubectl delete node ip-192-168-40-6.ec2.internal node "ip-192-168-40-6.ec2.internal" deleted $ kubectl get node NAME STATUS ROLES AGE VERSION ip-192-168-23-112.ec2.internal Ready <none> 30m v1.23.13-eks-fb459a0