Оглавление
1.k8s механизм просмотра списка
1.1 Введение в механизм просмотра списков
1.2 В соответствии с механизмом просмотра списка процесс создания модуля
2. Стратегия планирования планировщика
2.1 Введение в стратегию планирования планировщика
2.2 Алгоритм предварительного выбора стратегии Планировщика
2.3 Алгоритм стратегии оптимизации планировщика
3. Управление тегами в k8s и метод планирования nodeSelector и nodeName
3.2. Получить справку по лейблу
3.3 Необходимо получить имя NAME на узле
3.4 Установите метки для соответствующих узлов как lbj=a и lbj=b соответственно.
3.6 Изменение метода планирования nodeSelector
3.7 Просмотр подробностей событий
(1) Настройка проверки жесткой стратегии привязки узлов
(2) Операционная связь «ключ-значение»
Поэкспериментируйте с жесткими настройками политики:
Поэкспериментируйте с настройками мягкой политики:
4.2 Сродство и антисродство подов
4.3 Использование планирования антисходства Pod
5.3 Основные операции по удалению пятен
(1) Проверьте пятно на узле узла.
5.4. Перед лицом пятен создайте настройки допуска для ресурсов модуля.
6. Интерпретация статуса и навыки устранения неполадок на этапе запуска модуля.
6.1 Статус фазы запуска модуля (фаза)
6.2 Действия по устранению неполадок кластера k8
1.k8s механизм просмотра списка
1.1 Введение в механизм просмотра списков
Kubernetes использует механизм List-Watch для взаимодействия с каждым компонентом для поддержания синхронизации данных, а конструкция между каждым компонентом обеспечивает разделение.
Пользователи отправляют команды APIServer через kubectl в соответствии с файлом конфигурации для создания подов и контейнеров на узлах Node.
APIServer прошел процесс вызова API, управления разрешениями, вызова ресурсов и хранения ресурсов, но фактически не начал развертывание приложений. Для завершения всего процесса развертывания необходима помощь Controller Manager, Scheduler и kubelet.
В Kubernetes вся информация о развертывании записывается в etcd и сохраняется . Фактически, когда etcd сохраняет информацию о развертывании, он отправляет событие Create на APIServer, а APIServer будет прослушивать (отслеживать) события, отправленные etcd. Другие компоненты также будут отслеживать (Watch) события, отправленные APIServer.
1.2 В соответствии с механизмом просмотра списка процесс создания модуля
(1) Здесь есть три List-Watches, а именно диспетчер контроллера (работает на Master), планировщик (работает на Master) и kubelet (работает на узле). Они будут прослушивать (наблюдать) события, отправленные APIServer после запуска процесса.
(2) Пользователи отправляют запросы к APIServer через kubectl или другие клиенты API, чтобы создать копию объекта Pod.
(3) APIServer пытается сохранить соответствующую метаинформацию объекта Pod в etcd. После завершения операции записи APIServer вернет клиенту подтверждающую информацию.
(4) Когда etcd примет информацию о создании пода, он отправит событие Create на APIServer.
(5) Поскольку диспетчер контроллера прослушивал (отслеживание через порт 6443 https) событий на APIServer. В это время APIServer получает событие Create и отправляет его диспетчеру контроллеров.
(6) После получения события Create диспетчер контроллера вызывает контроллер репликации, чтобы убедиться в количестве копий, которые необходимо создать на узле. Как только количество реплик станет меньше числа, определенного в RC, RC автоматически создаст реплики. Короче говоря, это Контроллер, гарантирующий количество копий (PS: отвечающий за расширение и сжатие).
(7) После того, как диспетчер контроллеров создаст копию модуля, APIServer запишет подробную информацию о модуле в etcd. Например, количество копий Пода и содержимого Контейнера.
(8) Тот же etcd отправит информацию о создании пода на APIServer через события.
(9) Поскольку Планировщик контролирует (наблюдает) за API-сервером и играет роль «соединения верхнего и нижнего» в системе, «соединение верхнего» означает, что он отвечает за получение созданных событий Pod и организацию узлов. для них «подключение нижних» означает: после завершения работ по размещению процесс kubelet на Ноде возьмет на себя последующую работу и будет отвечать за «вторую половину» жизненного цикла Пода. Другими словами, роль планировщика заключается в привязке пода, который будет запланирован, к узлу в кластере в соответствии с алгоритмом и политикой планирования.
(10) Планировщик обновит информацию о модуле после завершения планирования, и информация в это время будет более подробной. Помимо знания количества реплик Pod, необходимо узнать содержимое реплик. Вы также знаете, на каком узле выполнять развертывание. И обновите указанную выше информацию о Pod на API-сервере, обновите ее до etcd с APIServer и сохраните.
(11) etcd отправляет успешно обновленное событие на APIServer, и APIServer также начинает отражать результаты планирования этого объекта Pod.
(12) Kubelet — это процесс, работающий на узле. Он также прослушивает через List-Watch (отслеживание через порт 6443 https) события обновления Pod, отправленные APIServer. Кубелет попытается вызвать Docker на текущем узле, чтобы запустить контейнер, и отправит полученный статус пода и контейнера обратно на APIServer.
(13) APIServer хранит информацию о состоянии модуля в etcd. После того, как etcd подтвердит, что операция записи завершилась успешно, APIServer отправляет подтверждающее сообщение соответствующему кубелету, через который событие будет принято.
Примечание. Почему кубелет продолжает слушать после завершения работы по созданию пода? Причина очень проста: если kubectl в это время выдаст команду на увеличение количества копий Pod, то описанный выше процесс запустится снова, и kubelet скорректирует ресурсы Node в соответствии с последним развертыванием Pod. А может быть, количество копий Pod не изменилось, но файл образа в нем обновился, и kubelet автоматически получит последний файл образа и загрузит его.
2. Стратегия планирования планировщика
2.1 Введение в стратегию планирования планировщика
Scheduler — планировщик kubernetes, его основная задача — распределить определенные поды по узлам кластера. Основные рассматриваемые вопросы:
● Справедливость: как гарантировать, что каждому узлу могут быть выделены ресурсы.
● Эффективное использование ресурсов: все ресурсы в кластере максимально используются.
● Эффективность: производительность планирования должна быть хорошей, и можно использовать большое количество модулей. запланировано как можно быстрее. Работает
● Гибко: позволяет пользователям управлять логикой планирования в соответствии со своими потребностями.
Sheduler запускается как отдельная программа. После запуска он всегда будет прослушивать APIServer, получать поды, у которых spec.nodeName пуст, и создавать привязку для каждого пода, чтобы указать, на каком узле следует разместить под.
Планирование делится на несколько частей: сначала отфильтровывание узлов, не соответствующих условиям, этот процесс называется бюджетной стратегией (предикатом); затем сортировка проходящих узлов по приоритету, это приоритетная стратегия (приоритеты); и, наконец, сортировка проходящих узлов по приоритету. выбор приоритетов.Высший узел. Если на каком-либо из промежуточных шагов возникнет ошибка, ошибка будет возвращена напрямую.
2.2 Алгоритм предварительного выбора стратегии Планировщика
●PodFitsResources: превышают ли оставшиеся ресурсы на узле ресурс odeName, запрошенный модулем, проверьте, соответствует ли имя узла NodeName. .
●PodFitsHost: если для модуля указано N.
●PodFitsHostPorts: конфликтует ли порт, уже используемый на узле, с портом, к которому применяется модуль.
●PodSelectorMatches: отфильтровывать узлы, не соответствующие метке, указанной модулем.
●NoDiskConflict: подключенный том не конфликтует с томом, указанным модулем, если только они оба не доступны только для чтения.
Если во время процесса предиката не будет подходящего узла, модуль останется в состоянии ожидания и продолжит повторять попытки планирования до тех пор, пока узел не будет соответствовать условиям. После этого шага, если есть несколько узлов, соответствующих условиям, продолжите процесс определения приоритетов: отсортируйте узлы в соответствии с их приоритетом.
2.3 Алгоритм стратегии оптимизации планировщика
●LeastRequestedPriority: вес определяется путем расчета использования ЦП и памяти.Чем ниже использование, тем выше вес. Другими словами, этот индикатор приоритета отдает предпочтение узлам с более низким коэффициентом использования ресурсов.
●BalancedResourceAllocation: чем ближе степень использования ЦП и памяти на узле, тем выше вес. Обычно это используется вместе с вышеперечисленным, а не отдельно. Например, использование ЦП и памяти узла 01 составляет 20:60, а использование ЦП и памяти узла 02 — 50:50. Хотя общее использование ЦП и памяти узла 01 ниже, чем у узла 02, использование ЦП и памяти узла 02 ближе , поэтому при планировании предпочтение будет отдано узлу 02. .
●ImageLocalityPriority: как правило, уже есть узлы, которые хотят использовать зеркала. Чем больше общий размер зеркала, тем выше вес.
3. Управление тегами в k8s и метод планирования nodeSelector и nodeName
3.1 Укажите узел планирования
●pod.spec.nodeName планирует работу модуля непосредственно на указанном узле узла, минуя политику планирования планировщика. Это правило сопоставления является обязательным.
vim myapp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
nodeName: node01
containers:
- name: myapp
image: soscscs/myapp:v1
ports:
- containerPort: 80
kubectl apply -f myapp.yaml
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-6bc58d7775-6wlpp 1/1 Running 0 14s 10.244.1.25 node01 <none> <none>
myapp-6bc58d7775-szcvp 1/1 Running 0 14s 10.244.1.26 node01 <none> <none>
myapp-6bc58d7775-vnxlp 1/1 Running 0 14s 10.244.1.24 node01 <none> <none>
//查看详细事件(发现未经过 scheduler 调度分配)
kubectl describe pod myapp-6bc58d7775-6wlpp
......
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulled 95s kubelet, node01 Container image "soscscs/myapp:v1" already present on machine
Normal Created 99s kubelet, node01 Created container nginx
Normal Started 99s kubelet, node01 Started container nginx
●pod.spec.nodeSelector: выберите узлы с помощью механизма выбора метки Kubernetes. Планировщик планирует политику, соответствующую метке, а затем планирует Pod для целевого узла. Это правило сопоставления является обязательным ограничением.
3.2. Получить справку по лейблу
kubectl label --help
Usage:
kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version] [options]
3.3 Необходимо получить имя NAME на узле
kubectl get node
AME STATUS ROLES AGE VERSION
master Ready master 30h v1.20.11
node01 Ready <none> 30h v1.20.11
node02 Ready <none> 30h v1.20.11
3.4 Установите метки для соответствующих узлов как lbj=a и lbj=b соответственно.
kubectl label nodes node01 lbj=a
kubectl label nodes node02 lbj=b
3.5 Просмотр тегов
kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master Ready master 30h v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
node01 Ready <none> 30h v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kgc=a,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux
node02 Ready <none> 30h v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kgc=b,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux
3.6 Изменение метода планирования nodeSelector
vim myapp1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp1
spec:
replicas: 3
selector:
matchLabels:
app: myapp1
template:
metadata:
labels:
app: myapp1
spec:
nodeSelector:
kgc: a
containers:
- name: myapp1
image: soscscs/myapp:v1
ports:
- containerPort: 80
kubectl apply -f myapp1.yaml
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp1-58cff4d75-52xm5 1/1 Running 0 24s 10.244.1.29 node01 <none> <none>
myapp1-58cff4d75-f747q 1/1 Running 0 24s 10.244.1.27 node01 <none> <none>
myapp1-58cff4d75-kn8gk 1/1 Running 0 24s 10.244.1.28 node01 <none> <none>
3.7 Просмотр подробностей событий
kubectl describe pod myapp1-58cff4d75-52xm5
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 57s default-scheduler Successfully assigned default/myapp1-58cff4d75-52xm5 to node01
Normal Pulled 57s kubelet, node01 Container image "soscscs/myapp:v1" already present on machine
Normal Created 56s kubelet, node01 Created container myapp1
Normal Started 56s kubelet, node01 Started container myapp1
//修改一个 label 的值,需要加上 --overwrite 参数
kubectl label nodes node02 kgc=a --overwrite
//删除一个 label,只需在命令行最后指定 label 的 key 名并与一个减号相连即可:
kubectl label nodes node02 kgc-
//指定标签查询 node 节点
kubectl get node -l kgc=
4. Близость
Официальная ссылка на обучение: https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node/
Что касается методов планирования сходства, их можно разделить на три категории: сходство узлов, сходство модулей и антисходство модулей. Все они могут играть роль в управлении результатами планирования распределения модулей по узлам.
#查看亲和性的种类
kubectl explain pod.spec.affinity
4.1 привязка узлов
Существует две стратегии планирования привязки узлов: мягкая стратегия (preferredDuringSchedulingIgnoredDuringExecution) и жесткая стратегия (requiredDuringSchedulingIgnoredDuringExecution).
#查看你node亲和性的调度策略
kubectl explain pod.spec.affinity.nodeAffinity
(1) Настройка проверки жесткой стратегии привязки узлов
#硬策略的设置方式
kubectl explain pod.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms
#硬策略的标签设置方式
kubectl explain pod.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions
(2) Операционная связь «ключ-значение»
●In: значение метки находится на рассмотрении в определенном списке.
●NotIn: значение метки отсутствует в определенном списке.
●Gt: значение метки больше определенного значения.
●Lt: значение метки меньше a. определенное значение
●Exists: определенная метка существует.
●DoesNotExist: определенная метка не существует.
Поэкспериментируйте с жесткими настройками политики:
Перед экспериментом мы добавили метки test=a и test=b к узлам node01 и node02 соответственно.
kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master Ready master 11d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
node01 Ready <none> 11d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux
node02 Ready <none> 11d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux
//requiredDuringSchedulingIgnoredDuringExecution:硬策略
mkdir /opt/affinity
cd /opt/affinity
vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname #指定node的标签
operator: NotIn #设置Pod安装到kubernetes.io/hostname的标签值不在values列表中的node上
values::
- node02
kubectl apply -f pod1.yaml
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity 1/1 Running 0 13s 10.244.1.30 node01 <none> <none>
kubectl delete pod --all && kubectl apply -f pod1.yaml && kubectl get pods -o wide
#如果硬策略不满足条件,Pod 状态一直会处于 Pending 状态。
Поэкспериментируйте с настройками мягкой политики:
//preferredDuringSchedulingIgnoredDuringExecution:软策略
vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1 #如果有多个软策略选项的话,权重越大,优先级越高
preference:
matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node03
kubectl apply -f pod2.yaml
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity 1/1 Running 0 5s 10.244.2.35 node02 <none> <none>
//把values:的值改成node01,则会优先在node01上创建Pod
kubectl delete pod --all && kubectl apply -f pod2.yaml && kubectl get pods -o wide
//如果把硬策略和软策略合在一起使用,则要先满足硬策略之后才会满足软策略
//示例:
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: #先满足硬策略,排除有kubernetes.io/hostname=node02标签的节点
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values:
- node02
preferredDuringSchedulingIgnoredDuringExecution: #再满足软策略,优先选择有kgc=a标签的节点
- weight: 1
preference:
matchExpressions:
- key: lbj
operator: In
values:
- a
4.2 Сродство и антисродство подов
调度策略 匹配标签 操作符 拓扑域支持 调度目标
nodeAffinity 主机 In, NotIn, Exists,DoesNotExist, Gt, Lt 否 指定主机
podAffinity Pod In, NotIn, Exists,DoesNotExist 是 Pod与指定Pod同一拓扑域
podAntiAffinity Pod In, NotIn, Exists,DoesNotExist 是 Pod与指定Pod不在同一拓扑域
kubectl label nodes node01 lbj=a
kubectl label nodes node02 lbj=a
//创建一个标签为 app=myapp01 的 Pod
vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp01
labels:
app: myapp01
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
kubectl apply -f pod3.yaml
kubectl get pods --show-labels -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
myapp01 1/1 Running 0 37s 10.244.2.3 node01 <none> <none> app=myapp01
//使用 Pod 亲和性调度,创建多个 Pod 资源
vim pod4.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp02
labels:
app: myapp02
spec:
containers:
- name: myapp02
image: soscscs/myapp:v1
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp01
topologyKey: lbj
#仅当节点和至少一个已运行且有键为“app”且值为“myapp01”的标签 的 Pod 处于同一拓扑域时,才可以将该 Pod 调度到节点上。 (更确切的说,如果节点 N 具有带有键 kgc 和某个值 V 的标签,则 Pod 有资格在节点 N 上运行,以便集群中至少有一个具有键 kgc 和值为 V 的节点正在运行具有键“app”和值 “myapp01”的标签的 pod。)
#topologyKey 是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值,则调度器会将这两个节点视为处于同一拓扑域中。 调度器试图在每个拓扑域中放置数量均衡的 Pod。
#如果 kgc 对应的值不一样就是不同的拓扑域。比如 Pod1 在 kgc=a 的 Node 上,Pod2 在 lbj=b 的 Node 上,Pod3 在 lbj=a 的 Node 上,则 Pod2 和 Pod1、Pod3 不在同一个拓扑域,而Pod1 和 Pod3在同一个拓扑域。
kubectl apply -f pod4.yaml
kubectl get pods --show-labels -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
myapp01 1/1 Running 0 15m 10.244.1.3 node01 <none> <none> app=myapp01
myapp02 1/1 Running 0 8s 10.244.1.4 node01 <none> <none> app=myapp02
myapp03 1/1 Running 0 52s 10.244.2.53 node02 <none> <none> app=myapp03
myapp04 1/1 Running 0 44s 10.244.1.51 node01 <none> <none> app=myapp03
myapp05 1/1 Running 0 38s 10.244.2.54 node02 <none> <none> app=myapp03
myapp06 1/1 Running 0 30s 10.244.1.52 node01 <none> <none> app=myapp03
myapp07 1/1 Running 0 24s 10.244.2.55 node02 <none> <none> app=myapp03
4.3 Использование планирования антисходства Pod
Официальный пример 1:
vim pod5.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp10
labels:
app: myapp10
spec:
containers:
- name: myapp10
image: soscscs/myapp:v1
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp01
topologyKey: kubernetes.io/hostname
Если узел находится в том же топологическом домене, что и модуль, и имеет метку с ключом «app» и значением «myapp01», то модуль не следует планировать для этого узла. (Если topologyKey — это kubernetes.io/hostname, это означает, что, когда узел и под с ключом «app» и значением «myapp01» находятся в одном домене топологии, под не может быть запланировано для этого узла.
kubectl apply -f pod5.yaml
kubectl get pods --show-labels -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
myapp01 1/1 Running 0 44m 10.244.1.3 node01 <none> <none> app=myapp01
myapp02 1/1 Running 0 29m 10.244.1.4 node01 <none> <none> app=myapp02
myapp10 1/1 Running 0 75s 10.244.2.4 node02 <none> <none> app=myapp03
Официальный пример 2:
vim pod6.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp20
labels:
app: myapp20
spec:
containers:
- name: myapp20
image: soscscs/myapp:v1
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp01
topologyKey: lbj
//由于指定 Pod 所在的 node01 节点上具有带有键 kgc 和标签值 a 的标签,node02 也有这个kgc=a的标签,所以 node01 和 node02 是在一个拓扑域中,反亲和要求新 Pod 与指定 Pod 不在同一拓扑域,所以新 Pod 没有可用的 node 节点,即为 Pending 状态。
kubectl get pod --show-labels -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
myapp01 1/1 Running 0 43s 10.244.1.68 node01 <none> <none> app=myapp01
myapp20 0/1 Pending 0 4s <none> <none> <none> <none> app=myapp03
kubectl label nodes node02 kgc=b --overwrite
kubectl get pod --show-labels -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
myapp01 1/1 Running 0 7m40s 10.244.1.68 node01 <none> <none> app=myapp01
myapp21 1/1 Running 0 7m1s 10.244.2.65 node02 <none> <none> app=myapp03
5. Порча и терпимость
5.1 Порча
- Привязка узла — это атрибут (предпочтение или жесткое требование) пода, который заставляет под привлекать узел определенного типа. С другой стороны, Taint позволяет узлам исключать определенный класс подов.
- Taint и Toleration работают вместе, чтобы предотвратить назначение подов неподходящим узлам. К каждому узлу можно применить одно или несколько ограничений, а это означает, что поды, которые не могут терпеть эти ограничения, не будут приняты узлом. Если к подам применяется толерантность, это означает, что эти поды могут (но не обязательно) быть запланированы для узлов с соответствующими искажениями.
- Используйте команду kubectl taint, чтобы установить порчу на узле. После того, как на узле установлена порча, у него будут эксклюзивные отношения с подом, что позволяет узлу отказаться от планирования и выполнения пода или даже выселить существующий под из узла погаснет.
5.2 Формат композиции Taint
key=value:effect
## 每个污点有一个 key 和 value 作为污点的标签,其中 value 可以为空,effect 描述污点的作用。
5.3 Основные операции по удалению пятен
(1) Проверьте пятно на узле узла.
格式:kubectl describe nodes <节点名称> | grep Taints
或者是kubectl describe nodes <节点名称> | grep -i taints
eg:查看master01的污点
kubectl describe nodes master01 |grep -i taints
(2) Закрепить пятна
格式kubectl taint node 指定的node key1=value1:NoSchedule
eg:给node01 设置污点进行测试
kubectl taint node node01 abc=a:NoSchedule
(3) Удалить пятна
格式:kubectl taint node 指定的node key:NoSchedule-
eg:清除node01 设置的污点
kubectl taint node node01 abc:NoSchedule-
5.4. Перед лицом пятен создайте настройки допуска для ресурсов модуля.
vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp01
labels:
app: myapp01
spec:
containers:
- name: with-node-affinity
image: nginx:1.14
tolerations:
- key: "abc"
operator: "Equal"
value: "a"
effect: "NoExecute"
tolerationSeconds: 3600
#Ключ, значение и эффект должны соответствовать настроению, установленному на узле.
Если значение #operator — Exists, значение значения будет игнорироваться, то есть оно существует.
#tolerationSeconds используется для описания того, как долго под может продолжать работать на узле, когда его необходимо выселить.
Описание процесса: Известно, что на узле 01 установлена пятно вытеснения, и на основе приведенной выше конфигурации создается под. Будет работать на node01 в течение часа (терпимо), а затем будет выселено.
5,5 кордон и водосток
##对节点执行维护操作:
kubectl get nodes
//将 Node 标记为不可调度的状态,这样就不会让新创建的 Pod 在此 Node 上运行
kubectl cordon <NODE_NAME> #该node将会变为SchedulingDisabled状态
//kubectl drain 可以让 Node 节点开始释放所有 pod,并且不接收新的 pod 进程。drain 本意排水,意思是将出问题的 Node 下的 Pod 转移到其它 Node 下运行
kubectl drain <NODE_NAME> --ignore-daemonsets --delete-emptydir-data --force
--ignore-daemonsets:无视 DaemonSet 管理下的 Pod。
--delete-emptydir-data:如果有 mount local volume 的 pod,会强制杀掉该 pod。
--force:强制释放不是控制器管理的 Pod。
注:执行 drain 命令,会自动做了两件事情:
(1)设定此 node 为不可调度状态(cordon)
(2)evict(驱逐)了 Pod
//kubectl uncordon 将 Node 标记为可调度的状态
kubectl uncordon <NODE_NAME>
6. Интерпретация статуса и навыки устранения неполадок на этапе запуска модуля.
6.1 Статус фазы запуска модуля (фаза)
(1) Этапы запуска
После создания модуля, пока он не будет работать постоянно, между ними будет много шагов и существует много возможностей для ошибок, поэтому будет много разных состояний.
Вообще говоря, процесс pod включает в себя следующие этапы:
1) Расписание на определенный узел. Kubernetes выбирает узел на основе определенного алгоритма приоритета и использует его в качестве узла для запуска в качестве пода.
2) Вытащите изображение
3) Смонтировать конфигурацию хранилища и т. д.
4) Запустите его. Если есть проверка работоспособности, ее статус будет установлен по результатам проверки.
(2) Возможные состояния фазы
● Ожидание: указывает, что APIServer создал объект ресурса Pod и сохранил его в etcd, но он не был запланирован (например, он не был запланирован для определенного узла) или все еще находится в процессе загрузки. изображение со склада.
●Выполняется: модуль был запланирован на узле, и все контейнеры в модуле были созданы kubelet. По крайней мере один контейнер запущен или запускается или перезапускается (то есть модули Pod в состоянии «Выполняется» могут быть недоступны в обычном режиме).
●Успешно: некоторые модули не выполняются долго, например задания и задания cron.По истечении определенного периода времени все контейнеры в модуле успешно завершаются и не перезапускаются. Обратная связь по результатам выполнения задания обязательна.
●Failed: все контейнеры в модуле были прекращены, и по крайней мере один контейнер был завершен из-за сбоя. Другими словами, контейнер закрывается с ненулевым статусом или завершается системой, например, проблема с написанием команды.
●Unknown: указывает, что статус модуля не может быть прочитан, обычно потому, что kube-controller-manager не может связаться с модулем. Возникла проблема с узлом, на котором расположен модуль, или потеряно соединение, в результате чего статус модуля стал неизвестным.
//Как удалить под в неизвестном состоянии?
●Удалите проблемный узел из кластера. При использовании общедоступного облака kube-controller-manager автоматически удалит соответствующий узел после удаления виртуальной машины. В кластере, развернутом на физических машинах, администратору необходимо вручную удалить узел (kubectl delete node <node_name>).
● Пассивно подождите, пока узел вернется в нормальное состояние. Kubelet снова свяжется с kube-apiserver, чтобы подтвердить ожидаемый статус этих модулей, а затем решит удалить или продолжить запуск этих модулей.
● Упреждающее удаление модулей и принудительное удаление модулей с помощью команды kubectl delete pod <pod_name> --grace- period=0 --force . Однако здесь следует отметить, что этот метод не рекомендуется, если точно не известно, что Pod действительно остановлен (например, виртуальная машина или физическая машина, на которой расположен Node, была выключена). Принудительное удаление может легко привести к таким проблемам, как разделение мозга или потеря данных, особенно для модулей, управляемых StatefulSet.
6.2 Действия по устранению неполадок кластера k8
kubectl get pods/nodes 查看Pod/Node节点的状态提示
kubectl describe 查看相关资源的详细事件信息
kubectl logs 查看Pod容器的进程日志
kubectl exec -it 进入Pod容器查看容器的一些状态
journalctl -u kubelet 查看kubelet进程日志