Так само як і з будь-якою іншою технологією, ви можете зіткнутися з проблемами під час встановлення або використання kubeadm. Цей документ містить список найпоширеніших проблем та їх рішень, пропонуючи вам кроки, які допоможуть зʼясувати та розвʼязати проблеми.
Якщо вашої проблеми немає в переліку нижче, будь ласка, скористайтесь настпуним:
Ви вважаєте, що це помилка в kubeadm:
Ви не впевнені, що це проблема в роботі kubeadm, ви можете запитати в Slack в каналі #kubeadm, або поставити питання на Stack Overflow. Будь ласка, додайте теґи #kubeadm та #kubernetes.
У версії v1.18 kubeadm додав запобігання приєднання вузла до кластера, якщо вузол з таким самим імʼям вже існує. Це вимагало додавання RBAC для користувача bootstrap-token для можливості виконання операції GET обʼєкта Node.
Однак це викликає проблему, коли kubeadm join з v1.18 не може приєднатися до кластера, створеного за допомогою kubeadm v1.17.
Для того, щоб оминути цю проблему у вас є два варіанти:
Виконайте kubeadm init phase bootstrap-token на вузлі панелі управління за допомогою kubeadm v1.18. Зауважте, що це дозволяє інші дозволи bootstrap-token.
або
Застосуйте наступний RBAC вручну за допомогою kubectl apply -f ...:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kubeadm:get-nodes
rules:
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubeadm:get-nodes
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubeadm:get-nodes
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:bootstrappers:kubeadm:default-node-token
ebtables або подібний виконавчий файл не знайдений під час встановленняЯкщо ви бачите наступні попередження під час виконання kubeadm init:
[preflight] WARNING: ebtables not found in system path
[preflight] WARNING: ethtool not found in system path
Тоді вам може бракувати ebtables, ethtool або подібного виконавчого файлу на вашому вузлі. Ви можете встановити їх за допомогою наступних команд:
apt install ebtables ethtool.yum install ebtables ethtool.kubeadm блокується під час очікування на панель управління під час встановленняЯкщо ви помічаєте, що kubeadm init зупиняється після виведення наступного рядка:
[apiclient] Created API client, waiting for the control plane to become ready
Це може бути спричинено кількома проблемами. Найбільш поширеними є:
docker ps та вивчаючи кожен контейнер за допомогою docker logs. Для інших середовищ виконання контейнерів, див. Налагодження вузлів Kubernetes за допомогою crictl.kubeadm блокується під час видалення керованих контейнерівНаступне може трапитися, якщо середовище виконання контейнерів зупиняється і не видаляє жодних керованих контейнерів Kubernetes:
sudo kubeadm reset
[preflight] Running pre-flight checks
[reset] Stopping the kubelet service
[reset] Unmounting mounted directories in "/var/lib/kubelet"
[reset] Removing kubernetes-managed containers
(block)
Можливий варіант вирішення — перезапустити середовище виконання контейнерів, а потім знову запустити kubeadm reset. Ви також можете використовувати crictl для налагодження стану середовища виконання контейнерів. Див. Налагодження вузлів Kubernetes за допомогою crictl.
RunContainerError, CrashLoopBackOff або ErrorВідразу після виконання kubeadm init не повинно бути жодних контейнерів у таких станах.
kubeadm init, будь ласка, створіть тікет в репозиторії kubeadm. coredns (або kube-dns) повинен перебувати у стані Pending до моменту розгортання додатка для мережі.RunContainerError, CrashLoopBackOff або Error після розгортання додатка для мережі та нічого не відбувається з coredns (або kube-dns), дуже ймовірно, що додаток Pod Network, який ви встановили, є пошкодженим. Можливо, вам потрібно надати йому більше привілеїв RBAC або використовувати новішу версію. Будь ласка, створіть тікет в системі відстеження проблем постачальника Pod Network та очікуйте розвʼязання проблеми там.coredns застрягає у стані PendingЦе очікувано і є частиною дизайну. kubeadm є агностичним до мережі, тому адміністратор повинен встановити вибраний додаток для мережі за власним вибором. Вам потрібно встановити Pod Network, перш ніж coredns може бути повністю розгорнутим. Таким чином, стан Pending перед налаштуванням мережі є нормальним.
HostPort не працюютьФункціональність HostPort та HostIP доступна залежно від вашого провайдера Pod Network. Будь ласка, звʼяжіться з автором додатка Pod Network, щоб дізнатися, чи
функціональність HostPort та HostIP доступна.
Перевірено, що Calico, Canal та Flannel CNI підтримують HostPort.
Для отримання додаткової інформації перегляньте документацію CNI portmap.
Якщо ваш постачальник мережі не підтримує втулок CNI portmap, можливо, вам доведеться використовувати функцію NodePort для сервісів або використовуйте HostNetwork=true.
Багато додатків для мережі ще не увімкнули режим hairpin, який дозволяє Podʼам звертатися до себе за їх Service IP. Це повʼязано з CNI. Будь ласка, звʼяжіться з постачальником додатка для мережі, щоб дізнатися про останній статус підтримки режиму hairpin.
Якщо ви використовуєте VirtualBox (безпосередньо, або через Vagrant), вам слід переконатися, що hostname -i повертає маршрутизовану IP-адресу. Типово перший інтерфейс підключений до немаршрутизованої мережі тільки для хосту. Як тимчасовий варіант, ви можете змінити /etc/hosts, подивіться цей Vagrantfile для прикладу.
Наступна помилка вказує на можливу несумісність сертифікатів.
# kubectl get pods
Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
Перевірте, що файл $HOME/.kube/config містить дійсний сертифікат, та перегенеруйте сертифікат за необхідності. Сертифікати у файлі конфігурації kubeconfig закодовані у форматі base64. Команда base64 --decode може бути використана для декодування сертифіката, а openssl x509 -text -noout може бути використано для перегляду інформації про сертифікат.
Скасуйте змінну середовища KUBECONFIG за допомогою:
unset KUBECONFIG
Або встановіть його в типове розташування KUBECONFIG:
export KUBECONFIG=/etc/kubernetes/admin.conf
Іншим обхідним методом є перезапис наявного kubeconfig для користувача "admin":
mv $HOME/.kube $HOME/.kube.bak
mkdir $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Стандартно kubeadm налаштовує kubelet на автоматичну ротацію сертифікатів клієнта за допомогою символічного посилання /var/lib/kubelet/pki/kubelet-client-current.pem, вказаного в /etc/kubernetes/kubelet.conf. Якщо цей процес ротації завершиться невдачею, ви можете побачити помилки, такі як x509: certificate has expired or is not yet valid в журналах kube-apiserver. Щоб виправити цю проблему, слід виконати наступні кроки:
Зробіть резервну копію та видаліть файли /etc/kubernetes/kubelet.conf та /var/lib/kubelet/pki/kubelet-client* з несправного вузла.
З робочого вузла панелі управління кластера, де є /etc/kubernetes/pki/ca.key, виконайте kubeadm kubeconfig user --org system:nodes --client-name system:node:$NODE > kubelet.conf. $NODE повинно бути встановлено на імʼя наявного несправного вузла в кластері. Вручну змініть отриманий kubelet.conf, щоб відкоригувати імʼя та endpoint сервера, або передайте kubeconfig user --config (див. see Створення файлів kubeconfig для додаткових користувачів). Якщо в у вашому кластері немає ca.key, ви повинні вручну підписати вбудовані сертифікати в kubelet.conf.
Скопіюйте цей отриманий kubelet.conf в /etc/kubernetes/kubelet.conf на несправному вузлі.
Перезапустіть kubelet (systemctl restart kubelet) на несправному вузлі та зачекайте, доки /var/lib/kubelet/pki/kubelet-client-current.pem буде відновлено.
Вручну відредагуйте kubelet.conf, щоб вказати на обертані сертифікати клієнта kubelet, замінивши client-certificate-data та client-key-data на:
client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
Перезапустіть kubelet.
Переконайтеся, що вузол стає Ready.
Наступна помилка може свідчити про те, що щось пішло не так у мережі Podʼів:
Error from server (NotFound): the server could not find the requested resource
Якщо ви використовуєте Flannel як мережу для Podʼів у Vagrant, тоді вам доведеться вказати типове імʼя інтерфейсу для Flannel.
Зазвичай Vagrant призначає два інтерфейси всім віртуальним машинам. Перший, для якого всі хости мають IP-адресу 10.0.2.15, призначено для зовнішнього трафіку, який проходить через NAT.
Це може призвести до проблем із Flannel, яка стандартно він обирає перший інтерфейс на хості. Це призводить до того, що всі хости вважають, що у них однакова публічна IP-адреса. Щоб цього уникнути, передайте прапорець --iface eth1 для Flannel, щоб обрати другий інтерфейс.
У деяких ситуаціях команди kubectl logs та kubectl run можуть повертати помилки на функціональному кластері:
Error from server: Get https://10.19.0.41:10250/containerLogs/default/mysql-ddc65b868-glc5m/mysql: dial tcp 10.19.0.41:10250: getsockopt: no route to host
Це може бути викликано використанням Kubernetes IP-адреси, яка не може взаємодіяти з іншими IP-адресами на одній підмережі, можливо, через політику провайдера машин.
DigitalOcean призначає публічний IP для eth0, а також приватний IP для внутрішнього використання як анкера для їхньої функції змінного IP. Однак, kubelet вибере останній як InternalIP вузла замість першого.
Використовуйте ip addr show для перевірки цього сценарію, а не ifconfig, оскільки ifconfig не показує обрану адресу IP для аліаса. Альтернативно, API-точка, специфічна для DigitalOcean, дозволяє запитувати анкер IP-адресу з машини:
curl http://169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address
Обхідним рішенням є повідомлення kubelet, яку IP використовувати за допомогою --node-ip. Коли використовується DigitalOcean, це може бути публічний IP (призначений eth0) або приватний IP (призначений eth1), якщо ви хочете використовувати додаткову приватну мережу. Розділ kubeletExtraArgs структури kubeadm NodeRegistrationOptions може бути використаний для цього.
Потім перезапустіть kubelet:
systemctl daemon-reload
systemctl restart kubelet
coredns перебувають у стані CrashLoopBackOff або ErrorЯкщо у вас є вузли, які працюють із SELinux та старішою версією Docker, ви можете стикнутися зі сценарієм, де Podʼи coredns не запускаються. Щоб вирішити це, ви можете спробувати один з наступних варіантів:
Оновіться до новішої версії Docker.
Змініть розгортання coredns, встановивши allowPrivilegeEscalation в true:
kubectl -n kube-system get deployment coredns -o yaml | \
sed 's/allowPrivilegeEscalation: false/allowPrivilegeEscalation: true/g' | \
kubectl apply -f -
Іншою причиною того, що CoreDNS має CrashLoopBackOff, є те, що Pod CoreDNS, розгорнутий в Kubernetes, виявляє цикл. Існують різні обхідні варіанти, щоб уникнути спроб перезапуску Podʼа CoreDNS кожного разу, коли CoreDNS виявляє цикл та виходить.
allowPrivilegeEscalation в true може піддавати ризику безпеку вашого кластера.Якщо ви стикаєтеся з такою помилкою:
rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "process_linux.go:110: decoding init error from pipe caused \"read parent: connection reset by peer\""
Ця проблема виникає, якщо ви використовуєте CentOS 7 з Docker 1.13.1.84. Ця версія Docker може завадити kubelet виконуватися в контейнері etcd.
Для усунення цієї проблеми виберіть один з наступних варіантів:
Поверніться до попередньої версії Docker, наприклад, 1.13.1-75
yum downgrade docker-1.13.1-75.git8633870.el7.centos.x86_64 docker-client-1.13.1-75.git8633870.el7.centos.x86_64 docker-common-1.13.1-75.git8633870.el7.centos.x86_64
Встановіть одну з новіших рекомендованих версій, наприклад 18.06:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce-18.06.1.ce-3.el7.x86_64
--component-extra-argsПрапорці kubeadm init, такі як --component-extra-args, дозволяють передавати власні аргументи компоненту панелі управління, наприклад, kube-apiserver. Однак цей механізм обмежений через тип, який використовується для розбору значень (mapStringString).
Якщо ви вирішите передати аргумент, який підтримує кілька значень, розділених комами, такий як --apiserver-extra-args "enable-admission-plugins=LimitRanger,NamespaceExists", цей прапорець видасть помилку flag: malformed pair, expect string=string. Це відбувається через те, що список аргументів для --apiserver-extra-args очікує пари key=value, і в цьому випадку NamespacesExists розглядається як ключ, якому не вистачає значення.
У іншому випадку ви можете спробувати розділити пари key=value так: --apiserver-extra-args "enable-admission-plugins=LimitRanger,enable-admission-plugins=NamespaceExists", але це призведе до того, що ключ enable-admission-plugins матиме лише значення NamespaceExists.
Відомий обхід цього — використання файлу конфігурації kubeadm.
У сценаріях хмарних провайдерів kube-proxy може виявитися запланованим на нових робочих вузлах до того, як cloud-controller-manager ініціалізує адреси вузла. Це призводить до того, що kube-proxy не може належним чином отримати IP-адресу вузла, і це має негативний вплив на функцію проксі, що керує балансуванням навантаження.
У kube-proxy Pods можна побачити наступну помилку:
server.go:610] Failed to retrieve node IP: host IP unknown; known addresses: []
proxier.go:340] invalid nodeIP, initializing kube-proxy with 127.0.0.1 as nodeIP
Відомий варіант рішення — виправлення DaemonSet kube-proxy, щоб дозволити його планування на вузлах панелі управління незалежно від їхніх умов, утримуючи його подальше від інших вузлів, доки їхні початкові умови зберігаються:
kubectl -n kube-system patch ds kube-proxy -p='{
"spec": {
"template": {
"spec": {
"tolerations": [
{
"key": "CriticalAddonsOnly",
"operator": "Exists"
},
{
"effect": "NoSchedule",
"key": "node-role.kubernetes.io/control-plane"
}
]
}
}
}
}'
Тікет, що відстежує цю проблему, розташовано тут.
/usr монтується тільки для читання на вузлахУ дистрибутивах Linux, таких як Fedora CoreOS або Flatcar Container Linux, тека /usr монтується як файлова система тільки для читання. Для підтримки flex-volume компоненти Kubernetes, такі як kubelet і kube-controller-manager, використовують типовий шлях /usr/libexec/kubernetes/kubelet-plugins/volume/exec/, проте тека flex-volume має бути доступною для запису, щоб ця функція працювала.
Для усунення цієї проблеми ви можете налаштувати теку flex-volume, використовуючи файл конфігурації kubeadm.
На основному вузлі панелі управління (створеному за допомогою kubeadm init) передайте наступний файл, використовуючи параметр --config:
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
- name: "volume-plugin-dir"
value: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
controllerManager:
extraArgs:
- name: "flex-volume-plugin-dir"
value: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
При долученні вузлів:
apiVersion: kubeadm.k8s.io/v1beta4
kind: JoinConfiguration
nodeRegistration:
kubeletExtraArgs:
- name: "volume-plugin-dir"
value: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
Альтернативно ви можете змінити файл /etc/fstab, щоб зробити монтування /usr доступним для запису, проте будьте обізнані, що це змінює принцип дизайну дистрибутиву Linux.
kubeadm upgrade plan виводить повідомлення про помилку context deadline exceededЦе повідомлення про помилку виводиться при оновленні кластера Kubernetes за допомогою kubeadm у випадку використання зовнішнього etcd. Це не критична помилка і виникає через те, що старі версії kubeadm виконують перевірку версії зовнішнього кластера etcd. Ви можете продовжити з kubeadm upgrade apply ....
Цю проблему виправлено у версії 1.19.
kubeadm reset відмонтовує /var/lib/kubeletЯкщо /var/lib/kubelet має точку монтування, виконання kubeadm reset фактично відмонтує його.
Для уникнення цієї проблеми повторно замонтуйте теку /var/lib/kubelet після виконання операції kubeadm reset.
Це вдосконалення було введено в kubeadm 1.15. Проблема виправлена в 1.20.
У кластері kubeadm metrics-server може бути використаний в небезпечний спосіб, передаючи йому параметр --kubelet-insecure-tls. Це не рекомендується для промислових кластерів.
Якщо ви хочете використовувати TLS між metrics-server та kubelet, виникає проблема, оскільки kubeadm розгортає самопідписний службовий сертифікат для kubelet. Це може призвести до наступних помилок з боку metrics-server:
x509: certificate signed by unknown authority
x509: certificate is valid for IP-foo not IP-bar
Дивіться Увімкнення підписаних службових сертифікатів kubelet, щоб зрозуміти, як налаштувати kubelet в кластері kubeadm для отримання належно підписаних службових сертифікатів.
Також перегляньте Як запустити metrics-server безпечно.
Це стосується лише оновлення вузла панелі управління за допомогою бінарного файлу kubeadm v1.28.3 або пізніше, при умові, що вузол в цей час керується версіями kubeadm v1.28.0, v1.28.1 або v1.28.2.
Ось повідомлення про помилку, яке може виникнути:
[upgrade/etcd] Failed to upgrade etcd: couldn't upgrade control plane. kubeadm has tried to recover everything into the earlier state. Errors faced: static Pod hash for component etcd on Node kinder-upgrade-control-plane-1 did not change after 5m0s: timed out waiting for the condition
[upgrade/etcd] Waiting for previous etcd to become available
I0907 10:10:09.109104 3704 etcd.go:588] [etcd] attempting to see if all cluster endpoints ([https://172.17.0.6:2379/ https://172.17.0.4:2379/ https://172.17.0.3:2379/]) are available 1/10
[upgrade/etcd] Etcd was rolled back and is now available
static Pod hash for component etcd on Node kinder-upgrade-control-plane-1 did not change after 5m0s: timed out waiting for the condition
couldn't upgrade control plane. kubeadm has tried to recover everything into the earlier state. Errors faced
k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade.rollbackOldManifests
cmd/kubeadm/app/phases/upgrade/staticpods.go:525
k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade.upgradeComponent
cmd/kubeadm/app/phases/upgrade/staticpods.go:254
k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade.performEtcdStaticPodUpgrade
cmd/kubeadm/app/phases/upgrade/staticpods.go:338
...
Причина цієї помилки полягає в тому, що пошкоджені версії генерують файл маніфесту etcd із небажаними стандартними в PodSpec. Це призводить до різниці в порівнянні маніфестів, і kubeadm буде очікувати зміни хешу в Pod, але kubelet ніколи не оновить хеш.
Є два способи обійти цю проблему, якщо ви бачите її у своєму кластері:
Оновлення etcd може бути пропущено між пошкодженими версіями та v1.28.3 (або пізніше) за допомогою:
kubeadm upgrade {apply|node} [version] --etcd-upgrade=false
Це не рекомендується у випадку, якщо пізніше патч-версії v1.28 вводять нову версію etcd.
Перед оновленням виправте маніфест для статичного Pod etcd, щоб видалити стандартні проблемні атрибути:
diff --git a/etc/kubernetes/manifests/etcd_defaults.yaml b/etc/kubernetes/manifests/etcd_origin.yaml
index d807ccbe0aa..46b35f00e15 100644
--- a/etc/kubernetes/manifests/etcd_defaults.yaml
+++ b/etc/kubernetes/manifests/etcd_origin.yaml
@@ -43,7 +43,6 @@ spec:
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
- successThreshold: 1
timeoutSeconds: 15
name: etcd
resources:
@@ -59,26 +58,18 @@ spec:
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
- successThreshold: 1
timeoutSeconds: 15
- terminationMessagePath: /dev/termination-log
- terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/etcd
name: etcd-data
- mountPath: /etc/kubernetes/pki/etcd
name: etcd-certs
- dnsPolicy: ClusterFirst
- enableServiceLinks: true
hostNetwork: true
priority: 2000001000
priorityClassName: system-node-critical
- restartPolicy: Always
- schedulerName: default-scheduler
securityContext:
seccompProfile:
type: RuntimeDefault
- terminationGracePeriodSeconds: 30
volumes:
- hostPath:
path: /etc/kubernetes/pki/etcd
Більше інформації можна знайти в тікеті для цієї помилки.