Я изучаю кубернет, проходя через Kubernetes учебник. Выполняя упражнения в модуль 4, Я заметил странное поведение кубернетов при перезаписи метки. Я мог бы использовать некоторые объяснения, потому что то, что я вижу, не соответствует ни руководству, ни документации, ни моим ожиданиям.
Для справки, моя среда выполнения выглядит следующим образом:
dfvsmdev@gotham:~/workspace/kube$ minikube version
minikube version: v1.10.0
commit: f318680e7e5bf539f7fadeaaf198f4e468393fb9
dfvsmdev@gotham:~/workspace/kube$ kubectl version
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.2", GitCommit:"52c56ce7a8272c798dbc29846288d7cd9fbae032", GitTreeState:"clean", BuildDate:"2020-04-16T11:56:40Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.1", GitCommit:"7879fc12a63337efff607952a323df90cdc7a335", GitTreeState:"clean", BuildDate:"2020-04-08T17:30:47Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
dfvsmdev@gotham:~/workspace/kube$ uname -a
Linux gotham 4.15.0-72-generic #81~16.04.1-Ubuntu SMP Tue Nov 26 16:34:21 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
dfvsmdev@gotham:~/workspace/kube$
Также для удобства я написал небольшой скрипт под названием get-pod-labels
:
#!/bin/sh
REGEX=[-A-Za-z0-9._/]+
kubectl describe pods | egrep "(^Name: .+$|^.+ ${REGEX}=${REGEX}$)"
Когда я запускаю этот скрипт, он дает следующий результат:
dfvsmdev@gotham:~/workspace/kube$ ./get-pod-labels
Name: hello-node-7bf657c596-xr8dk
Labels: app=hello-node
pod-template-hash=7bf657c596
Name: kubernetes-bootcamp-86656bc875-nz9f6
Labels: app=kubernetes-bootcamp
kb=true
pod-template-hash=86656bc875
Name: kubernetes-bootcamp-86656bc875-wlqnw
Labels: app=kubernetes-bootcamp
kb=true
pod-template-hash=86656bc875
Теперь я нахожусь в той части руководства, где они хотят, чтобы мы выполнили команду kubectl label pod POD_NAME app=v1
. На этом шаге учебного пособия нужно изменить существующую этикетку. Как написано команда выдает ошибку, error: 'app' already has a value (kubernetes-bootcamp), and --overwrite is false
. Итак, я добавил --overwrite
флаг и повторил попытку.
dfvsmdev@gotham:~/workspace/kube$ kubectl label pods --overwrite kubernetes-bootcamp-86656bc875-nz9f6 app=v1
pod/kubernetes-bootcamp-86656bc875-nz9f6 labeled
Но когда я проверил этикетки на капсулах, чтобы проверить модификацию, я увидел кое-что странное:
dfvsmdev@gotham:~/workspace/kube$ ./get-pod-labels
Name: hello-node-7bf657c596-xr8dk
Labels: app=hello-node
pod-template-hash=7bf657c596
Name: kubernetes-bootcamp-86656bc875-48frs
Labels: app=kubernetes-bootcamp
pod-template-hash=86656bc875
Name: kubernetes-bootcamp-86656bc875-nz9f6
Labels: app=v1
kb=true
pod-template-hash=86656bc875
Name: kubernetes-bootcamp-86656bc875-wlqnw
Labels: app=kubernetes-bootcamp
kb=true
pod-template-hash=86656bc875
dfvsmdev@gotham:~/workspace/kube$
Как и ожидалось, kubernetes изменили этикетку app=v1
для указанного имени модуля. Но он также создал новый экземпляр пода, чего я не ожидал. В руководстве также не упоминается новый модуль. Новый экземпляр модуля выглядит как новая установка модуля, поскольку у него нет специальной метки (kb=true
), который я добавил к другим модулям kubernetes-bootcamp.
Так что давайте отложим учебник, потому что, откровенно говоря, в нем много опечаток. Давайте просто сосредоточимся на ожидаемом поведении изменения метки. то страница руководства метки kubectl объясняет флаг перезаписи следующим образом:
--overwrite=false
If true, allow labels to be overwritten, otherwise reject label updates that overwrite existing labels.
В этой документации ничего не говорится о создании нового экземпляра модуля. В чем здесь смысл? Является ли создание немодифицированного модуля чем-то особенным в кубернетах? Или это ошибка? Меня удивляет такое поведение. Что, если мне нужно изменить ярлыки сотен контейнеров? Смогут ли кубернеты делать сотни новых стручков?
Пожалуйста, объясните мне это поведение.
ДОБАВЛЕНИЕ
В ответ на ответ KoopaKiller ниже вот пояснение. Следующий журнал трассировки следует за его действиями. Обратите внимание, что в начале есть два модуля "kubernetes-bootcamp".
dfvsmdev@gotham:~/workspace/kube$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
hello-node-7bf657c596-xr8dk 1/1 Running 1 3d18h app=hello-node,pod-template-hash=7bf657c596
kubernetes-bootcamp-86656bc875-nz9f6 1/1 Running 0 2d22h app=kubernetes-bootcamp,kb=true,pod-template-hash=86656bc875
kubernetes-bootcamp-86656bc875-wlqnw 1/1 Running 0 2d22h app=kubernetes-bootcamp,kb=true,pod-template-hash=86656bc875
dfvsmdev@gotham:~/workspace/kube$ kubectl label pods --overwrite kubernetes-bootcamp-86656bc875-nz9f6 app=v1
pod/kubernetes-bootcamp-86656bc875-nz9f6 labeled
dfvsmdev@gotham:~/workspace/kube$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
hello-node-7bf657c596-xr8dk 1/1 Running 1 3d18h app=hello-node,pod-template-hash=7bf657c596
kubernetes-bootcamp-86656bc875-jh9ml 1/1 Running 0 2m9s app=kubernetes-bootcamp,pod-template-hash=86656bc875
kubernetes-bootcamp-86656bc875-nz9f6 1/1 Running 0 2d22h app=v1,kb=true,pod-template-hash=86656bc875
kubernetes-bootcamp-86656bc875-wlqnw 1/1 Running 0 2d22h app=kubernetes-bootcamp,kb=true,pod-template-hash=86656bc875
Как видите, новый, третий модуль "kubernetes-bootcamp" действительно был создан после выполнения команды label / overwrite.
Учитывая, что такого же результата не было в контрпримере KoopaKiller, я полагаю, что то, что я вижу, может быть ошибкой в реализации minikube. Это может быть лучшим объяснением.
Я протестировал в своей лаборатории и пришел к выводу, что модуль не создается повторно после применения / изменения метки.
Вkind: Pod
не воссоздайте контейнер после любых изменений.
Вы можете заставить тест выполнить простой модуль, применить метку и изменить метку с помощью --overwrite
флаг, и они проверяют контейнер AGE
с comamnf kubectl get pods
.
Пример:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
command:
- sleep
- "3600"
EOF
$ kubectl label pod nginx app=nginx
pod/nginx labeled
$ kg pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 2m4s app=nginx
Как видите, возраст стручка 2 м4.
$ kubectl label pod nginx app=my-nginx --overwrite
pod/nginx labeled
$ kg pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 3m28s app=my-nginx
Прочие соображения:
Стручки сами по себе не исцеляются. Если Pod запланирован для узла, который выходит из строя, или если сама операция планирования завершается неудачно, Pod удаляется; аналогично, Pod не переживет выселение из-за нехватки ресурсов или обслуживания узла.
Вам необходимо использовать, например, развертывание, которое гарантирует, что ваш модуль будет устойчивым и высокодоступным.