[Cloud Native] k8s ----- Планирование кластера

Оглавление

1.k8s механизм просмотра списка

1.1 Введение в механизм просмотра списков

1.2 В соответствии с механизмом просмотра списка процесс создания модуля

 2. Стратегия планирования планировщика

2.1 Введение в стратегию планирования планировщика

2.2 Алгоритм предварительного выбора стратегии Планировщика 

2.3 Алгоритм стратегии оптимизации планировщика

3. Управление тегами в k8s и метод планирования nodeSelector и nodeName

3.1 Укажите узел планирования

3.2. Получить справку по лейблу

3.3 Необходимо получить имя NAME на узле

3.4 Установите метки для соответствующих узлов как lbj=a и lbj=b соответственно.

3.5 Просмотр тегов

3.6 Изменение метода планирования nodeSelector

3.7 Просмотр подробностей событий

4. Близость

4.1 привязка узлов 

(1) Настройка проверки жесткой стратегии привязки узлов 

(2) Операционная связь «ключ-значение»

Поэкспериментируйте с жесткими настройками политики:

Поэкспериментируйте с настройками мягкой политики:

4.2 Сродство и антисродство подов

4.3 Использование планирования антисходства Pod

Официальный пример 1:

Официальный пример 2:

5. Порча и терпимость

5.1 Порча 

5.2 Формат композиции Taint

5.3 Основные операции по удалению пятен

(1) Проверьте пятно на узле узла.

(2) Закрепить пятна

(3) Удалить пятна

5.4. Перед лицом пятен создайте настройки допуска для ресурсов модуля.

5,5 кордон и водосток

6. Интерпретация статуса и навыки устранения неполадок на этапе запуска модуля.

6.1 Статус фазы запуска модуля (фаза)

(1) Этапы запуска

(2) Возможные состояния фазы

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进程日志

Guess you like

Origin blog.csdn.net/Sp_Tizzy/article/details/133028503